diff options
9 files changed, 184 insertions, 59 deletions
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index f0f2470e80a..dbc1d4ec193 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -12,6 +12,7 @@ pub use self::CandidateSource::*; pub use self::MethodError::*; use crate::check::FnCtxt; +use crate::ObligationCause; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -71,7 +72,8 @@ pub enum MethodError<'tcx> { #[derive(Debug)] pub struct NoMatchData<'tcx> { pub static_candidates: Vec<CandidateSource>, - pub unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>, + pub unsatisfied_predicates: + Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>, pub out_of_scope_traits: Vec<DefId>, pub lev_candidate: Option<ty::AssocItem>, pub mode: probe::Mode, @@ -80,7 +82,11 @@ pub struct NoMatchData<'tcx> { impl<'tcx> NoMatchData<'tcx> { pub fn new( static_candidates: Vec<CandidateSource>, - unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>, + unsatisfied_predicates: Vec<( + ty::Predicate<'tcx>, + Option<ty::Predicate<'tcx>>, + Option<ObligationCause<'tcx>>, + )>, out_of_scope_traits: Vec<DefId>, lev_candidate: Option<ty::AssocItem>, mode: probe::Mode, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 95fe6c9b93c..9fd7e8c4daa 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -78,7 +78,8 @@ struct ProbeContext<'a, 'tcx> { /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used /// for error reporting - unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>, + unsatisfied_predicates: + Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>, is_suggestion: IsSuggestion, @@ -1351,6 +1352,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { possibly_unsatisfied_predicates: &mut Vec<( ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, + Option<ObligationCause<'tcx>>, )>, unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option<PickResult<'tcx>> @@ -1497,6 +1499,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { possibly_unsatisfied_predicates: &mut Vec<( ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, + Option<ObligationCause<'tcx>>, )>, ) -> ProbeResult { debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe); @@ -1508,8 +1511,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .sup(probe.xform_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => obligations, - Err(_) => { - debug!("--> cannot relate self-types"); + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); return ProbeResult::NoMatch; } }; @@ -1558,7 +1561,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let o = self.resolve_vars_if_possible(o); if !self.predicate_may_hold(&o) { result = ProbeResult::NoMatch; - possibly_unsatisfied_predicates.push((o.predicate, None)); + possibly_unsatisfied_predicates.push(( + o.predicate, + None, + Some(o.cause), + )); } } } @@ -1604,8 +1611,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } else { Some(predicate) }; - possibly_unsatisfied_predicates - .push((nested_predicate, p)); + possibly_unsatisfied_predicates.push(( + nested_predicate, + p, + Some(obligation.cause.clone()), + )); } } } @@ -1613,7 +1623,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Some nested subobligation of this predicate // failed. let predicate = self.resolve_vars_if_possible(predicate); - possibly_unsatisfied_predicates.push((predicate, None)); + possibly_unsatisfied_predicates.push((predicate, None, None)); } } false @@ -1632,7 +1642,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let o = self.resolve_vars_if_possible(o); if !self.predicate_may_hold(&o) { result = ProbeResult::NoMatch; - possibly_unsatisfied_predicates.push((o.predicate, None)); + possibly_unsatisfied_predicates.push((o.predicate, None, Some(o.cause))); } } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 6411c062fea..b4508368e26 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -17,7 +17,9 @@ use rustc_span::lev_distance; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::{FulfillmentError, Obligation}; +use rustc_trait_selection::traits::{ + FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, +}; use std::cmp::Ordering; use std::iter; @@ -791,9 +793,88 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, } }; + + // Find all the requirements that come from a local `impl` block. + let mut skip_list: FxHashSet<_> = Default::default(); + let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default(); + for (data, p, parent_p) in unsatisfied_predicates + .iter() + .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) + .filter_map(|(p, parent, c)| match c.code { + ObligationCauseCode::ImplDerivedObligation(ref data) => { + Some((data, p, parent)) + } + _ => None, + }) + { + let parent_trait_ref = data.parent_trait_ref; + let parent_def_id = parent_trait_ref.def_id(); + let path = parent_trait_ref.print_only_trait_path(); + let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); + let mut candidates = vec![]; + self.tcx.for_each_relevant_impl( + parent_def_id, + parent_trait_ref.self_ty().skip_binder(), + |impl_def_id| match self.tcx.hir().get_if_local(impl_def_id) { + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { .. }), + .. + })) => { + candidates.push(impl_def_id); + } + _ => {} + }, + ); + if let [def_id] = &candidates[..] { + match self.tcx.hir().get_if_local(*def_id) { + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), + .. + })) => { + if let Some(pred) = parent_p { + // Done to add the "doesn't satisfy" `span_label`. + let _ = format_pred(*pred); + } + skip_list.insert(p); + let mut spans = Vec::with_capacity(2); + if let Some(trait_ref) = of_trait { + spans.push(trait_ref.path.span); + } + spans.push(self_ty.span); + let entry = spanned_predicates.entry(spans.into()); + entry + .or_insert_with(|| (path, tr_self_ty, Vec::new())) + .2 + .push(p); + } + _ => {} + } + } + } + for (span, (path, self_ty, preds)) in spanned_predicates { + err.span_note( + span, + &format!( + "the following trait bounds were not satisfied because of the \ + requirements of the implementation of `{}` for `{}`:\n{}", + path, + self_ty, + preds + .into_iter() + // .map(|pred| format!("{:?}", pred)) + .filter_map(|pred| format_pred(*pred)) + .map(|(p, _)| format!("`{}`", p)) + .collect::<Vec<_>>() + .join("\n"), + ), + ); + } + + // The requirements that didn't have an `impl` span to show. let mut bound_list = unsatisfied_predicates .iter() - .filter_map(|(pred, parent_pred)| { + .filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred)) + .filter_map(|(pred, parent_pred, _cause)| { format_pred(*pred).map(|(p, self_ty)| match parent_pred { None => format!("`{}`", &p), Some(parent_pred) => match format_pred(*parent_pred) { @@ -836,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (span, msg) in bound_spans.into_iter() { err.span_label(span, &msg); } - if !bound_list.is_empty() { + if !bound_list.is_empty() || !skip_list.is_empty() { let bound_list = bound_list .into_iter() .map(|(_, path)| path) @@ -846,9 +927,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.set_primary_message(&format!( "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied" )); - err.note(&format!( - "the following trait bounds were not satisfied:\n{bound_list}" - )); + if !bound_list.is_empty() { + err.note(&format!( + "the following trait bounds were not satisfied:\n{bound_list}" + )); + } self.suggest_derive(&mut err, &unsatisfied_predicates); unsatisfied_bounds = true; @@ -1062,18 +1145,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_note(spans, &msg); } - let preds: Vec<_> = errors.iter().map(|e| (e.obligation.predicate, None)).collect(); + let preds: Vec<_> = errors + .iter() + .map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone()))) + .collect(); self.suggest_derive(err, &preds); } fn suggest_derive( &self, err: &mut DiagnosticBuilder<'_>, - unsatisfied_predicates: &Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>, + unsatisfied_predicates: &Vec<( + ty::Predicate<'tcx>, + Option<ty::Predicate<'tcx>>, + Option<ObligationCause<'tcx>>, + )>, ) { let mut derives = Vec::<(String, Span, String)>::new(); let mut traits = Vec::<Span>::new(); - for (pred, _) in unsatisfied_predicates { + for (pred, _, _) in unsatisfied_predicates { let trait_pred = match pred.kind().skip_binder() { ty::PredicateKind::Trait(trait_pred) => trait_pred, _ => continue, @@ -1264,7 +1354,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name: Ident, source: SelfSource<'tcx>, valid_out_of_scope_traits: Vec<DefId>, - unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)], + unsatisfied_predicates: &[( + ty::Predicate<'tcx>, + Option<ty::Predicate<'tcx>>, + Option<ObligationCause<'tcx>>, + )], unsatisfied_bounds: bool, ) { let mut alt_rcvr_sugg = false; @@ -1380,7 +1474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // this isn't perfect (that is, there are cases when // implementing a trait would be legal but is rejected // here). - unsatisfied_predicates.iter().all(|(p, _)| { + unsatisfied_predicates.iter().all(|(p, _, _)| { match p.kind().skip_binder() { // Hide traits if they are present in predicates as they can be fixed without // having to implement them. diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index 1080f947732..45a906a3947 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -13,12 +13,16 @@ LL | struct NotClone; LL | Bar::<NotClone> { x: 1 }.clone(); | ^^^^^ method cannot be called on `Bar<NotClone>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NotClone: Clone` - which is required by `Bar<NotClone>: Clone` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `Clone` for `_`: + `NotClone: Clone` + --> $DIR/derive-assoc-type-not-impl.rs:6:10 + | +LL | #[derive(Clone)] + | ^^^^^ = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NotClone` with `#[derive(Clone)]` | LL | #[derive(Clone)] diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs index 6db249221b8..8b6f7c41a7c 100644 --- a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs +++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs @@ -12,6 +12,7 @@ trait M { } impl<T: X<Y<i32> = i32>> M for T {} +//~^ NOTE the following trait bounds were not satisfied struct S; //~^ NOTE method `f` not found for this @@ -26,7 +27,6 @@ fn f(a: S) { a.f(); //~^ ERROR the method `f` exists for struct `S`, but its trait bounds were not satisfied //~| NOTE method cannot be called on `S` due to unsatisfied trait bounds - //~| NOTE the following trait bounds were not satisfied: } fn main() {} diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr index 8af9fbed872..3eeb9540e73 100644 --- a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr +++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr @@ -1,5 +1,5 @@ error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied - --> $DIR/method-unsatified-assoc-type-predicate.rs:26:7 + --> $DIR/method-unsatified-assoc-type-predicate.rs:27:7 | LL | struct S; | --------- @@ -11,9 +11,12 @@ LL | struct S; LL | a.f(); | ^ method cannot be called on `S` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `<S as X>::Y<i32> = i32` - which is required by `S: M` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `M` for `_`: + `<S as X>::Y<i32> = i32` + --> $DIR/method-unsatified-assoc-type-predicate.rs:14:26 + | +LL | impl<T: X<Y<i32> = i32>> M for T {} + | ^ ^ error: aborting due to previous error diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index a769872d83a..a497c6257da 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -10,13 +10,14 @@ LL | pub struct Map<S, F> { LL | let filter = map.filterx(|x: &_| true); | ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` - `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` - `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`: + `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + --> $DIR/issue-30786.rs:106:9 + | +LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} + | ^^^^^^^^^ ^ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`, but its trait bounds were not satisfied --> $DIR/issue-30786.rs:141:24 @@ -30,13 +31,14 @@ LL | pub struct Filter<S, F> { LL | let count = filter.countx(); | ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` - `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` - `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`: + `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + --> $DIR/issue-30786.rs:106:9 + | +LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} + | ^^^^^^^^^ ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index a769872d83a..a497c6257da 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -10,13 +10,14 @@ LL | pub struct Map<S, F> { LL | let filter = map.filterx(|x: &_| true); | ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` - `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` - `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` - which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`: + `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream` + --> $DIR/issue-30786.rs:106:9 + | +LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} + | ^^^^^^^^^ ^ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`, but its trait bounds were not satisfied --> $DIR/issue-30786.rs:141:24 @@ -30,13 +31,14 @@ LL | pub struct Filter<S, F> { LL | let count = filter.countx(); | ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` - `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` - `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` - which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`: + `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + --> $DIR/issue-30786.rs:106:9 + | +LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} + | ^^^^^^^^^ ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index ce981bc0098..81e2a9a1ffc 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -20,8 +20,12 @@ LL | struct MyStruct; LL | println!("{}", MyStruct.foo_one()); | ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `MyStruct: Foo` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `Foo` for `_`: + `MyStruct: Foo` + --> $DIR/specialization-trait-not-implemented.rs:14:17 + | +LL | default impl<T> Foo for T { + | ^^^ ^ note: the following trait must be implemented --> $DIR/specialization-trait-not-implemented.rs:7:1 | |
