Skip to content

Commit d5c5d58

Browse files
Pull out expr handling
1 parent 30afeb0 commit d5c5d58

File tree

1 file changed

+97
-93
lines changed

1 file changed

+97
-93
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+97-93
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128128
}
129129

130130
match self.tcx.hir_node(hir_id) {
131-
hir::Node::Expr(&hir::Expr {
132-
kind:
133-
hir::ExprKind::Call(
134-
hir::Expr { kind: hir::ExprKind::Path(qpath), span: callee_span, .. },
135-
args,
136-
),
137-
span,
138-
..
139-
}) => {
140-
if self.closure_span_overlaps_error(error, span) {
141-
return false;
131+
hir::Node::Expr(expr) => self.point_at_expr_if_possible(
132+
error,
133+
def_id,
134+
expr,
135+
predicate_self_type_to_point_at,
136+
param_to_point_at,
137+
fallback_param_to_point_at,
138+
self_param_to_point_at,
139+
),
140+
141+
hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => {
142+
for param in [
143+
predicate_self_type_to_point_at,
144+
param_to_point_at,
145+
fallback_param_to_point_at,
146+
self_param_to_point_at,
147+
]
148+
.into_iter()
149+
.flatten()
150+
{
151+
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
152+
return true;
153+
}
142154
}
143155

156+
false
157+
}
158+
159+
_ => false,
160+
}
161+
}
162+
163+
fn point_at_expr_if_possible(
164+
&self,
165+
error: &mut traits::FulfillmentError<'tcx>,
166+
callee_def_id: DefId,
167+
expr: &'tcx hir::Expr<'tcx>,
168+
predicate_self_type_to_point_at: Option<ty::GenericArg<'tcx>>,
169+
param_to_point_at: Option<ty::GenericArg<'tcx>>,
170+
fallback_param_to_point_at: Option<ty::GenericArg<'tcx>>,
171+
self_param_to_point_at: Option<ty::GenericArg<'tcx>>,
172+
) -> bool {
173+
if self.closure_span_overlaps_error(error, expr.span) {
174+
return false;
175+
}
176+
177+
match expr.kind {
178+
hir::ExprKind::Call(
179+
hir::Expr { kind: hir::ExprKind::Path(qpath), span: callee_span, .. },
180+
args,
181+
) => {
144182
if let Some(param) = predicate_self_type_to_point_at
145-
&& self.point_at_path_if_possible(error, def_id, param, &qpath)
183+
&& self.point_at_path_if_possible(error, callee_def_id, param, &qpath)
146184
{
147185
return true;
148186
}
@@ -153,9 +191,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
153191
{
154192
if self.blame_specific_arg_if_possible(
155193
error,
156-
def_id,
194+
callee_def_id,
157195
param,
158-
hir_id,
196+
expr.hir_id,
159197
*callee_span,
160198
None,
161199
args,
@@ -168,88 +206,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
168206
.into_iter()
169207
.flatten()
170208
{
171-
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
209+
if self.point_at_path_if_possible(error, callee_def_id, param, &qpath) {
172210
return true;
173211
}
174212
}
175213
}
176-
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Path(qpath), span, .. }) => {
177-
if self.closure_span_overlaps_error(error, span) {
178-
return false;
214+
hir::ExprKind::Path(qpath) => {
215+
// If the parent is an call, then process this as a call.
216+
//
217+
// This is because the `WhereClauseInExpr` obligations come from
218+
// the well-formedness of the *path* expression, but we care to
219+
// point at the call expression (namely, its args).
220+
if let hir::Node::Expr(
221+
call_expr @ hir::Expr { kind: hir::ExprKind::Call(callee, ..), .. },
222+
) = self.tcx.parent_hir_node(expr.hir_id)
223+
&& callee.hir_id == expr.hir_id
224+
{
225+
return self.point_at_expr_if_possible(
226+
error,
227+
callee_def_id,
228+
call_expr,
229+
predicate_self_type_to_point_at,
230+
param_to_point_at,
231+
fallback_param_to_point_at,
232+
self_param_to_point_at,
233+
);
179234
}
180235

236+
// Otherwise, just try to point at path components.
237+
181238
if let Some(param) = predicate_self_type_to_point_at
182-
&& self.point_at_path_if_possible(error, def_id, param, &qpath)
239+
&& self.point_at_path_if_possible(error, callee_def_id, param, &qpath)
183240
{
184241
return true;
185242
}
186243

187-
if let hir::Node::Expr(hir::Expr {
188-
kind: hir::ExprKind::Call(callee, args),
189-
hir_id: call_hir_id,
190-
span: call_span,
191-
..
192-
}) = self.tcx.parent_hir_node(hir_id)
193-
&& callee.hir_id == hir_id
194-
{
195-
if self.closure_span_overlaps_error(error, *call_span) {
196-
return false;
197-
}
198-
199-
for param in
200-
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
201-
.into_iter()
202-
.flatten()
203-
{
204-
if self.blame_specific_arg_if_possible(
205-
error,
206-
def_id,
207-
param,
208-
*call_hir_id,
209-
callee.span,
210-
None,
211-
args,
212-
) {
213-
return true;
214-
}
215-
}
216-
}
217-
218244
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
219245
.into_iter()
220246
.flatten()
221247
{
222-
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
248+
if self.point_at_path_if_possible(error, callee_def_id, param, &qpath) {
223249
return true;
224250
}
225251
}
226252
}
227-
hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => {
228-
for param in [
229-
predicate_self_type_to_point_at,
230-
param_to_point_at,
231-
fallback_param_to_point_at,
232-
self_param_to_point_at,
233-
]
234-
.into_iter()
235-
.flatten()
236-
{
237-
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
238-
return true;
239-
}
240-
}
241-
}
242-
hir::Node::Expr(&hir::Expr {
243-
kind: hir::ExprKind::MethodCall(segment, receiver, args, ..),
244-
span,
245-
..
246-
}) => {
247-
if self.closure_span_overlaps_error(error, span) {
248-
return false;
249-
}
250-
253+
hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
251254
if let Some(param) = predicate_self_type_to_point_at
252-
&& self.point_at_generic_if_possible(error, def_id, param, segment)
255+
&& self.point_at_generic_if_possible(error, callee_def_id, param, segment)
253256
{
254257
// HACK: This is not correct, since `predicate_self_type_to_point_at` might
255258
// not actually correspond to the receiver of the method call. But we
@@ -259,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
259262
error.obligation.cause.map_code(|parent_code| {
260263
ObligationCauseCode::FunctionArg {
261264
arg_hir_id: receiver.hir_id,
262-
call_hir_id: hir_id,
265+
call_hir_id: expr.hir_id,
263266
parent_code,
264267
}
265268
});
@@ -272,9 +275,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
272275
{
273276
if self.blame_specific_arg_if_possible(
274277
error,
275-
def_id,
278+
callee_def_id,
276279
param,
277-
hir_id,
280+
expr.hir_id,
278281
segment.ident.span,
279282
Some(receiver),
280283
args,
@@ -283,7 +286,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
283286
}
284287
}
285288
if let Some(param_to_point_at) = param_to_point_at
286-
&& self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment)
289+
&& self.point_at_generic_if_possible(
290+
error,
291+
callee_def_id,
292+
param_to_point_at,
293+
segment,
294+
)
287295
{
288296
return true;
289297
}
@@ -297,25 +305,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
297305
return true;
298306
}
299307
}
300-
hir::Node::Expr(&hir::Expr {
301-
kind: hir::ExprKind::Struct(qpath, fields, ..),
302-
span,
303-
..
304-
}) => {
305-
if self.closure_span_overlaps_error(error, span) {
306-
return false;
307-
}
308-
308+
hir::ExprKind::Struct(qpath, fields, ..) => {
309309
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
310-
self.typeck_results.borrow().qpath_res(qpath, hir_id)
310+
self.typeck_results.borrow().qpath_res(qpath, expr.hir_id)
311311
{
312312
for param in
313313
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
314314
.into_iter()
315315
.flatten()
316316
{
317-
let refined_expr =
318-
self.point_at_field_if_possible(def_id, param, variant_def_id, fields);
317+
let refined_expr = self.point_at_field_if_possible(
318+
callee_def_id,
319+
param,
320+
variant_def_id,
321+
fields,
322+
);
319323

320324
match refined_expr {
321325
None => {}
@@ -339,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339343
.into_iter()
340344
.flatten()
341345
{
342-
if self.point_at_path_if_possible(error, def_id, param, qpath) {
346+
if self.point_at_path_if_possible(error, callee_def_id, param, qpath) {
343347
return true;
344348
}
345349
}

0 commit comments

Comments
 (0)