Rollup merge of #100500 - cjgillot:verify-self-predicate, r=lcnr
Ban references to `Self` in trait object substs for projection predicates too. Fixes https://github.com/rust-lang/rust/issues/100484 Fixes https://github.com/rust-lang/rust/issues/100485 r? ````@lcnr````
This commit is contained in:
commit
33a40297d3
@ -35,7 +35,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::astconv_object_safety_violations;
|
||||
@ -1453,21 +1453,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.enumerate()
|
||||
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
||||
.map(|(index, arg)| {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack() {
|
||||
debug!(?ty);
|
||||
if ty == dummy_self {
|
||||
let param = &generics.params[index];
|
||||
missing_type_params.push(param.name);
|
||||
tcx.ty_error().into()
|
||||
} else if ty.walk().any(|arg| arg == dummy_self.into()) {
|
||||
references_self = true;
|
||||
tcx.ty_error().into()
|
||||
} else {
|
||||
arg
|
||||
}
|
||||
} else {
|
||||
arg
|
||||
if arg == dummy_self.into() {
|
||||
let param = &generics.params[index];
|
||||
missing_type_params.push(param.name);
|
||||
return tcx.ty_error().into();
|
||||
} else if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||
references_self = true;
|
||||
return tcx.ty_error().into();
|
||||
}
|
||||
arg
|
||||
})
|
||||
.collect();
|
||||
let substs = tcx.intern_substs(&substs[..]);
|
||||
@ -1506,13 +1500,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
});
|
||||
|
||||
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
|
||||
bound.map_bound(|b| {
|
||||
if b.projection_ty.self_ty() != dummy_self {
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!("trait_ref_to_existential called on {:?} with non-dummy Self", b),
|
||||
);
|
||||
bound.map_bound(|mut b| {
|
||||
assert_eq!(b.projection_ty.self_ty(), dummy_self);
|
||||
|
||||
// Like for trait refs, verify that `dummy_self` did not leak inside default type
|
||||
// parameters.
|
||||
let references_self = b.projection_ty.substs.iter().skip(1).any(|arg| {
|
||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
if references_self {
|
||||
tcx.sess
|
||||
.delay_span_bug(span, "trait object projection bounds reference `Self`");
|
||||
let substs: Vec<_> = b
|
||||
.projection_ty
|
||||
.substs
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||
return tcx.ty_error().into();
|
||||
}
|
||||
arg
|
||||
})
|
||||
.collect();
|
||||
b.projection_ty.substs = tcx.intern_substs(&substs[..]);
|
||||
}
|
||||
|
||||
ty::ExistentialProjection::erase_self_ty(tcx, b)
|
||||
})
|
||||
});
|
||||
|
12
src/test/ui/traits/alias/self-in-const-generics.rs
Normal file
12
src/test/ui/traits/alias/self-in-const-generics.rs
Normal file
@ -0,0 +1,12 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Bar<const N: usize> {}
|
||||
|
||||
trait BB = Bar<{ 2 + 1 }>;
|
||||
|
||||
fn foo(x: &dyn BB) {}
|
||||
//~^ ERROR the trait alias `BB` cannot be made into an object [E0038]
|
||||
|
||||
fn main() {}
|
11
src/test/ui/traits/alias/self-in-const-generics.stderr
Normal file
11
src/test/ui/traits/alias/self-in-const-generics.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0038]: the trait alias `BB` cannot be made into an object
|
||||
--> $DIR/self-in-const-generics.rs:9:16
|
||||
|
|
||||
LL | fn foo(x: &dyn BB) {}
|
||||
| ^^
|
||||
|
|
||||
= note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
@ -1,3 +1,10 @@
|
||||
// astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
|
||||
// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
|
||||
// Using `save-analysis` triggers type-checking `f` that would be normally skipped
|
||||
// as `type_of` emitted an error.
|
||||
//
|
||||
// compile-flags: -Zsave-analysis
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
pub trait SelfInput = Fn(&mut Self);
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0038]: the trait alias `SelfInput` cannot be made into an object
|
||||
--> $DIR/self-in-generics.rs:5:19
|
||||
--> $DIR/self-in-generics.rs:12:19
|
||||
|
|
||||
LL | pub fn f(_f: &dyn SelfInput) {}
|
||||
| ^^^^^^^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user