Skip to content

Commit d7efa5b

Browse files
committed
review comments
1 parent 0487f0c commit d7efa5b

File tree

1 file changed

+91
-81
lines changed

1 file changed

+91
-81
lines changed

src/librustc/traits/error_reporting.rs

+91-81
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12301230
}
12311231
}
12321232

1233+
fn mk_obligation_for_def_id(
1234+
&self,
1235+
def_id: DefId,
1236+
output_ty: Ty<'tcx>,
1237+
cause: ObligationCause<'tcx>,
1238+
param_env: ty::ParamEnv<'tcx>,
1239+
) -> PredicateObligation<'tcx> {
1240+
let new_trait_ref = ty::TraitRef {
1241+
def_id,
1242+
substs: self.tcx.mk_substs_trait(output_ty, &[]),
1243+
};
1244+
Obligation::new(cause, param_env, new_trait_ref.to_predicate())
1245+
}
1246+
1247+
1248+
/// We tried to apply the bound to an `fn` or closure. Check whether calling it would
1249+
/// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
1250+
/// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
12331251
fn suggest_fn_call(
12341252
&self,
12351253
obligation: &PredicateObligation<'tcx>,
@@ -1248,19 +1266,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12481266
_ => return,
12491267
};
12501268
let msg = format!("use parentheses to call the {}", callable);
1251-
// We tried to apply the bound to an `fn` or closure. Check whether calling it would
1252-
// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
1253-
// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
12541269

1255-
let new_trait_ref = ty::TraitRef {
1256-
def_id: trait_ref.def_id(),
1257-
substs: self.tcx.mk_substs_trait(output_ty.skip_binder(), &[]),
1258-
};
1259-
let obligation = Obligation::new(
1270+
let obligation = self.mk_obligation_for_def_id(
1271+
trait_ref.def_id(),
1272+
output_ty.skip_binder(),
12601273
obligation.cause.clone(),
12611274
obligation.param_env,
1262-
new_trait_ref.to_predicate(),
12631275
);
1276+
12641277
let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option<String> {
12651278
// Get the local name of this closure. This can be inaccurate because
12661279
// of the possibility of reassignment, but this should be good enough.
@@ -1277,73 +1290,72 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12771290
match self.evaluate_obligation(&obligation) {
12781291
Ok(EvaluationResult::EvaluatedToOk) |
12791292
Ok(EvaluationResult::EvaluatedToOkModuloRegions) |
1280-
Ok(EvaluationResult::EvaluatedToAmbig) => {
1281-
let hir = self.tcx.hir();
1282-
// Get the name of the callable and the arguments to be used in the suggestion.
1283-
let snippet = match hir.get_if_local(def_id) {
1284-
Some(hir::Node::Expr(hir::Expr {
1285-
kind: hir::ExprKind::Closure(_, decl, _, span, ..),
1286-
..
1287-
})) => {
1288-
err.span_label(*span, "consider calling this closure");
1289-
let hir_id = match hir.as_local_hir_id(def_id) {
1290-
Some(hir_id) => hir_id,
1291-
None => return,
1292-
};
1293-
let parent_node = hir.get_parent_node(hir_id);
1294-
let name = match hir.find(parent_node) {
1295-
Some(hir::Node::Stmt(hir::Stmt {
1296-
kind: hir::StmtKind::Local(local), ..
1297-
})) => match get_name(err, &local.pat.kind) {
1298-
Some(name) => name,
1299-
None => return,
1300-
},
1301-
// Different to previous arm because one is `&hir::Local` and the other
1302-
// is `P<hir::Local>`.
1303-
Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) {
1304-
Some(name) => name,
1305-
None => return,
1306-
},
1307-
_ => return,
1308-
};
1309-
let args = decl.inputs.iter()
1310-
.map(|_| "_")
1311-
.collect::<Vec<_>>().join(", ");
1312-
format!("{}({})", name, args)
1313-
}
1314-
Some(hir::Node::Item(hir::Item {
1315-
ident,
1316-
kind: hir::ItemKind::Fn(.., body_id),
1317-
..
1318-
})) => {
1319-
err.span_label(ident.span, "consider calling this function");
1320-
let body = hir.body(*body_id);
1321-
let args = body.params.iter()
1322-
.map(|arg| match &arg.pat.kind {
1323-
hir::PatKind::Binding(_, _, ident, None)
1324-
if ident.name != kw::SelfLower => ident.to_string(),
1325-
_ => "_".to_string(),
1326-
}).collect::<Vec<_>>().join(", ");
1327-
format!("{}({})", ident, args)
1328-
}
1293+
Ok(EvaluationResult::EvaluatedToAmbig) => {}
1294+
_ => return,
1295+
}
1296+
let hir = self.tcx.hir();
1297+
// Get the name of the callable and the arguments to be used in the suggestion.
1298+
let snippet = match hir.get_if_local(def_id) {
1299+
Some(hir::Node::Expr(hir::Expr {
1300+
kind: hir::ExprKind::Closure(_, decl, _, span, ..),
1301+
..
1302+
})) => {
1303+
err.span_label(*span, "consider calling this closure");
1304+
let hir_id = match hir.as_local_hir_id(def_id) {
1305+
Some(hir_id) => hir_id,
1306+
None => return,
1307+
};
1308+
let parent_node = hir.get_parent_node(hir_id);
1309+
let name = match hir.find(parent_node) {
1310+
Some(hir::Node::Stmt(hir::Stmt {
1311+
kind: hir::StmtKind::Local(local), ..
1312+
})) => match get_name(err, &local.pat.kind) {
1313+
Some(name) => name,
1314+
None => return,
1315+
},
1316+
// Different to previous arm because one is `&hir::Local` and the other
1317+
// is `P<hir::Local>`.
1318+
Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) {
1319+
Some(name) => name,
1320+
None => return,
1321+
},
13291322
_ => return,
13301323
};
1331-
if points_at_arg {
1332-
// When the obligation error has been ensured to have been caused by
1333-
// an argument, the `obligation.cause.span` points at the expression
1334-
// of the argument, so we can provide a suggestion. This is signaled
1335-
// by `points_at_arg`. Otherwise, we give a more general note.
1336-
err.span_suggestion(
1337-
obligation.cause.span,
1338-
&msg,
1339-
snippet,
1340-
Applicability::HasPlaceholders,
1341-
);
1342-
} else {
1343-
err.help(&format!("{}: `{}`", msg, snippet));
1344-
}
1324+
let args = decl.inputs.iter()
1325+
.map(|_| "_")
1326+
.collect::<Vec<_>>().join(", ");
1327+
format!("{}({})", name, args)
1328+
}
1329+
Some(hir::Node::Item(hir::Item {
1330+
ident,
1331+
kind: hir::ItemKind::Fn(.., body_id),
1332+
..
1333+
})) => {
1334+
err.span_label(ident.span, "consider calling this function");
1335+
let body = hir.body(*body_id);
1336+
let args = body.params.iter()
1337+
.map(|arg| match &arg.pat.kind {
1338+
hir::PatKind::Binding(_, _, ident, None)
1339+
if ident.name != kw::SelfLower => ident.to_string(),
1340+
_ => "_".to_string(),
1341+
}).collect::<Vec<_>>().join(", ");
1342+
format!("{}({})", ident, args)
13451343
}
1346-
_ => {}
1344+
_ => return,
1345+
};
1346+
if points_at_arg {
1347+
// When the obligation error has been ensured to have been caused by
1348+
// an argument, the `obligation.cause.span` points at the expression
1349+
// of the argument, so we can provide a suggestion. This is signaled
1350+
// by `points_at_arg`. Otherwise, we give a more general note.
1351+
err.span_suggestion(
1352+
obligation.cause.span,
1353+
&msg,
1354+
snippet,
1355+
Applicability::HasPlaceholders,
1356+
);
1357+
} else {
1358+
err.help(&format!("{}: `{}`", msg, snippet));
13471359
}
13481360
}
13491361

@@ -1377,12 +1389,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13771389
if let ty::Ref(_, t_type, _) = trait_type.kind {
13781390
trait_type = t_type;
13791391

1380-
let substs = self.tcx.mk_substs_trait(trait_type, &[]);
1381-
let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs);
1382-
let new_obligation = Obligation::new(
1392+
let new_obligation = self.mk_obligation_for_def_id(
1393+
trait_ref.def_id,
1394+
trait_type,
13831395
ObligationCause::dummy(),
13841396
obligation.param_env,
1385-
new_trait_ref.to_predicate(),
13861397
);
13871398

13881399
if self.predicate_may_hold(&new_obligation) {
@@ -1440,12 +1451,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14401451
hir::Mutability::Immutable => self.tcx.mk_mut_ref(region, t_type),
14411452
};
14421453

1443-
let substs = self.tcx.mk_substs_trait(&trait_type, &[]);
1444-
let new_trait_ref = ty::TraitRef::new(trait_ref.skip_binder().def_id, substs);
1445-
let new_obligation = Obligation::new(
1454+
let new_obligation = self.mk_obligation_for_def_id(
1455+
trait_ref.skip_binder().def_id,
1456+
trait_type,
14461457
ObligationCause::dummy(),
14471458
obligation.param_env,
1448-
new_trait_ref.to_predicate(),
14491459
);
14501460

14511461
if self.evaluate_obligation_no_overflow(

0 commit comments

Comments
 (0)