diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 0c5c80ea89078..19381f992e42a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -894,7 +894,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [candidate] => format!( "the method of the same name on {} `{}`", match candidate.kind { - probe::CandidateKind::InherentImplCandidate(..) => "the inherent impl for", + probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for", _ => "trait", }, self.tcx.def_path_str(candidate.item.container_id(self.tcx)) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index bdc796aca3a46..25bcfce3275a2 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::ToPredicate; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint; use rustc_span::def_id::DefId; @@ -31,13 +31,12 @@ use rustc_span::edit_distance::{ }; use rustc_span::symbol::sym; use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP}; -use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy; use rustc_trait_selection::traits::query::method_autoderef::{ CandidateStep, MethodAutoderefStepsResult, }; use rustc_trait_selection::traits::query::CanonicalTyGoal; -use rustc_trait_selection::traits::NormalizeExt; +use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::cell::RefCell; use std::cmp::max; @@ -99,39 +98,6 @@ impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> { #[derive(Debug, Clone)] pub(crate) struct Candidate<'tcx> { - // Candidates are (I'm not quite sure, but they are mostly) basically - // some metadata on top of a `ty::AssocItem` (without args). - // - // However, method probing wants to be able to evaluate the predicates - // for a function with the args applied - for example, if a function - // has `where Self: Sized`, we don't want to consider it unless `Self` - // is actually `Sized`, and similarly, return-type suggestions want - // to consider the "actual" return type. - // - // The way this is handled is through `xform_self_ty`. It contains - // the receiver type of this candidate, but `xform_self_ty`, - // `xform_ret_ty` and `kind` (which contains the predicates) have the - // generic parameters of this candidate instantiated with the *same set* - // of inference variables, which acts as some weird sort of "query". - // - // When we check out a candidate, we require `xform_self_ty` to be - // a subtype of the passed-in self-type, and this equates the type - // variables in the rest of the fields. - // - // For example, if we have this candidate: - // ``` - // trait Foo { - // fn foo(&self) where Self: Sized; - // } - // ``` - // - // Then `xform_self_ty` will be `&'erased ?X` and `kind` will contain - // the predicate `?X: Sized`, so if we are evaluating `Foo` for a - // the receiver `&T`, we'll do the subtyping which will make `?X` - // get the right value, then when we evaluate the predicate we'll check - // if `T: Sized`. - xform_self_ty: Ty<'tcx>, - xform_ret_ty: Option>, pub(crate) item: ty::AssocItem, pub(crate) kind: CandidateKind<'tcx>, pub(crate) import_ids: SmallVec<[LocalDefId; 1]>, @@ -139,17 +105,10 @@ pub(crate) struct Candidate<'tcx> { #[derive(Debug, Clone)] pub(crate) enum CandidateKind<'tcx> { - InherentImplCandidate( - GenericArgsRef<'tcx>, - // Normalize obligations - Vec>, - ), - ObjectCandidate, - TraitCandidate(ty::TraitRef<'tcx>), - WhereClauseCandidate( - // Trait - ty::PolyTraitRef<'tcx>, - ), + InherentImplCandidate(DefId), + ObjectCandidate(ty::PolyTraitRef<'tcx>), + TraitCandidate(ty::PolyTraitRef<'tcx>), + WhereClauseCandidate(ty::PolyTraitRef<'tcx>), } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -736,42 +695,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.record_static_candidate(CandidateSource::Impl(impl_def_id)); continue; } - - let (impl_ty, impl_args) = self.impl_ty_and_args(impl_def_id); - let impl_ty = impl_ty.instantiate(self.tcx, impl_args); - - debug!("impl_ty: {:?}", impl_ty); - - // Determine the receiver type that the method itself expects. - let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_args); - debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty); - - // We can't use `FnCtxt::normalize` as it will pollute the - // fcx's fulfillment context after this probe is over. - // - // Note: we only normalize `xform_self_ty` here since the normalization - // of the return type can lead to inference results that prohibit - // valid candidates from being found, see issue #85671 - // - // FIXME Postponing the normalization of the return type likely only hides a deeper bug, - // which might be caused by the `param_env` itself. The clauses of the `param_env` - // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized, - // see issue #89650 - let cause = traits::ObligationCause::misc(self.span, self.body_id); - let InferOk { value: xform_self_ty, obligations } = - self.fcx.at(&cause, self.param_env).normalize(xform_self_ty); - - debug!( - "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}", - xform_self_ty, xform_ret_ty - ); - self.push_candidate( Candidate { - xform_self_ty, - xform_ret_ty, item, - kind: InherentImplCandidate(impl_args, obligations), + kind: InherentImplCandidate(impl_def_id), import_ids: smallvec![], }, true, @@ -803,26 +730,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // a `&self` method will wind up with an argument type like `&dyn Trait`. let trait_ref = principal.with_self_ty(self.tcx, self_ty); self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| { - if new_trait_ref.has_non_region_bound_vars() { - this.dcx().span_delayed_bug( - this.span, - "tried to select method from HRTB with non-lifetime bound vars", - ); - return; - } - - let new_trait_ref = this.instantiate_bound_regions_with_erased(new_trait_ref); - - let (xform_self_ty, xform_ret_ty) = - this.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.args); this.push_candidate( - Candidate { - xform_self_ty, - xform_ret_ty, - item, - kind: ObjectCandidate, - import_ids: smallvec![], - }, + Candidate { item, kind: ObjectCandidate(new_trait_ref), import_ids: smallvec![] }, true, ); }); @@ -853,19 +762,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }); self.elaborate_bounds(bounds, |this, poly_trait_ref, item| { - let trait_ref = this.instantiate_binder_with_fresh_vars( - this.span, - infer::BoundRegionConversionTime::FnCall, - poly_trait_ref, - ); - - let (xform_self_ty, xform_ret_ty) = - this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.args); - this.push_candidate( Candidate { - xform_self_ty, - xform_ret_ty, item, kind: WhereClauseCandidate(poly_trait_ref), import_ids: smallvec![], @@ -922,27 +820,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - fn matches_return_type( - &self, - method: ty::AssocItem, - self_ty: Option>, - expected: Ty<'tcx>, - ) -> bool { + fn matches_return_type(&self, method: ty::AssocItem, expected: Ty<'tcx>) -> bool { match method.kind { ty::AssocKind::Fn => self.probe(|_| { let args = self.fresh_args_for_item(self.span, method.def_id); let fty = self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args); let fty = self.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, fty); - - if let Some(self_ty) = self_ty { - if self - .at(&ObligationCause::dummy(), self.param_env) - .sup(DefineOpaqueTypes::No, fty.inputs()[0], self_ty) - .is_err() - { - return false; - } - } self.can_sub(self.param_env, fty.output(), expected) }), _ => false, @@ -971,21 +854,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { bound_trait_ref.def_id(), )); } else { - let new_trait_ref = self.instantiate_binder_with_fresh_vars( - self.span, - infer::BoundRegionConversionTime::FnCall, - bound_trait_ref, - ); - - let (xform_self_ty, xform_ret_ty) = - self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.args); self.push_candidate( Candidate { - xform_self_ty, - xform_ret_ty, item, import_ids: import_ids.clone(), - kind: TraitCandidate(new_trait_ref), + kind: TraitCandidate(bound_trait_ref), }, false, ); @@ -1004,16 +877,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.record_static_candidate(CandidateSource::Trait(trait_def_id)); continue; } - - let (xform_self_ty, xform_ret_ty) = - self.xform_self_ty(item, trait_ref.self_ty(), trait_args); self.push_candidate( Candidate { - xform_self_ty, - xform_ret_ty, item, import_ids: import_ids.clone(), - kind: TraitCandidate(trait_ref), + kind: TraitCandidate(ty::Binder::dummy(trait_ref)), }, false, ); @@ -1033,7 +901,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .filter(|candidate| candidate_filter(&candidate.item)) .filter(|candidate| { if let Some(return_ty) = self.return_type { - self.matches_return_type(candidate.item, None, return_ty) + self.matches_return_type(candidate.item, return_ty) } else { true } @@ -1446,16 +1314,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource { match candidate.kind { - InherentImplCandidate(..) => { + InherentImplCandidate(_) => { CandidateSource::Impl(candidate.item.container_id(self.tcx)) } - ObjectCandidate | WhereClauseCandidate(_) => { + ObjectCandidate(_) | WhereClauseCandidate(_) => { CandidateSource::Trait(candidate.item.container_id(self.tcx)) } TraitCandidate(trait_ref) => self.probe(|_| { + let trait_ref = + self.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, trait_ref); + let (xform_self_ty, _) = + self.xform_self_ty(candidate.item, trait_ref.self_ty(), trait_ref.args); let _ = self.at(&ObligationCause::dummy(), self.param_env).sup( DefineOpaqueTypes::No, - candidate.xform_self_ty, + xform_self_ty, self_ty, ); match self.select_trait_candidate(trait_ref) { @@ -1482,54 +1354,38 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) -> ProbeResult { debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe); - self.probe(|_| { - // First check that the self type can be related. - let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup( - DefineOpaqueTypes::No, - probe.xform_self_ty, - self_ty, - ) { - Ok(InferOk { obligations, value: () }) => obligations, - Err(err) => { - debug!("--> cannot relate self-types {:?}", err); - return ProbeResult::NoMatch; - } - }; + self.probe(|snapshot| { + let outer_universe = self.universe(); let mut result = ProbeResult::Match; - let mut xform_ret_ty = probe.xform_ret_ty; - debug!(?xform_ret_ty); + let cause = &self.misc(self.span); + let ocx = ObligationCtxt::new(self); - let cause = traits::ObligationCause::misc(self.span, self.body_id); + let mut trait_predicate = None; + let (mut xform_self_ty, mut xform_ret_ty); - let mut parent_pred = None; - - // If so, impls may carry other conditions (e.g., where - // clauses) that must be considered. Make sure that those - // match as well (or at least may match, sometimes we - // don't have enough information to fully evaluate). match probe.kind { - InherentImplCandidate(args, ref ref_obligations) => { - // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`, - // see the reasons mentioned in the comments in `assemble_inherent_impl_probe` - // for why this is necessary - let InferOk { - value: normalized_xform_ret_ty, - obligations: normalization_obligations, - } = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty); - xform_ret_ty = normalized_xform_ret_ty; - debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty); - + InherentImplCandidate(impl_def_id) => { + let (impl_ty, impl_args) = self.impl_ty_and_args(impl_def_id); + (xform_self_ty, xform_ret_ty) = + self.xform_self_ty(probe.item, impl_ty, impl_args); + xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + // FIXME: Weirdly, we normalize the ret ty in this candidate, but no other candidates. + xform_ret_ty = ocx.normalize(cause, self.param_env, xform_ret_ty); + match ocx.eq_no_opaques(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); + return ProbeResult::NoMatch; + } + } // Check whether the impl imposes obligations we have to worry about. let impl_def_id = probe.item.container_id(self.tcx); - let impl_bounds = self.tcx.predicates_of(impl_def_id); - let impl_bounds = impl_bounds.instantiate(self.tcx, args); - - let InferOk { value: impl_bounds, obligations: norm_obligations } = - self.fcx.at(&cause, self.param_env).normalize(impl_bounds); - + let impl_bounds = + self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args); + let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds); // Convert the bounds into obligations. - let impl_obligations = traits::predicates_for_generics( + ocx.register_obligations(traits::predicates_for_generics( |idx, span| { let code = if span.is_dummy() { traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx) @@ -1545,106 +1401,56 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, self.param_env, impl_bounds, - ); - - let candidate_obligations = impl_obligations - .chain(norm_obligations) - .chain(ref_obligations.iter().cloned()) - .chain(normalization_obligations); - - // Evaluate those obligations to see if they might possibly hold. - for o in candidate_obligations { - let o = self.resolve_vars_if_possible(o); - if !self.predicate_may_hold(&o) { - result = ProbeResult::NoMatch; - let parent_o = o.clone(); - let implied_obligations = traits::elaborate(self.tcx, vec![o]); - for o in implied_obligations { - let parent = if o == parent_o { - None - } else { - if o.predicate.to_opt_poly_trait_pred().map(|p| p.def_id()) - == self.tcx.lang_items().sized_trait() - { - // We don't care to talk about implicit `Sized` bounds. - continue; - } - Some(parent_o.predicate) - }; - if !self.predicate_may_hold(&o) { - possibly_unsatisfied_predicates.push(( - o.predicate, - parent, - Some(o.cause), - )); - } - } - } - } - } - - ObjectCandidate | WhereClauseCandidate(..) => { - // These have no additional conditions to check. + )); } - - TraitCandidate(trait_ref) => { + TraitCandidate(poly_trait_ref) => { + // Some trait methods are excluded for arrays before 2021. + // (`array.into_iter()` wants a slice iterator for compatibility.) if let Some(method_name) = self.method_name { - // Some trait methods are excluded for arrays before 2021. - // (`array.into_iter()` wants a slice iterator for compatibility.) if self_ty.is_array() && !method_name.span.at_least_rust_2021() { - let trait_def = self.tcx.trait_def(trait_ref.def_id); + let trait_def = self.tcx.trait_def(poly_trait_ref.def_id()); if trait_def.skip_array_during_method_dispatch { return ProbeResult::NoMatch; } } } - let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx); - parent_pred = Some(predicate); - let obligation = - traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate); - if !self.predicate_may_hold(&obligation) { - result = ProbeResult::NoMatch; - if self.probe(|_| { - match self.select_trait_candidate(trait_ref) { - Err(_) => return true, - Ok(Some(impl_source)) - if !impl_source.borrow_nested_obligations().is_empty() => - { - for obligation in impl_source.borrow_nested_obligations() { - // Determine exactly which obligation wasn't met, so - // that we can give more context in the error. - if !self.predicate_may_hold(obligation) { - let nested_predicate = - self.resolve_vars_if_possible(obligation.predicate); - let predicate = - self.resolve_vars_if_possible(predicate); - let p = if predicate == nested_predicate { - // Avoid "`MyStruct: Foo` which is required by - // `MyStruct: Foo`" in E0599. - None - } else { - Some(predicate) - }; - possibly_unsatisfied_predicates.push(( - nested_predicate, - p, - Some(obligation.cause.clone()), - )); - } - } - } - _ => { - // Some nested subobligation of this predicate - // failed. - let predicate = self.resolve_vars_if_possible(predicate); - possibly_unsatisfied_predicates.push((predicate, None, None)); - } - } - false - }) { - // This candidate's primary obligation doesn't even - // select - don't bother registering anything in - // `potentially_unsatisfied_predicates`. + + let trait_ref = self.instantiate_binder_with_fresh_vars( + self.span, + infer::FnCall, + poly_trait_ref, + ); + (xform_self_ty, xform_ret_ty) = + self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); + xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + match ocx.eq_no_opaques(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); + return ProbeResult::NoMatch; + } + } + ocx.register_obligation(traits::Obligation::new( + self.tcx, + cause.clone(), + self.param_env, + ty::Binder::dummy(trait_ref), + )); + trait_predicate = Some(ty::Binder::dummy(trait_ref).to_predicate(self.tcx)); + } + ObjectCandidate(poly_trait_ref) | WhereClauseCandidate(poly_trait_ref) => { + let trait_ref = self.instantiate_binder_with_fresh_vars( + self.span, + infer::FnCall, + poly_trait_ref, + ); + (xform_self_ty, xform_ret_ty) = + self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); + xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + match ocx.eq_no_opaques(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); return ProbeResult::NoMatch; } } @@ -1652,11 +1458,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } // Evaluate those obligations to see if they might possibly hold. - for o in sub_obligations { - let o = self.resolve_vars_if_possible(o); - if !self.predicate_may_hold(&o) { - result = ProbeResult::NoMatch; - possibly_unsatisfied_predicates.push((o.predicate, parent_pred, Some(o.cause))); + for error in ocx.select_where_possible() { + result = ProbeResult::NoMatch; + if let Some(trait_predicate) = trait_predicate + && self.resolve_vars_if_possible(error.obligation.predicate) + == self.resolve_vars_if_possible(trait_predicate) + { + // Don't report possibly unsatisfied predicates if the root + // trait obligation from a `TraitCandidate` is unsatisfied. + // That just means the candidate doesn't hold. + } else { + possibly_unsatisfied_predicates.push(( + error.obligation.predicate, + Some(error.root_obligation.predicate) + .filter(|predicate| *predicate != error.obligation.predicate), + Some(error.obligation.cause), + )); } } @@ -1668,38 +1485,34 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // We don't normalize the other candidates for perf/backwards-compat reasons... // but `self.return_type` is only set on the diagnostic-path, so we // should be okay doing it here. - if !matches!(probe.kind, InherentImplCandidate(..)) { - let InferOk { - value: normalized_xform_ret_ty, - obligations: normalization_obligations, - } = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty); - xform_ret_ty = normalized_xform_ret_ty; - debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty); - // Evaluate those obligations to see if they might possibly hold. - for o in normalization_obligations { - let o = self.resolve_vars_if_possible(o); - if !self.predicate_may_hold(&o) { - result = ProbeResult::NoMatch; - possibly_unsatisfied_predicates.push(( - o.predicate, - None, - Some(o.cause), - )); - } - } + if !matches!(probe.kind, InherentImplCandidate(_)) { + xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty); } debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty); - if let ProbeResult::Match = result - && self - .at(&ObligationCause::dummy(), self.param_env) - .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty) - .is_err() - { - result = ProbeResult::BadReturnType; + match ocx.sup(cause, self.param_env, return_ty, xform_ret_ty) { + Ok(()) => {} + Err(_) => { + result = ProbeResult::BadReturnType; + } + } + + // Evaluate those obligations to see if they might possibly hold. + for error in ocx.select_where_possible() { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push(( + error.obligation.predicate, + Some(error.root_obligation.predicate) + .filter(|predicate| *predicate != error.obligation.predicate), + Some(error.root_obligation.cause), + )); } } + if let Err(_) = self.leak_check(outer_universe, Some(snapshot)) { + result = ProbeResult::NoMatch; + } + result }) } @@ -1890,40 +1703,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn_sig.instantiate(self.tcx, args) }; - self.instantiate_bound_regions_with_erased(xform_fn_sig) + self.tcx.instantiate_bound_regions_with_erased(xform_fn_sig) } /// Gets the type of an impl and generate generic parameters with inference vars. - fn impl_ty_and_args( - &self, - impl_def_id: DefId, - ) -> (ty::EarlyBinder>, GenericArgsRef<'tcx>) { - (self.tcx.type_of(impl_def_id), self.fresh_args_for_item(self.span, impl_def_id)) - } - - /// Replaces late-bound-regions bound by `value` with `'static` using - /// `ty::instantiate_bound_regions_with_erased`. - /// - /// This is only a reasonable thing to do during the *probe* phase, not the *confirm* phase, of - /// method matching. It is reasonable during the probe phase because we don't consider region - /// relationships at all. Therefore, we can just replace all the region variables with 'static - /// rather than creating fresh region variables. This is nice for two reasons: - /// - /// 1. Because the numbers of the region variables would otherwise be fairly unique to this - /// particular method call, it winds up creating fewer types overall, which helps for memory - /// usage. (Admittedly, this is a rather small effect, though measurable.) - /// - /// 2. It makes it easier to deal with higher-ranked trait bounds, because we can replace any - /// late-bound regions with 'static. Otherwise, if we were going to replace late-bound - /// regions with actual region variables as is proper, we'd have to ensure that the same - /// region got replaced with the same variable, which requires a bit more coordination - /// and/or tracking the instantiations and - /// so forth. - fn instantiate_bound_regions_with_erased(&self, value: ty::Binder<'tcx, T>) -> T - where - T: TypeFoldable>, - { - self.tcx.instantiate_bound_regions_with_erased(value) + fn impl_ty_and_args(&self, impl_def_id: DefId) -> (Ty<'tcx>, GenericArgsRef<'tcx>) { + let args = self.fresh_args_for_item(self.span, impl_def_id); + (self.tcx.type_of(impl_def_id).instantiate(self.tcx, args), args) } /// Determine if the given associated item type is relevant in the current context. @@ -2047,10 +1833,10 @@ impl<'tcx> Candidate<'tcx> { Pick { item: self.item, kind: match self.kind { - InherentImplCandidate(..) => InherentImplPick, - ObjectCandidate => ObjectPick, + InherentImplCandidate(_) => InherentImplPick, + ObjectCandidate(_) => ObjectPick, TraitCandidate(_) => TraitPick, - WhereClauseCandidate(ref trait_ref) => { + WhereClauseCandidate(trait_ref) => { // Only trait derived from where-clauses should // appear here, so they should not contain any // inference variables or other artifacts. This @@ -2061,7 +1847,7 @@ impl<'tcx> Candidate<'tcx> { && !trait_ref.skip_binder().args.has_placeholders() ); - WhereClausePick(*trait_ref) + WhereClausePick(trait_ref) } }, import_ids: self.import_ids.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 9fbec174ce8d2..68c76dcf29734 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -129,6 +129,19 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } + pub fn eq_no_opaques>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + expected: T, + actual: T, + ) -> Result<(), TypeError<'tcx>> { + self.infcx + .at(cause, param_env) + .eq(DefineOpaqueTypes::No, expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + } + /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`. pub fn sub>( &self, diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index 9e17189671827..4d637c9728385 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -2,15 +2,13 @@ error[E0599]: the method `insert` exists for struct `HashSet`, but its tr --> $DIR/issue-91550.rs:8:8 | LL | struct Value(u32); - | ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq` + | ------------ doesn't satisfy `Value: Eq` or `Value: Hash` ... LL | hs.insert(Value(0)); | ^^^^^^ | = note: the following trait bounds were not satisfied: `Value: Eq` - `Value: PartialEq` - which is required by `Value: Eq` `Value: Hash` help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]` | @@ -22,7 +20,7 @@ error[E0599]: the method `use_eq` exists for struct `Object`, but its --> $DIR/issue-91550.rs:26:9 | LL | pub struct NoDerives; - | -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq` + | -------------------- doesn't satisfy `NoDerives: Eq` LL | LL | struct Object(T); | ---------------- method `use_eq` not found for this struct @@ -37,9 +35,6 @@ LL | impl Object { | ^^ --------- | | | unsatisfied trait bound introduced here - = note: the following trait bounds were not satisfied: - `NoDerives: PartialEq` - which is required by `NoDerives: Eq` help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` | LL + #[derive(Eq, PartialEq)] @@ -50,7 +45,7 @@ error[E0599]: the method `use_ord` exists for struct `Object`, but it --> $DIR/issue-91550.rs:27:9 | LL | pub struct NoDerives; - | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd` + | -------------------- doesn't satisfy `NoDerives: Ord` LL | LL | struct Object(T); | ---------------- method `use_ord` not found for this struct @@ -65,13 +60,6 @@ LL | impl Object { | ^^^ --------- | | | unsatisfied trait bound introduced here - = note: the following trait bounds were not satisfied: - `NoDerives: PartialOrd` - which is required by `NoDerives: Ord` - `NoDerives: PartialEq` - which is required by `NoDerives: Ord` - `NoDerives: Eq` - which is required by `NoDerives: Ord` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL + #[derive(Eq, Ord, PartialEq, PartialOrd)] @@ -82,7 +70,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object $DIR/issue-91550.rs:28:9 | LL | pub struct NoDerives; - | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd` + | -------------------- doesn't satisfy `NoDerives: Ord` or `NoDerives: PartialOrd` LL | LL | struct Object(T); | ---------------- method `use_ord_and_partial_ord` not found for this struct @@ -100,13 +88,6 @@ LL | impl Object { | | | | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here - = note: the following trait bounds were not satisfied: - `NoDerives: PartialEq` - which is required by `NoDerives: Ord` - `NoDerives: Eq` - which is required by `NoDerives: Ord` - `NoDerives: PartialEq` - which is required by `NoDerives: PartialOrd` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL + #[derive(Eq, Ord, PartialEq, PartialOrd)] diff --git a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr index 7813370ae63f8..b31689dbf7365 100644 --- a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr +++ b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr @@ -15,20 +15,15 @@ help: consider relaxing the implicit `Sized` restriction LL | type Pointer: Deref + ?Sized; | ++++++++ -error[E0599]: the size for values of type `Node` cannot be known at compilation time +error[E0599]: the variant or associated item `new` exists for enum `Node`, but its trait bounds were not satisfied --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:31:35 | LL | enum Node { - | ------------------------------ variant or associated item `new` not found for this enum because it doesn't satisfy `Node: Sized` + | ------------------------------ variant or associated item `new` not found for this enum ... LL | let mut list = RcNode::::new(); - | ^^^ doesn't have a size known at compile-time + | ^^^ variant or associated item cannot be called on `Node` due to unsatisfied trait bounds | -note: trait bound `Node: Sized` was not satisfied - --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:4:18 - | -LL | type Pointer: Deref; - | ------- ^ unsatisfied trait bound introduced here note: trait bound `(dyn Deref> + 'static): Sized` was not satisfied --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:23:29 | @@ -37,8 +32,6 @@ LL | impl Node LL | where LL | P::Pointer>: Sized, | ^^^^^ unsatisfied trait bound introduced here -note: the trait `Sized` must be implemented - --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr index 699a4ecc42bb9..450893e24f160 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr @@ -2,7 +2,7 @@ error[E0599]: the method `filterx` exists for struct `Map $DIR/issue-30786.rs:120:22 | LL | pub struct Map { - | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt` + | -------------------- method `filterx` not found for this struct ... LL | let filter = map.filterx(|x: &_| true); | ^^^^^^^ method cannot be called on `Map` due to unsatisfied trait bounds @@ -10,7 +10,6 @@ LL | let filter = map.filterx(|x: &_| true); note: the following trait bounds were not satisfied: `&'a mut &Map: Stream` `&'a mut &mut Map: Stream` - `&'a mut Map: Stream` --> $DIR/issue-30786.rs:98:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} @@ -26,7 +25,7 @@ error[E0599]: the method `countx` exists for struct `Filter $DIR/issue-30786.rs:132:24 | LL | pub struct Filter { - | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt` + | ----------------------- method `countx` not found for this struct ... LL | let count = filter.countx(); | ^^^^^^ method cannot be called due to unsatisfied trait bounds @@ -34,7 +33,6 @@ LL | let count = filter.countx(); note: the following trait bounds were not satisfied: `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream` `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream` - `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream` --> $DIR/issue-30786.rs:98:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 9ec581c231b7b..f6798f55a472c 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -1,30 +1,27 @@ -error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied - --> $DIR/issue-62742.rs:4:5 +error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied + --> $DIR/issue-62742.rs:4:16 | LL | WrongImpl::foo(0i32); - | ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` + | ^^^ function or associated item cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds +... +LL | pub struct RawImpl(PhantomData); + | --------------------- doesn't satisfy `RawImpl<_>: Raw<_>` +... +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ----------------------------------------- function or associated item `foo` not found for this struct | - = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` -note: required by a bound in `SafeImpl::::foo` +note: trait bound `RawImpl<_>: Raw<_>` was not satisfied --> $DIR/issue-62742.rs:29:20 | LL | impl> SafeImpl { - | ^^^^^^ required by this bound in `SafeImpl::::foo` -LL | pub fn foo(value: A::Value) {} - | --- required by a bound in this associated function - -error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied - --> $DIR/issue-62742.rs:4:5 - | -LL | WrongImpl::foo(0i32); - | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` - | - = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` -note: required by a bound in `SafeImpl` - --> $DIR/issue-62742.rs:27:35 + | ^^^^^^ -------------- + | | + | unsatisfied trait bound introduced here +note: the trait `Raw` must be implemented + --> $DIR/issue-62742.rs:13:1 | -LL | pub struct SafeImpl>(PhantomData<(A, T)>); - | ^^^^^^ required by this bound in `SafeImpl` +LL | pub trait Raw { + | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied --> $DIR/issue-62742.rs:7:22 @@ -51,6 +48,19 @@ note: the trait `Raw` must be implemented LL | pub trait Raw { | ^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied + --> $DIR/issue-62742.rs:4:5 + | +LL | WrongImpl::foo(0i32); + | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` + | + = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:27:35 + | +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ^^^^^^ required by this bound in `SafeImpl` + error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied --> $DIR/issue-62742.rs:7:5 | diff --git a/tests/ui/impl-trait/issues/issue-84073.stderr b/tests/ui/impl-trait/issues/issue-84073.stderr index ab119a8a4f456..eeb23b130819d 100644 --- a/tests/ui/impl-trait/issues/issue-84073.stderr +++ b/tests/ui/impl-trait/issues/issue-84073.stderr @@ -1,9 +1,29 @@ -error[E0275]: overflow assigning `_` to `Option<_>` - --> $DIR/issue-84073.rs:32:22 +error[E0599]: the method `when` exists for struct `RaceBuilder<_, Never<_>>`, but its trait bounds were not satisfied + --> $DIR/issue-84073.rs:32:27 | +LL | pub struct Never(PhantomData); + | ------------------- doesn't satisfy `Never<_>: StatefulFuture>` +... +LL | pub struct RaceBuilder { + | ---------------------------- method `when` not found for this struct +... LL | Race::new(|race| race.when()); - | ^^^^ + | ^^^^ method cannot be called on `RaceBuilder<_, Never<_>>` due to unsatisfied trait bounds + | +note: trait bound `Never<_>: StatefulFuture>` was not satisfied + --> $DIR/issue-84073.rs:14:8 + | +LL | impl RaceBuilder + | ----------------- +LL | where +LL | F: StatefulFuture>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here +note: the trait `StatefulFuture` must be implemented + --> $DIR/issue-84073.rs:3:1 + | +LL | pub trait StatefulFuture {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr index 84247a4270484..0468e0522d1e7 100644 --- a/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr +++ b/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr @@ -6,6 +6,7 @@ LL | let _result = &Some(42).as_deref(); | = note: the following trait bounds were not satisfied: `{integer}: Deref` + which is required by `<{integer} as Deref>::Target = _` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr index bf05ab5665cba..cf4e866901cd9 100644 --- a/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr +++ b/tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr @@ -6,6 +6,7 @@ LL | let _result = &mut Some(42).as_deref_mut(); | = note: the following trait bounds were not satisfied: `{integer}: Deref` + which is required by `<{integer} as Deref>::Target = _` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr index ac744a6d3b672..0e3e7999044fc 100644 --- a/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr +++ b/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr @@ -6,6 +6,7 @@ LL | let _result = &Ok(42).as_deref(); | = note: the following trait bounds were not satisfied: `{integer}: Deref` + which is required by `<{integer} as Deref>::Target = _` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr index 688d2cf3486e8..43143db0da742 100644 --- a/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr +++ b/tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr @@ -6,6 +6,7 @@ LL | let _result = &mut Ok(42).as_deref_mut(); | = note: the following trait bounds were not satisfied: `{integer}: Deref` + which is required by `<{integer} as Deref>::Target = _` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-57362-2.stderr b/tests/ui/issues/issue-57362-2.stderr index 57477f5341ede..a78c96dbd0d59 100644 --- a/tests/ui/issues/issue-57362-2.stderr +++ b/tests/ui/issues/issue-57362-2.stderr @@ -1,11 +1,9 @@ -error[E0599]: the function or associated item `make_g` exists for fn pointer `fn(&())`, but its trait bounds were not satisfied +error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope --> $DIR/issue-57362-2.rs:22:25 | LL | let x = ::make_g(); - | ^^^^^^ function or associated item cannot be called on `fn(&())` due to unsatisfied trait bounds + | ^^^^^^ function or associated item not found in `fn(&())` | - = note: the following trait bounds were not satisfied: - `for<'a> fn(&'a ()): X` = help: items from traits can only be used if the trait is implemented and in scope note: `X` defines an item `make_g`, perhaps you need to implement it --> $DIR/issue-57362-2.rs:8:1 diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr index 6d23319ca7e64..fdf75898ae25d 100644 --- a/tests/ui/mismatched_types/issue-36053-2.stderr +++ b/tests/ui/mismatched_types/issue-36053-2.stderr @@ -21,14 +21,16 @@ error[E0599]: the method `count` exists for struct `Filter>, {cl LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | --------- ^^^^^ method cannot be called due to unsatisfied trait bounds | | - | doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool` or `_: FnMut<(&&str,)>` + | doesn't satisfy `_: FnMut<(&&str,)>` or `_: FnOnce<(&&str,)>` | = note: the following trait bounds were not satisfied: - `<{closure@$DIR/issue-36053-2.rs:7:39: 7:48} as FnOnce<(&&str,)>>::Output = bool` - which is required by `Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` `{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnMut<(&&str,)>` which is required by `Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` - `Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` + `{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnOnce<(&&str,)>` + which is required by `Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` + `{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnMut<(&&str,)>` + which is required by `&mut Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` + `{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnOnce<(&&str,)>` which is required by `&mut Filter>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator` error: aborting due to 2 previous errors diff --git a/tests/ui/missing-trait-bounds/issue-35677.stderr b/tests/ui/missing-trait-bounds/issue-35677.stderr index f73bff51e7ad1..3bfdd4da6dac8 100644 --- a/tests/ui/missing-trait-bounds/issue-35677.stderr +++ b/tests/ui/missing-trait-bounds/issue-35677.stderr @@ -6,8 +6,6 @@ LL | this.is_subset(other) | = note: the following trait bounds were not satisfied: `T: Eq` - `T: PartialEq` - which is required by `T: Eq` `T: Hash` help: consider restricting the type parameters to satisfy the trait bounds | diff --git a/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr b/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr index d1e94bc702cae..679bab63e8531 100644 --- a/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr +++ b/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr @@ -1,11 +1,9 @@ -error[E0599]: the function or associated item `make_g` exists for fn pointer `fn(&())`, but its trait bounds were not satisfied +error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope --> $DIR/issue-57642-higher-ranked-subtype.rs:31:25 | LL | let x = ::make_g(); - | ^^^^^^ function or associated item cannot be called on `fn(&())` due to unsatisfied trait bounds + | ^^^^^^ function or associated item not found in `fn(&())` | - = note: the following trait bounds were not satisfied: - `for<'a> fn(&'a ()): X` = help: items from traits can only be used if the trait is implemented and in scope note: `X` defines an item `make_g`, perhaps you need to implement it --> $DIR/issue-57642-higher-ranked-subtype.rs:4:1 diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 9d6d29ec74eec..ae3a0391eea24 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -74,22 +74,30 @@ LL | struct Struct { error[E0599]: the method `test` exists for struct `Foo, Instant>`, but its trait bounds were not satisfied --> $DIR/derive-trait-for-method-call.rs:40:15 | +LL | enum Enum { + | --------- doesn't satisfy `Enum: Clone` +... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct ... LL | let y = x.test(); | ^^^^ method cannot be called on `Foo, Instant>` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied: - `Instant: Default` - `Vec: Clone` - --> $DIR/derive-trait-for-method-call.rs:20:9 +note: trait bound `Instant: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 | LL | impl Foo { - | ^^^^^ ^^^^^^^ --------- - | | | - | | unsatisfied trait bound introduced here - | unsatisfied trait bound introduced here + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here + = note: the following trait bounds were not satisfied: + `Enum: Clone` + which is required by `Vec: Clone` +help: consider annotating `Enum` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | enum Enum { + | error: aborting due to 3 previous errors diff --git a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr index 74526b4dbc182..49a4db7491ed8 100644 --- a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr +++ b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr @@ -12,13 +12,6 @@ note: trait bound `(): Iterator` was not satisfied | LL | trait IteratorAlias = Iterator; | ------------- ^^^^^^^^ unsatisfied trait bound introduced here -note: trait bound `(): IteratorAlias` was not satisfied - --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:9:9 - | -LL | impl Foo { - | ^^^^^^^^^^^^^ ------ - | | - | unsatisfied trait bound introduced here error: aborting due to 1 previous error diff --git a/tests/ui/traits/method-on-unbounded-type-param.stderr b/tests/ui/traits/method-on-unbounded-type-param.stderr index 0d8bd8ee964e7..7203d820ba0b2 100644 --- a/tests/ui/traits/method-on-unbounded-type-param.stderr +++ b/tests/ui/traits/method-on-unbounded-type-param.stderr @@ -70,7 +70,7 @@ LL | x.cmp(&x); which is required by `Box: Iterator` `dyn T: Ord` which is required by `Box: Ord` - `Box: Iterator` + `dyn T: Iterator` which is required by `&mut Box: Iterator` `dyn T: Iterator` which is required by `&mut dyn T: Iterator` diff --git a/tests/ui/traits/track-obligations.stderr b/tests/ui/traits/track-obligations.stderr index 822fc91e43fea..141f565077a5b 100644 --- a/tests/ui/traits/track-obligations.stderr +++ b/tests/ui/traits/track-obligations.stderr @@ -2,7 +2,10 @@ error[E0599]: the method `check` exists for struct `Client<()>`, but its trait b --> $DIR/track-obligations.rs:83:16 | LL | struct ALayer(C); - | ---------------- doesn't satisfy `<_ as Layer<()>>::Service = as ParticularServiceLayer<()>>::Service` or `ALayer<()>: ParticularServiceLayer<()>` + | ---------------- doesn't satisfy `ALayer<()>: ParticularServiceLayer<()>` +... +LL | struct AService; + | --------------- doesn't satisfy `>::Response = Res` ... LL | struct Client(C); | ---------------- method `check` not found for this struct @@ -10,27 +13,14 @@ LL | struct Client(C); LL | Client(()).check(); | ^^^^^ method cannot be called on `Client<()>` due to unsatisfied trait bounds | -note: trait bound ` as Layer<()>>::Service = as ParticularServiceLayer<()>>::Service` was not satisfied - --> $DIR/track-obligations.rs:35:14 - | -LL | pub trait ParticularServiceLayer: - | ---------------------- -LL | Layer>::Service> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here -note: trait bound `ALayer<()>: ParticularServiceLayer<()>` was not satisfied - --> $DIR/track-obligations.rs:71:16 +note: trait bound `>::Response = Res` was not satisfied + --> $DIR/track-obligations.rs:24:21 | -LL | impl Client - | --------- +LL | impl ParticularService for T + | ----------------- - LL | where -LL | ALayer: ParticularServiceLayer, - | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here -note: the trait `ParticularServiceLayer` must be implemented - --> $DIR/track-obligations.rs:34:1 - | -LL | / pub trait ParticularServiceLayer: -LL | | Layer>::Service> - | |____________________________________________________________________^ +LL | T: Service, + | ^^^^^^^^^^^^^^ unsatisfied trait bound introduced here error[E0271]: type mismatch resolving `>::Response == Res` --> $DIR/track-obligations.rs:87:11 diff --git a/tests/ui/typeck/derive-sugg-arg-arity.stderr b/tests/ui/typeck/derive-sugg-arg-arity.stderr index 382b324c4cc50..477cec5bc1f3a 100644 --- a/tests/ui/typeck/derive-sugg-arg-arity.stderr +++ b/tests/ui/typeck/derive-sugg-arg-arity.stderr @@ -9,9 +9,9 @@ LL | _ => match A::partial_cmp() {}, | = note: the following trait bounds were not satisfied: `A: PartialOrd<_>` - which is required by `&A: PartialOrd<&_>` + which is required by `&A: PartialOrd<_>` `A: PartialOrd<_>` - which is required by `&mut A: PartialOrd<&mut _>` + which is required by `&mut A: PartialOrd<_>` `A: Iterator` which is required by `&mut A: Iterator` note: the trait `Iterator` must be implemented diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr index 0983147a5f0c5..5fee16b5e89f7 100644 --- a/tests/ui/typeck/issue-31173.stderr +++ b/tests/ui/typeck/issue-31173.stderr @@ -39,7 +39,7 @@ LL | | .collect(); = note: the following trait bounds were not satisfied: `, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_` which is required by `Cloned, {closure@$DIR/issue-31173.rs:7:21: 7:25}>>: Iterator` - `Cloned, {closure@$DIR/issue-31173.rs:7:21: 7:25}>>: Iterator` + `, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_` which is required by `&mut Cloned, {closure@$DIR/issue-31173.rs:7:21: 7:25}>>: Iterator` error: aborting due to 2 previous errors