diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index b69728c24aa51..c61ed66a5e42b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1803,8 +1803,7 @@ pub fn check_type_bounds<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); - let assumed_wf_types = - ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty.def_id.expect_local()); + let assumed_wf_types = ocx.assumed_wf_types(impl_ty.def_id.expect_local()); let normalize_cause = ObligationCause::new( impl_ty_span, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 94d333c336ef3..dacb150ae823b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -97,7 +97,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( let infcx = &tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(infcx); - let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id); + let assumed_wf_types = ocx.assumed_wf_types(body_def_id); let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env }; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index fd8e8ed7ba605..713677db43c34 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -167,8 +167,7 @@ fn get_impl_substs<'tcx>( let param_env = tcx.param_env(impl1_def_id); let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id); - let assumed_wf_types = - ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id); + let assumed_wf_types = ocx.assumed_wf_types(impl1_def_id); let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id()); let impl2_substs = diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ab512804330b9..eea5d8fe63754 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -800,10 +800,9 @@ rustc_queries! { } /// Returns the types assumed to be well formed while "inside" of the given item. - /// - /// Note that we've liberated the late bound regions of function signatures, so - /// this can not be used to check whether these types are well formed. - query assumed_wf_types(key: DefId) -> &'tcx ty::List> { + query assumed_wf_types( + key: DefId + ) -> ty::EarlyBinder>>> { desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a04b15f8cf13c..99f3fe556516d 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -705,6 +705,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; self.0.fold_with(&mut folder) } + + pub fn subst_identity(self) -> T { + self.0 + } } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 7c569621cfeb8..626fb7f1af08f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -389,7 +389,7 @@ fn resolve_negative_obligation<'tcx>( }; let ocx = ObligationCtxt::new(&infcx); - let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id); + let wf_tys = ocx.assumed_wf_types(body_def_id); let outlives_env = OutlivesEnvironment::with_bounds( param_env, Some(&infcx), diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index c028e89e4ea29..2fd8ce8518a80 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -20,7 +20,6 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::Span; pub trait TraitEngineExt<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> Box; @@ -179,34 +178,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.engine.borrow_mut().select_all_or_error(self.infcx) } - pub fn assumed_wf_types( - &self, - param_env: ty::ParamEnv<'tcx>, - span: Span, - def_id: LocalDefId, - ) -> FxIndexSet> { + pub fn assumed_wf_types(&self, def_id: LocalDefId) -> FxIndexSet> { let tcx = self.infcx.tcx; - let assumed_wf_types = tcx.assumed_wf_types(def_id); - let mut implied_bounds = FxIndexSet::default(); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let cause = ObligationCause::misc(span, hir_id); - for ty in assumed_wf_types { - // FIXME(@lcnr): rustc currently does not check wf for types - // pre-normalization, meaning that implied bounds are sometimes - // incorrect. See #100910 for more details. - // - // Not adding the unnormalized types here mostly fixes that, except - // that there are projections which are still ambiguous in the item definition - // but do normalize successfully when using the item, see #98543. - // - // Anyways, I will hopefully soon change implied bounds to make all of this - // sound and then uncomment this line again. - - // implied_bounds.insert(ty); - let normalized = self.normalize(&cause, param_env, ty); - implied_bounds.insert(normalized); - } - implied_bounds + let def_id = def_id.to_def_id(); + let assumed_wf_types = tcx.assumed_wf_types(def_id).subst_identity(); + tcx.liberate_late_bound_regions(def_id, assumed_wf_types).into_iter().collect() } pub fn make_canonicalized_query_response( diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index f0d8c240ea588..e7b4246980d4f 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,34 +1,45 @@ use crate::rustc_middle::ty::DefIdTree; use rustc_hir::{def::DefKind, def_id::DefId}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::traits::query::NoSolution; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List> { +fn assumed_wf_types<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> ty::EarlyBinder>>> { match tcx.def_kind(def_id) { - DefKind::Fn => { - let sig = tcx.fn_sig(def_id); - let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - liberated_sig.inputs_and_output - } + DefKind::Fn => ty::EarlyBinder(from_fn_sig(tcx, def_id)), DefKind::AssocFn => { - let sig = tcx.fn_sig(def_id); - let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - let mut assumed_wf_types: Vec<_> = - tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); - assumed_wf_types.extend(liberated_sig.inputs_and_output); - tcx.intern_type_list(&assumed_wf_types) + let from_sig = from_fn_sig(tcx, def_id); + let from_impl = tcx.assumed_wf_types(tcx.parent(def_id)).subst_identity(); + + let assumed_wf_types = from_impl.no_bound_vars().unwrap().into_iter(); + let assumed_wf_types = assumed_wf_types.chain(from_sig.skip_binder()); + ty::EarlyBinder(from_sig.rebind(tcx.mk_type_list(assumed_wf_types))) + } + DefKind::Impl => { + let unnormalized = match tcx.impl_trait_ref(def_id) { + Some(trait_ref) => tcx.mk_type_list(trait_ref.substs.types()), + // Only the impl self type + None => tcx.intern_type_list(&[tcx.type_of(def_id)]), + }; + + // FIXME(@lcnr): rustc currently does not check wf for types + // pre-normalization, meaning that implied bounds from unnormalized types + // are sometimes incorrect. See #100910 for more details. + // + // Not adding the unnormalized types here mostly fixes that, except + // that there are projections which are still ambiguous in the item definition + // but do normalize successfully when using the item, see #98543. + let normalized = + normalize_ignoring_obligations(tcx, tcx.param_env(def_id), unnormalized) + .unwrap_or_else(|_| ty::List::empty()); + ty::EarlyBinder(ty::Binder::dummy(normalized)) } - DefKind::Impl => match tcx.impl_trait_ref(def_id) { - Some(trait_ref) => { - let types: Vec<_> = trait_ref.substs.types().collect(); - tcx.intern_type_list(&types) - } - // Only the impl self type - None => tcx.intern_type_list(&[tcx.type_of(def_id)]), - }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), DefKind::Mod | DefKind::Struct @@ -56,6 +67,38 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List ty::List::empty(), + | DefKind::Generator => ty::EarlyBinder(ty::Binder::dummy(ty::List::empty())), } } + +fn from_fn_sig<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> ty::Binder<'tcx, &'tcx ty::List>> { + // FIXME(#84533): We probably shouldn't use output types in implied bounds. + // This would reject this fn `fn f<'a, 'b>() -> &'a &'b () { .. }`. + let unnormalized = tcx.fn_sig(def_id).map_bound(|sig| sig.inputs_and_output); + let normalized = normalize_ignoring_obligations(tcx, tcx.param_env(def_id), unnormalized) + .unwrap_or_else(|_| ty::Binder::dummy(ty::List::empty())); + + // FIXME(#105948): Use unnormalized types for implied bounds as well. + normalized +} + +fn normalize_ignoring_obligations<'tcx, T: TypeFoldable<'tcx>>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: T, +) -> Result { + use rustc_infer::infer::TyCtxtInferExt as _; + use rustc_infer::traits::ObligationCause; + use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt as _; + + let infcx = tcx.infer_ctxt().build(); + let normalized = infcx + .at(&ObligationCause::dummy(), param_env) + .query_normalize(value) + .map(|normalized| infcx.resolve_vars_if_possible(normalized.value))?; + assert!(!normalized.needs_infer()); + Ok(normalized) +} diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr index 389cc7beddd83..6552c8be78089 100644 --- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr +++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-for-unimpl-trait.rs:10:5 + --> $DIR/associated-types-for-unimpl-trait.rs:10:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr index 1feaa612ee688..b2ee1b5e6d045 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: Get` is not satisfied - --> $DIR/associated-types-no-suitable-bound.rs:11:5 + --> $DIR/associated-types-no-suitable-bound.rs:11:21 | LL | fn uhoh(foo: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr index cc3ed556115bc..2e40dbd065d3e 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5 + --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr index 18f2830d8b215..bd3ee2abd2c76 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `(T, U): Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:22:5 + --> $DIR/associated-types-no-suitable-supertrait.rs:22:40 | LL | fn uhoh(&self, foo: U, bar: <(T, U) as Get>::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:17:5 + --> $DIR/associated-types-no-suitable-supertrait.rs:17:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr index 66d59bccdbb68..2e67c21940fc7 100644 --- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5 + --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40 | LL | fn okay(&self, foo: U, bar: ::Value); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr index 62cf1f37a7713..dd5ec7175b5f1 100644 --- a/src/test/ui/associated-types/issue-59324.stderr +++ b/src/test/ui/associated-types/issue-59324.stderr @@ -45,20 +45,16 @@ LL | pub trait ThriftService: | +++++ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:23:1 + --> $DIR/issue-59324.rs:23:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:16:5 + --> $DIR/issue-59324.rs:16:8 | -LL | / fn get_service( -LL | | -LL | | -LL | | &self, -LL | | ) -> Self::AssocType; - | |_________________________^ the trait `Foo` is not implemented for `Bug` +LL | fn get_service( + | ^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` | help: consider further restricting this bound | diff --git a/src/test/ui/const-generics/generic_const_exprs/closures.stderr b/src/test/ui/const-generics/generic_const_exprs/closures.stderr index a7d891d77908c..9c585d1d35168 100644 --- a/src/test/ui/const-generics/generic_const_exprs/closures.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/closures.stderr @@ -15,11 +15,11 @@ note: ...which requires type-checking `test::{constant#0}`... LL | fn test() -> [u8; N + (|| 42)()] {} | ^^^^^^^^^^^^^ = note: ...which again requires building an abstract representation for `test::{constant#0}`, completing the cycle -note: cycle used when checking that `test` is well-formed - --> $DIR/closures.rs:3:1 +note: cycle used when building MIR for `test::{constant#0}` + --> $DIR/closures.rs:3:35 | LL | fn test() -> [u8; N + (|| 42)()] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr index 5ebb4c3999c36..68244019fec14 100644 --- a/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr @@ -1,17 +1,17 @@ error: overly complex generic constant - --> $DIR/let-bindings.rs:6:68 + --> $DIR/let-bindings.rs:6:35 | LL | fn test() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default { - | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant + | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant | = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future error: overly complex generic constant - --> $DIR/let-bindings.rs:6:35 + --> $DIR/let-bindings.rs:6:68 | LL | fn test() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default { - | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant + | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant | = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future diff --git a/src/test/ui/const-generics/issues/issue-77357.rs b/src/test/ui/const-generics/issues/issue-77357.rs index 3cb8d3846ab7c..b8d0a32b15684 100644 --- a/src/test/ui/const-generics/issues/issue-77357.rs +++ b/src/test/ui/const-generics/issues/issue-77357.rs @@ -5,6 +5,7 @@ trait MyTrait {} fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { //~^ ERROR overly complex generic constant + //~| ERROR cycle detected when evaluating type-level constant todo!() } diff --git a/src/test/ui/const-generics/issues/issue-77357.stderr b/src/test/ui/const-generics/issues/issue-77357.stderr index 804c0ae5175a8..51e40c3870576 100644 --- a/src/test/ui/const-generics/issues/issue-77357.stderr +++ b/src/test/ui/const-generics/issues/issue-77357.stderr @@ -7,5 +7,45 @@ LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future -error: aborting due to previous error +error[E0391]: cycle detected when evaluating type-level constant + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `bug::{constant#0}`... + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `bug::{constant#0}`... + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires caching mir of `bug::{constant#0}` for CTFE... + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires elaborating drops for `bug::{constant#0}`... + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires borrow-checking `bug::{constant#0}`... + --> $DIR/issue-77357.rs:6:46 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `Binder(ConstEvaluatable(Const { ty: usize, kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_77357[fee6]::bug::{constant#0}), const_param_did: None }, substs: [T] }) }), [])`... + = note: ...which again requires evaluating type-level constant, completing the cycle +note: cycle used when computing the implied bounds of `bug` + --> $DIR/issue-77357.rs:6:1 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr index 22c3470b61ede..bd18d46223e69 100644 --- a/src/test/ui/issues/issue-18611.stderr +++ b/src/test/ui/issues/issue-18611.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied - --> $DIR/issue-18611.rs:1:1 + --> $DIR/issue-18611.rs:1:18 | -LL | / fn add_state(op: ::State) { -LL | | -LL | | } - | |_^ the trait `HasState` is not implemented for `isize` +LL | fn add_state(op: ::State) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index ef62dece83640..57f9575bdbd29 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -1,14 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:8 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | // -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime defined here... --> $DIR/issue-20831-debruijn.rs:28:58 @@ -21,16 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:8 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | // -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^ = note: expected ` as Publisher<'_>>` found ` as Publisher<'_>>` diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs index a2b0222d4f395..42bdb423f8f5c 100644 --- a/src/test/ui/issues/issue-35570.rs +++ b/src/test/ui/issues/issue-35570.rs @@ -7,7 +7,6 @@ trait Trait2<'a> { fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied - //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied let _e: (usize, usize) = unsafe{mem::transmute(param)}; } diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr index ebc40f6786fd0..2697d46bdb2f4 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -1,19 +1,9 @@ -error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:1 - | -LL | / fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { -LL | | -LL | | -LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)}; -LL | | } - | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()` - error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied --> $DIR/issue-35570.rs:8:40 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 6abe53127c3fb..6da3d5d96925d 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -1,8 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements - --> $DIR/normalization-bounds-error.rs:12:1 + --> $DIR/normalization-bounds-error.rs:12:4 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'d` as defined here... --> $DIR/normalization-bounds-error.rs:12:14 @@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ note: ...so that the types are compatible - --> $DIR/normalization-bounds-error.rs:12:1 + --> $DIR/normalization-bounds-error.rs:12:4 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ = note: expected `Visitor<'d>` found `Visitor<'_>` diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs index 1106352037a08..429548f119b14 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs @@ -20,7 +20,6 @@ trait Trait2<'a, 'b> { // do not infer that. fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied { } diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index 66f592c34dd07..6844e86653299 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -1,18 +1,3 @@ -error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1 - | -LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) -LL | | -LL | | -LL | | { -LL | | } - | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ++++++++++++++++++++++++ - error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49 | @@ -24,6 +9,6 @@ help: consider restricting type parameter `T` LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) | ++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr index fd34a59d2bd6d..34da1dd12df6f 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.stderr +++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr @@ -1,12 +1,8 @@ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:1 + --> $DIR/issue-79224.rs:18:17 | -LL | / impl Display for Cow<'_, B> { -LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | write!(f, "foo") -LL | | } -LL | | } - | |_^ the trait `Clone` is not implemented for `B` +LL | impl Display for Cow<'_, B> { + | ^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound @@ -15,12 +11,10 @@ LL | impl Display for Cow<'_, B> { | +++++++++++++++++++ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:19:5 + --> $DIR/issue-79224.rs:19:12 | -LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | write!(f, "foo") -LL | | } - | |_____^ the trait `Clone` is not implemented for `B` +LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + | ^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound diff --git a/src/test/ui/traits/issue-91594.stderr b/src/test/ui/traits/issue-91594.stderr index 5fcd090a8349f..9f9acf851135f 100644 --- a/src/test/ui/traits/issue-91594.stderr +++ b/src/test/ui/traits/issue-91594.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied - --> $DIR/issue-91594.rs:10:1 + --> $DIR/issue-91594.rs:10:6 | LL | impl HasComponent<>::Interface> for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` | = help: the trait `HasComponent<>::Interface>` is implemented for `Foo` note: required for `Foo` to implement `Component` diff --git a/src/test/ui/wf/issue-103573.stderr b/src/test/ui/wf/issue-103573.stderr index fcf3f15e4d3f6..5227badb77dde 100644 --- a/src/test/ui/wf/issue-103573.stderr +++ b/src/test/ui/wf/issue-103573.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `<>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied - --> $DIR/issue-103573.rs:18:5 + --> $DIR/issue-103573.rs:18:18 | LL | fn g<'a>(_: &< as TraitB>::TypeB as TraitA>::TypeA); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` | help: consider further restricting the associated type | diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr index 78312a0910594..b03023b5fd14f 100644 --- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/wf-foreign-fn-decl-ret.rs:11:5 + --> $DIR/wf-foreign-fn-decl-ret.rs:11:25 | LL | pub fn lint_me() -> <() as Foo>::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied --> $DIR/wf-foreign-fn-decl-ret.rs:14:32