Skip to content

Commit

Permalink
Don't store spans in assumed_wf_types actually
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 8, 2023
1 parent 0bddce5 commit e77e8eb
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 63 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Ty<'tcx>> {
desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
67 changes: 10 additions & 57 deletions compiler/rustc_ty_utils/src/implied_bounds.rs
Original file line number Diff line number Diff line change
@@ -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<Ty<'_>> {
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
Expand Down Expand Up @@ -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(),
}
}
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-35570.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ trait Trait2<'a> {

fn _ice(param: Box<dyn for <'a> 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)};
}

Expand Down
12 changes: 11 additions & 1 deletion src/test/ui/issues/issue-35570.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
LL | fn _ice(param: Box<dyn for <'a> 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<dyn for <'a> 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`.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ trait Trait2<'a, 'b> {
// do not infer that.
fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::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
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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< <T as Trait2<'y, 'z>>::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< <T as Trait2<'y, 'z>>::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< <T as Trait2<'y, 'z>>::Foo >)
| ++++++++++++++++++++++++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.

0 comments on commit e77e8eb

Please sign in to comment.