From ca554efaf78962f9dc9599663b29626269c69c8c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 02:40:59 +0000 Subject: [PATCH 1/3] Improve spans of non-WF implied bound types --- .../rustc_hir_analysis/src/check/wfcheck.rs | 58 ++++++---------- compiler/rustc_middle/src/query/mod.rs | 2 +- .../src/traits/engine.rs | 6 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 67 ++++++++++++++++--- .../associated-types-for-unimpl-trait.stderr | 4 +- .../associated-types-no-suitable-bound.stderr | 4 +- ...ated-types-no-suitable-supertrait-2.stderr | 4 +- ...ciated-types-no-suitable-supertrait.stderr | 8 +-- ...ted-trait-in-method-without-default.stderr | 4 +- src/test/ui/associated-types/issue-59324.rs | 2 +- .../ui/associated-types/issue-59324.stderr | 17 ++--- src/test/ui/issues/issue-18611.stderr | 8 +-- .../ui/issues/issue-20831-debruijn.stderr | 24 ++----- src/test/ui/issues/issue-35570.rs | 1 - src/test/ui/issues/issue-35570.stderr | 16 +---- .../ui/nll/normalization-bounds-error.stderr | 8 +-- ...ions-implied-bounds-projection-gap-hr-1.rs | 1 - ...-implied-bounds-projection-gap-hr-1.stderr | 21 +----- .../min_specialization/issue-79224.rs | 6 +- .../min_specialization/issue-79224.stderr | 18 ++--- src/test/ui/wf/issue-103573.stderr | 4 +- src/test/ui/wf/wf-foreign-fn-decl-ret.stderr | 4 +- 22 files changed, 134 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1afe624240378..b663f90cab712 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1489,54 +1489,38 @@ fn check_fn_or_method<'tcx>( def_id: LocalDefId, ) { let tcx = wfcx.tcx(); - let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); + let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); // Normalize the input and output types one at a time, using a different // `WellFormedLoc` for each. We cannot call `normalize_associated_types` // on the entire `FnSig`, since this would use the same `WellFormedLoc` // for each type, preventing the HIR wf check from generating // a nice error message. - let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig; - inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| { - wfcx.normalize( - span, - Some(WellFormedLoc::Param { - function: def_id, - // Note that the `param_idx` of the output type is - // one greater than the index of the last input type. - param_idx: i.try_into().unwrap(), - }), - ty, - ) - })); - // Manually call `normalize_associated_types_in` on the other types - // in `FnSig`. This ensures that if the types of these fields - // ever change to include projections, we will start normalizing - // them automatically. - let sig = ty::FnSig { - inputs_and_output, - c_variadic: wfcx.normalize(span, None, c_variadic), - unsafety: wfcx.normalize(span, None, unsafety), - abi: wfcx.normalize(span, None, abi), - }; + let arg_span = + |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span); + + sig.inputs_and_output = + tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| { + wfcx.normalize( + arg_span(idx), + Some(WellFormedLoc::Param { + function: def_id, + // Note that the `param_idx` of the output type is + // one greater than the index of the last input type. + param_idx: idx.try_into().unwrap(), + }), + ty, + ) + })); - for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() { + for (idx, ty) in sig.inputs_and_output.iter().enumerate() { wfcx.register_wf_obligation( - ty.span, - Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }), - input_ty.into(), + arg_span(idx), + Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }), + ty.into(), ); } - wfcx.register_wf_obligation( - hir_decl.output.span(), - Some(WellFormedLoc::Param { - function: def_id, - param_idx: sig.inputs().len().try_into().unwrap(), - }), - sig.output().into(), - ); - check_where_clauses(wfcx, span, def_id); check_return_position_impl_trait_in_trait_bounds( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 37db2274f678f..7f794a926c060 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -803,7 +803,7 @@ rustc_queries! { /// /// 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) -> &'tcx [(Ty<'tcx>, Span)] { desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index bc6d9d4b922d8..72ed3aa499daf 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -191,8 +191,8 @@ impl<'a, 'tcx> ObligationCtxt<'a, '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 { + for &(ty, ty_span) in assumed_wf_types { + let span = if ty_span.is_dummy() { span } else { ty_span }; // FIXME(@lcnr): rustc currently does not check wf for types // pre-normalization, meaning that implied bounds are sometimes // incorrect. See #100910 for more details. @@ -205,7 +205,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // sound and then uncomment this line again. // implied_bounds.insert(ty); - let normalized = self.normalize(&cause, param_env, ty); + let normalized = self.normalize(&ObligationCause::misc(span, hir_id), param_env, ty); implied_bounds.insert(normalized); } implied_bounds diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index b7a24a22c53e3..e3f34373ccc94 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,33 +1,80 @@ use crate::rustc_middle::ty::DefIdTree; -use rustc_hir::{def::DefKind, def_id::DefId}; +use rustc_hir::{self as hir, def::DefKind, def_id::DefId}; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::{Span, DUMMY_SP}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { 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 + if let Some(node) = tcx.hir().get_if_local(def_id) + && let Some(decl) = node.fn_decl() + { + assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); + tcx.arena.alloc_from_iter(std::iter::zip( + liberated_sig.inputs_and_output, + decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), + )) + } else { + tcx.arena.alloc_from_iter( + liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), + ) + } } 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 assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id)); + if let Some(node) = tcx.hir().get_if_local(def_id) + && let Some(decl) = node.fn_decl() + { + assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); + tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip( + liberated_sig.inputs_and_output, + decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), + ))) + } else { + tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain( + liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), + )) + } } 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) + let self_span = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(impl_), + .. + })) = tcx.hir().get_if_local(def_id) + { + impl_.self_ty.span + } else { + DUMMY_SP + }; + tcx.arena.alloc_from_iter(std::iter::zip( + types, + // FIXME: reliable way of getting trait ref substs... + [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)), + )) } // Only the impl self type - None => tcx.intern_type_list(&[tcx.type_of(def_id)]), + None => { + let span = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(impl_), + .. + })) = tcx.hir().get_if_local(def_id) + { + impl_.self_ty.span + } else { + DUMMY_SP + }; + tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)]) + } }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), DefKind::Mod @@ -56,6 +103,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Generator => ty::List::empty(), + | DefKind::Generator => &[], } } 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.rs b/src/test/ui/associated-types/issue-59324.rs index 9e68e9e77515b..551f13ee178da 100644 --- a/src/test/ui/associated-types/issue-59324.rs +++ b/src/test/ui/associated-types/issue-59324.rs @@ -15,9 +15,9 @@ pub trait ThriftService: { fn get_service( //~^ ERROR the trait bound `Bug: Foo` is not satisfied - //~| ERROR the trait bound `Bug: Foo` is not satisfied &self, ) -> Self::AssocType; + //~^ ERROR the trait bound `Bug: Foo` is not satisfied } fn with_factory(factory: dyn ThriftService<()>) {} diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr index 62cf1f37a7713..a84b599b52b68 100644 --- a/src/test/ui/associated-types/issue-59324.stderr +++ b/src/test/ui/associated-types/issue-59324.stderr @@ -20,7 +20,7 @@ LL | | LL | | LL | | Service::OnlyFoo> ... | -LL | | ) -> Self::AssocType; +LL | | LL | | } | |_^ the trait `Foo` is not implemented for `Bug` | @@ -34,7 +34,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied | LL | / fn get_service( LL | | -LL | | LL | | &self, LL | | ) -> Self::AssocType; | |_________________________^ the trait `Foo` is not implemented for `Bug` @@ -45,20 +44,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:19:10 | -LL | / fn get_service( -LL | | -LL | | -LL | | &self, -LL | | ) -> Self::AssocType; - | |_________________________^ the trait `Foo` is not implemented for `Bug` +LL | ) -> Self::AssocType; + | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` | help: consider further restricting this bound | 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..c3af1f6786b34 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:33 | -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:33 | -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..b6c244241edd9 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 + --> $DIR/issue-35570.rs:8:16 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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..0fc3670d6c523 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:31 | 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:31 | 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..43b7b9c16b1cb 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,29 +1,14 @@ 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 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: 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.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs index 408732fe944fe..d02c108ae6bc2 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.rs +++ b/src/test/ui/specialization/min_specialization/issue-79224.rs @@ -15,8 +15,10 @@ impl ToString for Cow<'_, str> { } } -impl Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277] +impl Display for Cow<'_, B> { + //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] + //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "foo") } } diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr index fd34a59d2bd6d..d4d7daf41117b 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:29 | -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:18:29 | -LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | write!(f, "foo") -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 diff --git a/src/test/ui/wf/issue-103573.stderr b/src/test/ui/wf/issue-103573.stderr index fcf3f15e4d3f6..3b6ab3326121a 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:17 | 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 From 0bddce50903c463ff06cc05edc1b3aba6645f50f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 03:14:27 +0000 Subject: [PATCH 2/3] Normalize assumed_wf_types after wfchecking is complete, for better spans --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 7 ++++--- src/test/ui/issues/issue-35570.stderr | 4 ++-- .../regions-implied-bounds-projection-gap-hr-1.stderr | 4 ++-- .../specialization/min_specialization/issue-79224.rs | 2 +- .../min_specialization/issue-79224.stderr | 10 +++++----- src/test/ui/traits/issue-91594.stderr | 4 ++-- src/test/ui/wf/issue-103573.stderr | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b663f90cab712..969f7de51cebd 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -97,21 +97,22 @@ 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 mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env }; if !tcx.features().trivial_bounds { wfcx.check_false_global_bounds() } f(&mut wfcx); + + let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id); + let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types); + let errors = wfcx.select_all_or_error(); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None); return; } - let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types); let outlives_environment = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr index b6c244241edd9..2697d46bdb2f4 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:16 + --> $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 `()` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` error: aborting due to previous error 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 43b7b9c16b1cb..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,8 +1,8 @@ error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs index d02c108ae6bc2..104bddd076ec1 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.rs +++ b/src/test/ui/specialization/min_specialization/issue-79224.rs @@ -17,8 +17,8 @@ impl ToString for Cow<'_, str> { impl Display for Cow<'_, B> { //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] - //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] write!(f, "foo") } } diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr index d4d7daf41117b..be6f04ae62a0d 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.stderr +++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:29 + --> $DIR/issue-79224.rs:18:17 | LL | impl Display for Cow<'_, B> { - | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` + | ^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound @@ -11,10 +11,10 @@ LL | impl Display for Cow<'_, B> { | +++++++++++++++++++ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:29 + --> $DIR/issue-79224.rs:20:12 | -LL | impl Display for Cow<'_, B> { - | ^^^^^^^^^^ 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 3b6ab3326121a..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:17 + --> $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 | From e77e8eb9455264b70eb4344a404243b7c012db08 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 19:02:58 +0000 Subject: [PATCH 3/3] Don't store spans in assumed_wf_types actually --- compiler/rustc_middle/src/query/mod.rs | 2 +- .../src/traits/engine.rs | 6 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 67 +++---------------- src/test/ui/issues/issue-35570.rs | 1 + src/test/ui/issues/issue-35570.stderr | 12 +++- ...ions-implied-bounds-projection-gap-hr-1.rs | 1 + ...-implied-bounds-projection-gap-hr-1.stderr | 17 ++++- 7 files changed, 43 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7f794a926c060..37db2274f678f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -803,7 +803,7 @@ rustc_queries! { /// /// 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<'tcx>, Span)] { + query assumed_wf_types(key: DefId) -> &'tcx ty::List> { desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 72ed3aa499daf..bc6d9d4b922d8 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -191,8 +191,8 @@ impl<'a, 'tcx> ObligationCtxt<'a, '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); - for &(ty, ty_span) in assumed_wf_types { - let span = if ty_span.is_dummy() { span } else { ty_span }; + 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. @@ -205,7 +205,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // sound and then uncomment this line again. // implied_bounds.insert(ty); - let normalized = self.normalize(&ObligationCause::misc(span, hir_id), param_env, ty); + let normalized = self.normalize(&cause, param_env, ty); implied_bounds.insert(normalized); } implied_bounds diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index e3f34373ccc94..b7a24a22c53e3 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,80 +1,33 @@ use crate::rustc_middle::ty::DefIdTree; -use rustc_hir::{self as hir, def::DefKind, def_id::DefId}; +use rustc_hir::{def::DefKind, def_id::DefId}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::{Span, DUMMY_SP}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { 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); - if let Some(node) = tcx.hir().get_if_local(def_id) - && let Some(decl) = node.fn_decl() - { - assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); - tcx.arena.alloc_from_iter(std::iter::zip( - liberated_sig.inputs_and_output, - decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), - )) - } else { - tcx.arena.alloc_from_iter( - liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), - ) - } + liberated_sig.inputs_and_output } DefKind::AssocFn => { let sig = tcx.fn_sig(def_id); let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - let assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id)); - if let Some(node) = tcx.hir().get_if_local(def_id) - && let Some(decl) = node.fn_decl() - { - assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); - tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip( - liberated_sig.inputs_and_output, - decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), - ))) - } else { - tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain( - liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), - )) - } + 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) } DefKind::Impl => match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.substs.types().collect(); - let self_span = if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(impl_), - .. - })) = tcx.hir().get_if_local(def_id) - { - impl_.self_ty.span - } else { - DUMMY_SP - }; - tcx.arena.alloc_from_iter(std::iter::zip( - types, - // FIXME: reliable way of getting trait ref substs... - [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)), - )) + tcx.intern_type_list(&types) } // Only the impl self type - None => { - let span = if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(impl_), - .. - })) = tcx.hir().get_if_local(def_id) - { - impl_.self_ty.span - } else { - DUMMY_SP - }; - tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)]) - } + None => tcx.intern_type_list(&[tcx.type_of(def_id)]), }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), DefKind::Mod @@ -103,6 +56,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Generator => &[], + | DefKind::Generator => ty::List::empty(), } } diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs index 42bdb423f8f5c..a2b0222d4f395 100644 --- a/src/test/ui/issues/issue-35570.rs +++ b/src/test/ui/issues/issue-35570.rs @@ -7,6 +7,7 @@ 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 2697d46bdb2f4..3dc33729d8fdb 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -4,6 +4,16 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` -error: aborting due to previous error +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: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. 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 429548f119b14..1106352037a08 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,6 +20,7 @@ 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 6844e86653299..3fd39810d4453 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 @@ -9,6 +9,21 @@ 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 previous error +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: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.