Skip to content

Commit c0b7e71

Browse files
committed
Auto merge of #64151 - estebank:binding-error, r=varkor
On obligation errors point at the unfulfilled binding when possible CC #42855, #64130, #64135. Fix #61860.
2 parents 1dd1884 + ff75124 commit c0b7e71

File tree

175 files changed

+904
-737
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+904
-737
lines changed

src/etc/generate-deriving-span-tests.py

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
1515

1616
TEMPLATE = """\
17+
// ignore-x86
18+
// ^ due to stderr output differences
1719
// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
1820
1921
{error_deriving}

src/librustc/hir/lowering.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1893,10 +1893,13 @@ impl<'a> LoweringContext<'a> {
18931893
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
18941894
// Do not suggest going from `Trait()` to `Trait<>`
18951895
if data.inputs.len() > 0 {
1896+
let split = snippet.find('(').unwrap();
1897+
let trait_name = &snippet[0..split];
1898+
let args = &snippet[split + 1 .. snippet.len() - 1];
18961899
err.span_suggestion(
18971900
data.span,
18981901
"use angle brackets instead",
1899-
format!("<{}>", &snippet[1..snippet.len() - 1]),
1902+
format!("{}<{}>", trait_name, args),
19001903
Applicability::MaybeIncorrect,
19011904
);
19021905
}

src/librustc/hir/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -2750,3 +2750,15 @@ pub enum Node<'hir> {
27502750

27512751
Crate,
27522752
}
2753+
2754+
impl Node<'_> {
2755+
pub fn ident(&self) -> Option<Ident> {
2756+
match self {
2757+
Node::TraitItem(TraitItem { ident, .. }) |
2758+
Node::ImplItem(ImplItem { ident, .. }) |
2759+
Node::ForeignItem(ForeignItem { ident, .. }) |
2760+
Node::Item(Item { ident, .. }) => Some(*ident),
2761+
_ => None,
2762+
}
2763+
}
2764+
}

src/librustc/traits/error_reporting.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ use syntax::symbol::{sym, kw};
4040
use syntax_pos::{DUMMY_SP, Span, ExpnKind};
4141

4242
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
43-
pub fn report_fulfillment_errors(&self,
44-
errors: &[FulfillmentError<'tcx>],
45-
body_id: Option<hir::BodyId>,
46-
fallback_has_occurred: bool) {
43+
pub fn report_fulfillment_errors(
44+
&self,
45+
errors: &[FulfillmentError<'tcx>],
46+
body_id: Option<hir::BodyId>,
47+
fallback_has_occurred: bool,
48+
) {
4749
#[derive(Debug)]
4850
struct ErrorDescriptor<'tcx> {
4951
predicate: ty::Predicate<'tcx>,
@@ -1053,6 +1055,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10531055
.filter(|c| !c.is_whitespace())
10541056
.take_while(|c| *c == '&')
10551057
.count();
1058+
if let Some('\'') = snippet.chars()
1059+
.filter(|c| !c.is_whitespace())
1060+
.skip(refs_number)
1061+
.next()
1062+
{ // Do not suggest removal of borrow from type arguments.
1063+
return;
1064+
}
10561065

10571066
let mut trait_type = trait_ref.self_ty();
10581067

@@ -1651,6 +1660,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16511660
err.note(&msg);
16521661
}
16531662
}
1663+
ObligationCauseCode::BindingObligation(item_def_id, span) => {
1664+
let item_name = tcx.def_path_str(item_def_id);
1665+
let msg = format!("required by this bound in `{}`", item_name);
1666+
if let Some(ident) = tcx.opt_item_name(item_def_id) {
1667+
err.span_label(ident.span, "");
1668+
}
1669+
if span != DUMMY_SP {
1670+
err.span_label(span, &msg);
1671+
} else {
1672+
err.note(&msg);
1673+
}
1674+
}
16541675
ObligationCauseCode::ObjectCastObligation(object_ty) => {
16551676
err.note(&format!("required for the cast to the object type `{}`",
16561677
self.ty_to_string(object_ty)));

src/librustc/traits/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ pub enum ObligationCauseCode<'tcx> {
176176
/// also implement all supertraits of `X`.
177177
ItemObligation(DefId),
178178

179+
/// Like `ItemObligation`, but with extra detail on the source of the obligation.
180+
BindingObligation(DefId, Span),
181+
179182
/// A type like `&'a T` is WF only if `T: 'a`.
180183
ReferenceOutlivesReferent(Ty<'tcx>),
181184

src/librustc/traits/structural_impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
472472
super::TupleElem => Some(super::TupleElem),
473473
super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
474474
super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
475+
super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
475476
super::ReferenceOutlivesReferent(ty) => {
476477
tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
477478
}

src/librustc/ty/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2797,6 +2797,10 @@ impl<'tcx> TyCtxt<'tcx> {
27972797
})
27982798
}
27992799

2800+
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
2801+
self.hir().as_local_hir_id(def_id).and_then(|hir_id| self.hir().get(hir_id).ident())
2802+
}
2803+
28002804
pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
28012805
let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
28022806
match self.hir().get(hir_id) {

src/librustc_typeck/check/callee.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
263263

264264
fn confirm_builtin_call(
265265
&self,
266-
call_expr: &hir::Expr,
266+
call_expr: &'tcx hir::Expr,
267267
callee_ty: Ty<'tcx>,
268268
arg_exprs: &'tcx [hir::Expr],
269269
expected: Expectation<'tcx>,
@@ -425,7 +425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
425425
);
426426
self.check_argument_types(
427427
call_expr.span,
428-
call_expr.span,
428+
call_expr,
429429
inputs,
430430
&expected_arg_tys[..],
431431
arg_exprs,
@@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
439439

440440
fn confirm_deferred_closure_call(
441441
&self,
442-
call_expr: &hir::Expr,
442+
call_expr: &'tcx hir::Expr,
443443
arg_exprs: &'tcx [hir::Expr],
444444
expected: Expectation<'tcx>,
445445
fn_sig: ty::FnSig<'tcx>,
@@ -458,7 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
458458

459459
self.check_argument_types(
460460
call_expr.span,
461-
call_expr.span,
461+
call_expr,
462462
fn_sig.inputs(),
463463
&expected_arg_tys,
464464
arg_exprs,
@@ -472,14 +472,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
472472

473473
fn confirm_overloaded_call(
474474
&self,
475-
call_expr: &hir::Expr,
475+
call_expr: &'tcx hir::Expr,
476476
arg_exprs: &'tcx [hir::Expr],
477477
expected: Expectation<'tcx>,
478478
method_callee: MethodCallee<'tcx>,
479479
) -> Ty<'tcx> {
480480
let output_type = self.check_method_argument_types(
481481
call_expr.span,
482-
call_expr.span,
482+
call_expr,
483483
Ok(method_callee),
484484
arg_exprs,
485485
TupleArgumentsFlag::TupleArguments,

src/librustc_typeck/check/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
796796
// Call the generic checker.
797797
self.check_method_argument_types(
798798
span,
799-
expr.span,
799+
expr,
800800
method,
801801
&args[1..],
802802
DontTupleArguments,

0 commit comments

Comments
 (0)