let tcx = self.tcx();
- // It is illegal to create a trait object with methods which includes
- // the Self type. An error will be reported when we coerce to a trait
- // object if the method refers to the `Self` type. Substituting ty_err
- // here allows compiler to soldier on.
- //
- // `confirm_candidate()` also relies upon this substitution
- // for Self. (fix)
- let rcvr_substs = substs.with_self_ty(ty::mk_err());
+ // It is illegal to invoke a method on a trait instance that refers to
+ // the `Self` type. Here, we use a substitution that replaces `Self`
+ // with the object type itself. Hence, a `&self` method will wind up
+ // with an argument type like `&Trait`.
+ let rcvr_substs = substs.with_self_ty(self_ty);
let trait_ref = Rc::new(TraitRef {
def_id: did,
self.ty_to_string(rcvr_ty),
candidate.repr(self.tcx()));
+ let rcvr_substs = candidate.rcvr_substs.clone();
self.enforce_drop_trait_limitations(candidate);
// Determine the values for the generic parameters of the method.
self.register_unsize_obligations(span, &**u)
}
ty::UnsizeVtable(ref ty_trait, self_ty) => {
- vtable2::check_object_safety(self.tcx(), ty_trait, span);
+ vtable::check_object_safety(self.tcx(), ty_trait, span);
// If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` implements `Foo`:
vtable::register_object_cast_obligations(self,
*/
let mut msgs = Vec::new();
- let method_name = method.ident.repr(tcx);
+ let method_name = method.name.repr(tcx);
match method.explicit_self {
ty::ByValueExplicitSelfCategory => { // reason (a) above
}
};
let ref sig = method.fty.sig;
- for &input_ty in sig.inputs.tail().iter().chain([sig.output].iter()) {
+ for &input_ty in sig.inputs[1..].iter() {
match check_for_self_ty(input_ty) {
Some(msg) => msgs.push(msg),
_ => {}
}
}
+ if let ty::FnConverging(result_type) = sig.output {
+ match check_for_self_ty(result_type) {
+ Some(msg) => msgs.push(msg),
+ _ => {}
+ }
+ }
if method.generics.has_type_params(FnSpace) {
// reason (b) above
// Test that attempts to implicitly coerce a value into an
// object respect the lifetime bound on the object type.
-fn a(v: &[u8]) -> Box<Clone + 'static> {
- let x: Box<Clone + 'static> = box v; //~ ERROR does not outlive
+trait Foo {}
+impl<'a> Foo for &'a [u8] {}
+
+fn a(v: &[u8]) -> Box<Foo + 'static> {
+ let x: Box<Foo + 'static> = box v; //~ ERROR does not outlive
x
}
-fn b(v: &[u8]) -> Box<Clone + 'static> {
+fn b(v: &[u8]) -> Box<Foo + 'static> {
box v //~ ERROR does not outlive
}
-fn c(v: &[u8]) -> Box<Clone> {
+fn c(v: &[u8]) -> Box<Foo> {
box v // OK thanks to lifetime elision
}
-fn d<'a,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
box v //~ ERROR does not outlive
}
-fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Foo+'b> {
box v // OK, thanks to 'a:'b
}