@@ -108,7 +108,7 @@ private module Input1 implements InputSig1<Location> {
108108 maxArity = max ( int i | i = any ( TupleType tt ) .getArity ( ) ) and
109109 tp0 = ttp and
110110 kind = 2 and
111- id = ttp .getArity ( ) * maxArity + ttp .getIndex ( )
111+ id = ttp .getTupleType ( ) . getArity ( ) * maxArity + ttp .getIndex ( )
112112 )
113113 |
114114 tp0 order by kind , id
@@ -335,7 +335,7 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
335335 arity = n2 .( TupleExpr ) .getNumberOfFields ( ) and
336336 n1 = n2 .( TupleExpr ) .getField ( i )
337337 or
338- arity = n2 .( TuplePat ) .getNumberOfFields ( ) and
338+ arity = n2 .( TuplePat ) .getTupleArity ( ) and
339339 n1 = n2 .( TuplePat ) .getField ( i )
340340 )
341341 or
@@ -553,9 +553,9 @@ private Type inferStructExprType(AstNode n, TypePath path) {
553553}
554554
555555pragma [ nomagic]
556- private Type inferTupleExprRootType ( TupleExpr te ) {
557- // `typeEquality` handles the non-root case
558- result = TTuple ( te . getNumberOfFields ( ) )
556+ private Type inferTupleRootType ( AstNode n ) {
557+ // `typeEquality` handles the non-root cases
558+ result = TTuple ( [ n . ( TupleExpr ) . getNumberOfFields ( ) , n . ( TuplePat ) . getTupleArity ( ) ] )
559559}
560560
561561pragma [ nomagic]
@@ -1091,16 +1091,27 @@ private Type inferTupleIndexExprType(FieldExpr fe, TypePath path) {
10911091
10921092/** Infers the type of `t` in `t.n` when `t` is a tuple. */
10931093private Type inferTupleContainerExprType ( Expr e , TypePath path ) {
1094- // NOTE: For a field expression `t.n` where `n` is a number `t` might both be
1095- // a tuple struct or a tuple. It is only correct to let type information flow
1096- // from `t.n` to tuple type parameters of `t` in the latter case. Hence we
1097- // include the condition that the root type of `t` must be a tuple type.
1094+ // NOTE: For a field expression `t.n` where `n` is a number `t` might be a
1095+ // tuple as in:
1096+ // ```rust
1097+ // let t = (Default::default(), 2);
1098+ // let s: String = t.0;
1099+ // ```
1100+ // But it could also be a tuple struct as in:
1101+ // ```rust
1102+ // struct T(String, u32);
1103+ // let t = T(Default::default(), 2);
1104+ // let s: String = t.0;
1105+ // ```
1106+ // We need type information to flow from `t.n` to tuple type parameters of `t`
1107+ // in the former case but not the latter case. Hence we include the condition
1108+ // that the root type of `t` must be a tuple type.
10981109 exists ( int i , TypePath path0 , FieldExpr fe , int arity |
10991110 e = fe .getContainer ( ) and
11001111 fe .getIdentifier ( ) .getText ( ) = i .toString ( ) and
11011112 arity = inferType ( fe .getContainer ( ) ) .( TupleType ) .getArity ( ) and
11021113 result = inferType ( fe , path0 ) and
1103- path = TypePath:: cons ( TTupleTypeParameter ( arity , i ) , path0 ) // FIXME:
1114+ path = TypePath:: cons ( TTupleTypeParameter ( arity , i ) , path0 )
11041115 )
11051116}
11061117
@@ -1992,7 +2003,7 @@ private module Cached {
19922003 or
19932004 result = inferStructExprType ( n , path )
19942005 or
1995- result = inferTupleExprRootType ( n ) and
2006+ result = inferTupleRootType ( n ) and
19962007 path .isEmpty ( )
19972008 or
19982009 result = inferPathExprType ( n , path )
0 commit comments