From e77e8eb9455264b70eb4344a404243b7c012db08 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 19:02:58 +0000 Subject: [PATCH] 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 7f794a926c06..37db2274f678 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 72ed3aa499da..bc6d9d4b922d 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 e3f34373ccc9..b7a24a22c53e 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 42bdb423f8f5..a2b0222d4f39 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 2697d46bdb2f..3dc33729d8fd 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 429548f119b1..1106352037a0 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 6844e8665329..3fd39810d445 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`.