From 89e96e9bc575b370c7b55055aad28bebd14e8dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2020 18:06:03 -0800 Subject: [PATCH] Point at closure definitions --- src/librustc_typeck/check/method/suggest.rs | 41 +++++++++++-------- src/test/ui/issues/issue-31173.stderr | 4 +- .../ui/mismatched_types/issue-36053-2.stderr | 7 +++- .../mut-borrow-needed-by-trait.stderr | 2 +- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 973f8208f16..5d4a143598f 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -538,28 +538,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let def_span = |def_id| self.tcx.sess.source_map().def_span(self.tcx.def_span(def_id)); let mut bound_spans = vec![]; - let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str| { + let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { + let msg = format!( + "doesn't satisfy {}", + if obligation.len() > 50 { quiet } else { obligation } + ); match &self_ty.kind { - ty::Adt(def, _) => { - // Point at the type that couldn't satisfy the bound. - bound_spans.push(( - def_span(def.did), - format!("doesn't satisfy {}", obligation), - )); - } + // Point at the type that couldn't satisfy the bound. + ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)), + // Point at the trait object that couldn't satisfy the bound. ty::Dynamic(preds, _) => { - // Point at the trait object that couldn't satisfy the bound. for pred in *preds.skip_binder() { match pred { - ty::ExistentialPredicate::Trait(tr) => bound_spans.push(( - def_span(tr.def_id), - format!("doesn't satisfy {}", obligation), - )), + ty::ExistentialPredicate::Trait(tr) => { + bound_spans.push((def_span(tr.def_id), msg.clone())) + } ty::ExistentialPredicate::Projection(_) | ty::ExistentialPredicate::AutoTrait(_) => {} } } } + // Point at the closure that couldn't satisfy the bound. + ty::Closure(def_id, _) => bound_spans + .push((def_span(*def_id), format!("doesn't satisfy {}", quiet))), _ => {} } }; @@ -573,9 +574,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .associated_item(pred.skip_binder().projection_ty.item_def_id); let ty = pred.skip_binder().ty; - let obligation = - format!("`{}::{} = {}`", trait_ref, assoc.ident, ty); - bound_span_label(trait_ref.self_ty(), &obligation); + let msg = format!("`{}::{} = {}`", trait_ref, assoc.ident, ty); + let quiet = format!( + "`<_ as {}>::{} = {}`", + trait_ref.print_only_trait_path(), + assoc.ident, + ty + ); + bound_span_label(trait_ref.self_ty(), &msg, &quiet); Some(obligation) } ty::Predicate::Trait(poly_trait_ref, _) => { @@ -583,7 +589,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let self_ty = p.self_ty(); let path = p.print_only_trait_path(); let obligation = format!("`{}: {}`", self_ty, path); - bound_span_label(self_ty, &obligation); + let quiet = format!("`_: {}`", path); + bound_span_label(self_ty, &obligation, &quiet); Some(obligation) } _ => None, diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index 9100f2c3a93..ca8e63550d6 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -16,10 +16,10 @@ LL | .collect(); ::: $SRC_DIR/libcore/iter/adapters/mod.rs:LL:COL | LL | pub struct Cloned { - | -------------------- doesn't satisfy `std::iter::Cloned, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>: std::iter::Iterator` + | -------------------- doesn't satisfy `_: std::iter::Iterator` ... LL | pub struct TakeWhile { - | -------------------------- doesn't satisfy `, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]> as std::iter::Iterator>::Item = &_` + | -------------------------- doesn't satisfy `<_ as std::iter::Iterator>::Item = &_` | = note: the method `collect` exists but the following trait bounds were not satisfied: `, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]> as std::iter::Iterator>::Item = &_` which is required by `std::iter::Cloned, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>: std::iter::Iterator` diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index 5899dfffa41..49e61cd2327 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -2,12 +2,15 @@ error[E0599]: no method named `count` found for struct `std::iter::Filter $DIR/issue-36053-2.rs:11:55 | LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); - | ^^^^^ method not found in `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>` + | -------------- ^^^^^ method not found in `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>` + | | + | doesn't satisfy `<_ as std::ops::FnOnce<(&&str,)>>::Output = bool` + | doesn't satisfy `_: std::ops::FnMut<(&&str,)>` | ::: $SRC_DIR/libcore/iter/adapters/mod.rs:LL:COL | LL | pub struct Filter { - | ----------------------- doesn't satisfy `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator` + | ----------------------- doesn't satisfy `_: std::iter::Iterator` | = note: the method `count` exists but the following trait bounds were not satisfied: `<[closure@$DIR/issue-36053-2.rs:11:39: 11:53] as std::ops::FnOnce<(&&str,)>>::Output = bool` which is required by `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator` diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 5d297728eca..16a03c42a4d 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -34,7 +34,7 @@ LL | writeln!(fp, "hello world").unwrap(); ::: $SRC_DIR/libstd/io/buffered.rs:LL:COL | LL | pub struct BufWriter { - | ------------------------------ doesn't satisfy `std::io::BufWriter<&dyn std::io::Write>: std::io::Write` + | ------------------------------ doesn't satisfy `_: std::io::Write` | = note: the method `write_fmt` exists but the following trait bounds were not satisfied: `&dyn std::io::Write: std::io::Write` which is required by `std::io::BufWriter<&dyn std::io::Write>: std::io::Write`