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 rustc_trait_selection::traits::wf::object_region_bounds;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::slice;
|
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
|
// 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.
|
// could not be done at path creation, since we need to see through trait aliases.
|
||||||
let mut missing_type_params = vec![];
|
let mut missing_type_params = vec![];
|
||||||
|
let mut references_self = false;
|
||||||
let generics = tcx.generics_of(trait_ref.def_id);
|
let generics = tcx.generics_of(trait_ref.def_id);
|
||||||
let substs: Vec<_> = trait_ref
|
let substs: Vec<_> = trait_ref
|
||||||
.substs
|
.substs
|
||||||
@ -1451,12 +1452,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
.skip(1) // Remove `Self` for `ExistentialPredicate`.
|
||||||
.map(|(index, arg)| {
|
.map(|(index, arg)| {
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
if let ty::GenericArgKind::Type(ty) = arg.unpack() {
|
||||||
&& ty == dummy_self
|
debug!(?ty);
|
||||||
{
|
if ty == dummy_self {
|
||||||
let param = &generics.params[index];
|
let param = &generics.params[index];
|
||||||
missing_type_params.push(param.name);
|
missing_type_params.push(param.name);
|
||||||
tcx.ty_error().into()
|
tcx.ty_error().into()
|
||||||
|
} else if ty.walk().any(|arg| arg == dummy_self.into()) {
|
||||||
|
references_self = true;
|
||||||
|
tcx.ty_error().into()
|
||||||
|
} else {
|
||||||
|
arg
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
arg
|
arg
|
||||||
}
|
}
|
||||||
@ -1476,6 +1483,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
empty_generic_args,
|
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 }
|
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