Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suspicious symbol structure is created around tuple fields #43597

Closed
AlekseyTs opened this issue Apr 23, 2020 · 3 comments · Fixed by #44231
Closed

Suspicious symbol structure is created around tuple fields #43597

AlekseyTs opened this issue Apr 23, 2020 · 3 comments · Fixed by #44231
Assignees
Labels
Area-Compilers Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality Feature - Tuples Tuples
Milestone

Comments

@AlekseyTs
Copy link
Contributor

The following unit-test succeeds today:

        [Fact]
        public void Test()
        {
            var source0 = @"
namespace System
{
    // struct with two values
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;

        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }

        public override string ToString()
        {
            return F1.ToString();
        }
    }
}
";


            var comp1 = CreateCompilation(source0, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe);

            var item1 = comp1.SourceModule.GlobalNamespace.GetMember<FieldSymbol>("System.ValueTuple.Item1");
            var underlying = item1.TupleUnderlyingField;

            Assert.Equal("T1 (T1, T2).Item1", item1.ToTestDisplayString());
            Assert.Equal("T1 (T1, T2).Item1", underlying.ToTestDisplayString());
            Assert.Same(underlying, underlying.TupleUnderlyingField);

            Assert.IsAssignableFrom<TupleFieldSymbol>(item1);
            Assert.IsAssignableFrom<SourceFieldSymbol>(underlying);
            Assert.False(item1.ContainingType.GetMembers().Any(m => m == (object)underlying));
        }

Observed:
For 'Item1' definition (and other fields declared within a tuple type) we have two field symbols. Both are reachable. The SourceFieldSymbol one is dangling, i.e. it is not in GetMembers for the type. TupleFieldSymbol is in GetMembers and points to the SourceFieldSymbol through TupleUnderlyingField. SourceFieldSymbol.TupleUnderlyingField returns itself.

This complicated shape is unexpected, it is not clear what is the motivation for it and what benefits we are getting from duplicating symbols like that. I think more sound design would be:

  • to have all field symbols within a tuple type definition to return themselves from TupleFieldSymbol API.
  • no dangling field symbols reachable, and preferably not even created.
  • the reachable symbols for declarations in source are SourceFieldSymbol, this will lead to less bugs in the future because people naturally assume that symbols for field declarations in source derive from SourceFieldSymbol. We already had to fix bugs in SemanticModel because of that.

I assume PE symbols have similar issues.

I also believe that this issue is the root cause of #43524. If we didn't have this symbol shape, we wouldn't crash.

@AlekseyTs AlekseyTs added Area-Compilers Feature - Tuples Tuples Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality labels Apr 23, 2020
@AlekseyTs
Copy link
Contributor Author

cc @jcouv

@AlekseyTs
Copy link
Contributor Author

It is likely that #43621 is also related

@jcouv jcouv self-assigned this Apr 23, 2020
@jcouv jcouv added this to the 16.7 milestone Apr 23, 2020
@AlekseyTs
Copy link
Contributor Author

I think #44000 is another manifestation of this issue

@jaredpar jaredpar modified the milestones: 16.7, 16.8 Jun 24, 2020
@jcouv jcouv added the 4 - In Review A fix for the issue is submitted for review. label Jul 7, 2020
@jcouv jcouv modified the milestones: 16.8, 16.9 Oct 6, 2020
@jcouv jcouv modified the milestones: 16.9, 16.10 Jan 27, 2021
@jcouv jcouv removed the 4 - In Review A fix for the issue is submitted for review. label Mar 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality Feature - Tuples Tuples
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants