Ban indirect references to Self
too.
This commit is contained in:
parent
e1e25a845c
commit
0df84ae67c
@ -43,7 +43,7 @@ use rustc_trait_selection::traits::error_reporting::{
|
||||
};
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::collections::BTreeSet;
|
||||
use std::slice;
|
||||
|
||||
@ -1444,6 +1444,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// Verify that `dummy_self` did not leak inside default type parameters. This
|
||||
// could not be done at path creation, since we need to see through trait aliases.
|
||||
let mut missing_type_params = vec![];
|
||||
let mut references_self = false;
|
||||
let generics = tcx.generics_of(trait_ref.def_id);
|
||||
let substs: Vec<_> = trait_ref
|
||||
.substs
|
||||
@ -1451,12 +1452,18 @@ 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()
|
||||
&& ty == dummy_self
|
||||
{
|
||||
let param = &generics.params[index];
|
||||
missing_type_params.push(param.name);
|
||||
tcx.ty_error().into()
|
||||
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
|
||||
}
|
||||
@ -1476,6 +1483,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
empty_generic_args,
|
||||
);
|
||||
|
||||
if references_self {
|
||||
let def_id = i.bottom().0.def_id();
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
i.bottom().1,
|
||||
E0038,
|
||||
"the {} `{}` cannot be made into an object",
|
||||
tcx.def_kind(def_id).descr(def_id),
|
||||
tcx.item_name(def_id),
|
||||
);
|
||||
err.note(
|
||||
rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![])
|
||||
.error_msg(),
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs }
|
||||
})
|
||||
});
|
||||
|
8
src/test/ui/traits/alias/self-in-generics.rs
Normal file
8
src/test/ui/traits/alias/self-in-generics.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(trait_alias)]
|
||||
|
||||
pub trait SelfInput = Fn(&mut Self);
|
||||
|
||||
pub fn f(_f: &dyn SelfInput) {}
|
||||
//~^ ERROR the trait alias `SelfInput` cannot be made into an object [E0038]
|
||||
|
||||
fn main() {}
|
11
src/test/ui/traits/alias/self-in-generics.stderr
Normal file
11
src/test/ui/traits/alias/self-in-generics.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0038]: the trait alias `SelfInput` cannot be made into an object
|
||||
--> $DIR/self-in-generics.rs:5:19
|
||||
|
|
||||
LL | pub fn f(_f: &dyn SelfInput) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= 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`.
|
Loading…
x
Reference in New Issue
Block a user