@@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20
20
else {
21
21
return false ;
22
22
} ;
23
- let hir = self . tcx . hir ( ) ;
24
- let hir:: Node :: Expr ( expr) = hir. get ( hir_id) else {
25
- return false ;
26
- } ;
27
23
28
24
let Some ( unsubstituted_pred) = self
29
25
. tcx
@@ -69,15 +65,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
69
65
70
66
// Account for enum variant constructors, where the type param corresponds to the enum
71
67
// itself.
72
- let enum_def_id = if let hir:: def:: DefKind :: Ctor ( hir:: def:: CtorOf :: Variant , _) =
73
- self . tcx . def_kind ( def_id)
74
- {
75
- // `def_id` corresponds to a constructor, and its parent is the variant, and we want
76
- // the enum.
77
- Some ( self . tcx . parent ( self . tcx . parent ( def_id) ) )
78
- } else {
79
- None
80
- } ;
68
+ let enum_def_id =
69
+ if let DefKind :: Ctor ( hir:: def:: CtorOf :: Variant , _) = self . tcx . def_kind ( def_id) {
70
+ // `def_id` corresponds to a constructor, and its parent is the variant, and we want
71
+ // the enum.
72
+ Some ( self . tcx . parent ( self . tcx . parent ( def_id) ) )
73
+ } else {
74
+ None
75
+ } ;
81
76
let variant_param_to_point_at = find_param_matching ( & |param_term| {
82
77
// FIXME: It would be nice to make this not use string manipulation,
83
78
// but it's pretty hard to do this, since `ty::ParamTy` is missing
@@ -90,11 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
90
85
} ;
91
86
// Account for enum variant constructors, where the type param corresponds to the enum
92
87
// itself.
93
- let def_id = if let Some ( def_id) = enum_def_id {
94
- def_id
95
- } else {
96
- def_id
97
- } ;
88
+ let def_id = if let Some ( def_id) = enum_def_id { def_id } else { def_id } ;
98
89
self . tcx . parent ( generics. param_at ( param_term. index ( ) , self . tcx ) . def_id ) == def_id
99
90
&& include
100
91
} ) ;
@@ -127,68 +118,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
127
118
self . find_ambiguous_parameter_in ( def_id, error. root_obligation . predicate ) ;
128
119
}
129
120
130
- if self . closure_span_overlaps_error ( error, expr. span ) {
131
- return false ;
132
- }
133
-
134
- match & expr. kind {
135
- hir:: ExprKind :: Path ( qpath) => {
136
- let def_id = if let Some ( def_id) = enum_def_id {
137
- def_id
138
- } else {
139
- def_id
140
- } ;
141
- if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind {
142
- for segment in path. segments {
143
- if let Some ( param) = variant_param_to_point_at
144
- && self . point_at_generic_if_possible ( error, def_id, param, segment)
145
- {
146
- return true ;
147
- }
148
- }
121
+ let hir = self . tcx . hir ( ) ;
122
+ let ( expr, qpath) = match hir. get ( hir_id) {
123
+ hir:: Node :: Expr ( expr) => {
124
+ if self . closure_span_overlaps_error ( error, expr. span ) {
125
+ return false ;
149
126
}
150
- if let hir:: Node :: Expr ( hir:: Expr {
151
- kind : hir:: ExprKind :: Call ( callee, args) ,
152
- hir_id : call_hir_id,
153
- span : call_span,
154
- ..
155
- } ) = hir. get_parent ( expr. hir_id )
156
- && callee. hir_id == expr. hir_id
157
- {
158
- if self . closure_span_overlaps_error ( error, * call_span) {
159
- return false ;
160
- }
127
+ let qpath =
128
+ if let hir:: ExprKind :: Path ( qpath) = expr. kind { Some ( qpath) } else { None } ;
161
129
162
- for param in
163
- [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
164
- . into_iter ( )
165
- . flatten ( )
130
+ ( Some ( * expr) , qpath)
131
+ }
132
+ hir:: Node :: Ty ( hir:: Ty { kind : hir:: TyKind :: Path ( qpath) , .. } ) => ( None , Some ( * qpath) ) ,
133
+ _ => return false ,
134
+ } ;
135
+
136
+ if let Some ( qpath) = qpath {
137
+ let def_id = if let Some ( def_id) = enum_def_id { def_id } else { def_id } ;
138
+ if let hir:: QPath :: Resolved ( None , path) = qpath {
139
+ for segment in path. segments {
140
+ if let Some ( param) = variant_param_to_point_at
141
+ && self . point_at_generic_if_possible ( error, def_id, param, segment)
166
142
{
167
- if self . blame_specific_arg_if_possible (
168
- error,
169
- def_id,
170
- param,
171
- * call_hir_id,
172
- callee. span ,
173
- None ,
174
- args,
175
- )
176
- {
177
- return true ;
178
- }
143
+ return true ;
179
144
}
180
145
}
146
+ }
147
+ if let hir:: QPath :: TypeRelative ( _ty, segment) = qpath {
148
+ if let Some ( param) = variant_param_to_point_at
149
+ && self . point_at_generic_if_possible ( error, def_id, param, segment)
150
+ {
151
+ return true ;
152
+ }
153
+ }
154
+ if let hir:: Node :: Expr ( hir:: Expr {
155
+ kind : hir:: ExprKind :: Call ( callee, args) ,
156
+ hir_id : call_hir_id,
157
+ span : call_span,
158
+ ..
159
+ } ) = hir. get_parent ( hir_id)
160
+ && callee. hir_id == hir_id
161
+ {
162
+ if self . closure_span_overlaps_error ( error, * call_span) {
163
+ return false ;
164
+ }
181
165
182
- for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
166
+ for param in
167
+ [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
183
168
. into_iter ( )
184
169
. flatten ( )
185
170
{
186
- if self . point_at_path_if_possible ( error, def_id, param, qpath) {
171
+ if self . blame_specific_arg_if_possible (
172
+ error,
173
+ def_id,
174
+ param,
175
+ * call_hir_id,
176
+ callee. span ,
177
+ None ,
178
+ args,
179
+ )
180
+ {
187
181
return true ;
188
182
}
189
183
}
190
184
}
191
- hir:: ExprKind :: MethodCall ( segment, receiver, args, ..) => {
185
+
186
+ for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
187
+ . into_iter ( )
188
+ . flatten ( )
189
+ {
190
+ if self . point_at_path_if_possible ( error, def_id, param, & qpath) {
191
+ return true ;
192
+ }
193
+ }
194
+ }
195
+
196
+ match expr. map ( |e| e. kind ) {
197
+ Some ( hir:: ExprKind :: MethodCall ( segment, receiver, args, ..) ) => {
192
198
for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
193
199
. into_iter ( )
194
200
. flatten ( )
@@ -220,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
220
226
return true ;
221
227
}
222
228
}
223
- hir:: ExprKind :: Struct ( qpath, fields, ..) => {
229
+ Some ( hir:: ExprKind :: Struct ( qpath, fields, ..) ) => {
224
230
if let Res :: Def ( DefKind :: Struct | DefKind :: Variant , variant_def_id) =
225
231
self . typeck_results . borrow ( ) . qpath_res ( qpath, hir_id)
226
232
{
0 commit comments