Auto merge of #55032 - oli-obk:the_early_unwrap_gets_the_panic, r=Mark-Simulacrum

Check the invariant for `principal` inside the method

r? @Mark-Simulacrum
This commit is contained in:
bors 2018-10-14 18:06:20 +00:00
commit 14f42a732f
26 changed files with 146 additions and 188 deletions

View File

@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
match ty.sty { match ty.sty {
ty::Ref(..) => true, ty::Ref(..) => true,
ty::Adt(def, _) => def.is_fundamental(), ty::Adt(def, _) => def.is_fundamental(),
ty::Dynamic(ref data, ..) => { ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"),
data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
}
_ => false _ => false
} }
} }
@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
ty::Adt(def, _) => def_id_is_local(def.did, in_crate), ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
ty::Foreign(did) => def_id_is_local(did, in_crate), ty::Foreign(did) => def_id_is_local(did, in_crate),
ty::Dynamic(ref tt, ..) => { ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),
tt.principal().map_or(false, |p|
def_id_is_local(p.def_id(), in_crate)
)
}
ty::Error => true, ty::Error => true,

View File

@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
return; return;
} }
match data.principal() { data.principal().with_self_ty(this.tcx(), self_ty)
Some(p) => p.with_self_ty(this.tcx(), self_ty),
None => return,
}
} }
ty::Infer(ty::TyVar(_)) => { ty::Infer(ty::TyVar(_)) => {
debug!("assemble_candidates_from_object_ty: ambiguous"); debug!("assemble_candidates_from_object_ty: ambiguous");
@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// //
// We always upcast when we can because of reason // We always upcast when we can because of reason
// #2 (region bounds). // #2 (region bounds).
match (data_a.principal(), data_b.principal()) { data_a.principal().def_id() == data_b.principal().def_id()
(Some(a), Some(b)) => { && data_b.auto_traits()
a.def_id() == b.def_id() // All of a's auto traits need to be in b's auto traits.
&& data_b.auto_traits() .all(|b| data_a.auto_traits().any(|a| a == b))
// All of a's auto traits need to be in b's auto traits.
.all(|b| data_a.auto_traits().any(|a| a == b))
}
_ => false,
}
} }
// T -> Trait. // T -> Trait.
@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
.shallow_resolve(*obligation.self_ty().skip_binder()); .shallow_resolve(*obligation.self_ty().skip_binder());
let poly_trait_ref = match self_ty.sty { let poly_trait_ref = match self_ty.sty {
ty::Dynamic(ref data, ..) => { ty::Dynamic(ref data, ..) => {
data.principal().unwrap().with_self_ty(self.tcx(), self_ty) data.principal().with_self_ty(self.tcx(), self_ty)
} }
_ => span_bug!(obligation.cause.span, "object candidate with non-object"), _ => span_bug!(obligation.cause.span, "object candidate with non-object"),
}; };
@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
// See assemble_candidates_for_unsizing for more info. // See assemble_candidates_for_unsizing for more info.
let existential_predicates = data_a.map_bound(|data_a| { let existential_predicates = data_a.map_bound(|data_a| {
let principal = data_a.principal(); let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
let iter = principal
.into_iter()
.map(ty::ExistentialPredicate::Trait)
.chain( .chain(
data_a data_a
.projection_bounds() .projection_bounds()
@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// T -> Trait. // T -> Trait.
(_, &ty::Dynamic(ref data, r)) => { (_, &ty::Dynamic(ref data, r)) => {
let mut object_dids = data.auto_traits() let mut object_dids = data.auto_traits()
.chain(data.principal().map(|p| p.def_id())); .chain(iter::once(data.principal().def_id()));
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did)); return Err(TraitNotObjectSafe(did));
} }

View File

@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::FnDef(..) => "fn item".into(), ty::FnDef(..) => "fn item".into(),
ty::FnPtr(_) => "fn pointer".into(), ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(ref inner, ..) => { ty::Dynamic(ref inner, ..) => {
inner.principal().map_or_else(|| "trait".into(), format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into()
|p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
} }
ty::Closure(..) => "closure".into(), ty::Closure(..) => "closure".into(),
ty::Generator(..) => "generator".into(), ty::Generator(..) => "generator".into(),

View File

@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType), ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
ty::RawPtr(_) => Some(PtrSimplifiedType), ty::RawPtr(_) => Some(PtrSimplifiedType),
ty::Dynamic(ref trait_info, ..) => { ty::Dynamic(ref trait_info, ..) => {
trait_info.principal().map(|p| TraitSimplifiedType(p.def_id())) Some(TraitSimplifiedType(trait_info.principal().def_id()))
} }
ty::Ref(_, ty, _) => { ty::Ref(_, ty, _) => {
// since we introduce auto-refs during method lookup, we // since we introduce auto-refs during method lookup, we

View File

@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
match ty.sty { match ty.sty {
ty::Adt(adt_def, _) => Some(adt_def.did), ty::Adt(adt_def, _) => Some(adt_def.did),
ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()), ty::Dynamic(data, ..) => Some(data.principal().def_id()),
ty::Array(subty, _) | ty::Array(subty, _) |
ty::Slice(subty) => characteristic_def_id_of_type(subty), ty::Slice(subty) => characteristic_def_id_of_type(subty),

View File

@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {} impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
impl<'tcx> List<ExistentialPredicate<'tcx>> { impl<'tcx> List<ExistentialPredicate<'tcx>> {
pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> { pub fn principal(&self) -> ExistentialTraitRef<'tcx> {
match self.get(0) { match self[0] {
Some(&ExistentialPredicate::Trait(tr)) => Some(tr), ExistentialPredicate::Trait(tr) => tr,
_ => None, other => bug!("first predicate is {:?}", other),
} }
} }
@ -589,8 +589,8 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
} }
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> { impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> { pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> {
self.skip_binder().principal().map(Binder::bind) Binder::bind(self.skip_binder().principal())
} }
#[inline] #[inline]
@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
} }
Dynamic(ref obj, region) => { Dynamic(ref obj, region) => {
let mut v = vec![region]; let mut v = vec![region];
if let Some(p) = obj.principal() { v.extend(obj.principal().skip_binder().substs.regions());
v.extend(p.skip_binder().substs.regions());
}
v v
} }
Adt(_, substs) | Opaque(_, substs) => { Adt(_, substs) | Opaque(_, substs) => {

View File

@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
let cause = self.cause(traits::MiscObligation); let cause = self.cause(traits::MiscObligation);
let component_traits = let component_traits =
data.auto_traits().chain(data.principal().map(|p| p.def_id())); data.auto_traits().chain(once(data.principal().def_id()));
self.out.extend( self.out.extend(
component_traits.map(|did| traits::Obligation::new( component_traits.map(|did| traits::Obligation::new(
cause.clone(), cause.clone(),

View File

@ -621,16 +621,16 @@ define_print! {
// Use a type that can't appear in defaults of type parameters. // Use a type that can't appear in defaults of type parameters.
let dummy_self = tcx.mk_infer(ty::FreshTy(0)); let dummy_self = tcx.mk_infer(ty::FreshTy(0));
if let Some(p) = self.principal() { let principal = tcx
let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") .lift(&self.principal())
.with_self_ty(tcx, dummy_self); .expect("could not lift TraitRef for printing")
let projections = self.projection_bounds().map(|p| { .with_self_ty(tcx, dummy_self);
tcx.lift(&p) let projections = self.projection_bounds().map(|p| {
.expect("could not lift projection for printing") tcx.lift(&p)
.with_self_ty(tcx, dummy_self) .expect("could not lift projection for printing")
}).collect::<Vec<_>>(); .with_self_ty(tcx, dummy_self)
cx.parameterized(f, principal.substs, principal.def_id, &projections)?; }).collect::<Vec<_>>();
} cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
// Builtin bounds. // Builtin bounds.
for did in self.auto_traits() { for did in self.auto_traits() {

View File

@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
/// Cache instances of monomorphic and polymorphic items /// Cache instances of monomorphic and polymorphic items
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>, pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
/// Cache generated vtables /// Cache generated vtables
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), pub vtables: RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>),
&'a Value>>, &'a Value>>,
/// Cache of constant strings, /// Cache of constant strings,
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>, pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,

View File

@ -435,12 +435,7 @@ fn trait_pointer_metadata(
// But it does not describe the trait's methods. // But it does not describe the trait's methods.
let containing_scope = match trait_type.sty { let containing_scope = match trait_type.sty {
ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() { ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
let def_id = principal.def_id();
Some(get_namespace_for_item(cx, def_id))
} else {
NO_SCOPE_METADATA
},
_ => { _ => {
bug!("debuginfo: Unexpected trait-object type in \ bug!("debuginfo: Unexpected trait-object type in \
trait_pointer_metadata(): {:?}", trait_pointer_metadata(): {:?}",

View File

@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
} }
}, },
ty::Dynamic(ref trait_data, ..) => { ty::Dynamic(ref trait_data, ..) => {
if let Some(principal) = trait_data.principal() { let principal = cx.tcx.normalize_erasing_late_bound_regions(
let principal = cx.tcx.normalize_erasing_late_bound_regions( ty::ParamEnv::reveal_all(),
ty::ParamEnv::reveal_all(), &trait_data.principal(),
&principal, );
); push_item_name(cx, principal.def_id, false, output);
push_item_name(cx, principal.def_id, false, output); push_type_params(cx, principal.substs, output);
push_type_params(cx, principal.substs, output);
}
}, },
ty::FnDef(..) | ty::FnPtr(_) => { ty::FnDef(..) | ty::FnPtr(_) => {
let sig = t.fn_sig(cx.tcx); let sig = t.fn_sig(cx.tcx);

View File

@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex {
pub fn get_vtable( pub fn get_vtable(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> &'ll Value { ) -> &'ll Value {
let tcx = cx.tcx; let tcx = cx.tcx;
@ -86,23 +86,19 @@ pub fn get_vtable(
// Not in the cache. Build it. // Not in the cache. Build it.
let nullptr = C_null(Type::i8p(cx)); let nullptr = C_null(Type::i8p(cx));
let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
let methods = methods.iter().cloned().map(|opt_mth| {
opt_mth.map_or(nullptr, |(def_id, substs)| {
callee::resolve_and_get_fn(cx, def_id, substs)
})
});
let (size, align) = cx.size_and_align_of(ty); let (size, align) = cx.size_and_align_of(ty);
let mut components: Vec<_> = [ let components: Vec<_> = [
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
C_usize(cx, size.bytes()), C_usize(cx, size.bytes()),
C_usize(cx, align.abi()) C_usize(cx, align.abi())
].iter().cloned().collect(); ].iter().cloned().chain(methods).collect();
if let Some(trait_ref) = trait_ref {
let trait_ref = trait_ref.with_self_ty(tcx, ty);
let methods = tcx.vtable_methods(trait_ref);
let methods = methods.iter().cloned().map(|opt_mth| {
opt_mth.map_or(nullptr, |(def_id, substs)| {
callee::resolve_and_get_fn(cx, def_id, substs)
})
});
components.extend(methods);
}
let vtable_const = C_struct(cx, &components, false); let vtable_const = C_struct(cx, &components, false);
let align = cx.data_layout().pointer_align; let align = cx.data_layout().pointer_align;

View File

@ -327,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
} }
(_, &ty::Dynamic(ref data, _)) => { (_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait // Initial cast from sized to dyn trait
let trait_ref = data.principal().unwrap().with_self_ty( let trait_ref = data.principal().with_self_ty(
*self.tcx, *self.tcx,
src_pointee_ty, src_pointee_ty,
); );

View File

@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
!impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); !impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty { if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
if let Some(principal) = trait_ty.principal() { let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
let poly_trait_ref = principal.with_self_ty(tcx, impl_ty); assert!(!poly_trait_ref.has_escaping_regions());
assert!(!poly_trait_ref.has_escaping_regions());
// Walk all methods of the trait, including those of its supertraits // Walk all methods of the trait, including those of its supertraits
let methods = tcx.vtable_methods(poly_trait_ref); let methods = tcx.vtable_methods(poly_trait_ref);
let methods = methods.iter().cloned().filter_map(|method| method) let methods = methods.iter().cloned().filter_map(|method| method)
.map(|(def_id, substs)| ty::Instance::resolve( .map(|(def_id, substs)| ty::Instance::resolve(
tcx, tcx,
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
def_id, def_id,
substs).unwrap()) substs).unwrap())
.filter(|&instance| should_monomorphize_locally(tcx, &instance)) .filter(|&instance| should_monomorphize_locally(tcx, &instance))
.map(|instance| create_fn_mono_item(instance)); .map(|instance| create_fn_mono_item(instance));
output.extend(methods); output.extend(methods);
}
// Also add the destructor // Also add the destructor
visit_drop_use(tcx, impl_ty, false, output); visit_drop_use(tcx, impl_ty, false, output);
} }

View File

@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
output.push(']'); output.push(']');
}, },
ty::Dynamic(ref trait_data, ..) => { ty::Dynamic(ref trait_data, ..) => {
if let Some(principal) = trait_data.principal() { let principal = trait_data.principal();
self.push_def_path(principal.def_id(), output); self.push_def_path(principal.def_id(), output);
self.push_type_params(principal.skip_binder().substs, self.push_type_params(
trait_data.projection_bounds(), principal.skip_binder().substs,
output); trait_data.projection_bounds(),
} output,
);
}, },
ty::Foreign(did) => self.push_def_path(did, output), ty::Foreign(did) => self.push_def_path(did, output),
ty::FnDef(..) | ty::FnDef(..) |

View File

@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
let ty_def_id = match self.tcx.type_of(item_def_id).sty { let ty_def_id = match self.tcx.type_of(item_def_id).sty {
ty::Adt(adt, _) => adt.did, ty::Adt(adt, _) => adt.did,
ty::Foreign(did) => did, ty::Foreign(did) => did,
ty::Dynamic(ref obj, ..) if obj.principal().is_some() => ty::Dynamic(ref obj, ..) => obj.principal().def_id(),
obj.principal().unwrap().def_id(),
ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id, ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
_ => return Some(AccessLevel::Public) _ => return Some(AccessLevel::Public)
}; };
@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
let ty_def_id = match ty.sty { let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.did), ty::Adt(adt, _) => Some(adt.did),
ty::Foreign(did) => Some(did), ty::Foreign(did) => Some(did),
ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
ty::Projection(ref proj) => Some(proj.item_def_id), ty::Projection(ref proj) => Some(proj.item_def_id),
ty::FnDef(def_id, ..) | ty::FnDef(def_id, ..) |
ty::Closure(def_id, ..) | ty::Closure(def_id, ..) |
@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
let ty_def_id = match ty.sty { let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.did), ty::Adt(adt, _) => Some(adt.did),
ty::Foreign(did) => Some(did), ty::Foreign(did) => Some(did),
ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
ty::Projection(ref proj) => { ty::Projection(ref proj) => {
if self.required_visibility == ty::Visibility::Invisible { if self.required_visibility == ty::Visibility::Invisible {
// Conservatively approximate the whole type alias as public without // Conservatively approximate the whole type alias as public without

View File

@ -73,7 +73,7 @@ enum PointerKind<'tcx> {
/// No metadata attached, ie pointer to sized type or foreign type /// No metadata attached, ie pointer to sized type or foreign type
Thin, Thin,
/// A trait object /// A trait object
Vtable(Option<DefId>), Vtable(DefId),
/// Slice /// Slice
Length, Length,
/// The unsize info of this projection /// The unsize info of this projection
@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Ok(match t.sty { Ok(match t.sty {
ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Slice(_) | ty::Str => Some(PointerKind::Length),
ty::Dynamic(ref tty, ..) => ty::Dynamic(ref tty, ..) =>
Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))), Some(PointerKind::Vtable(tty.principal().def_id())),
ty::Adt(def, substs) if def.is_struct() => { ty::Adt(def, substs) if def.is_struct() => {
match def.non_enum_variant().fields.last() { match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin), None => Some(PointerKind::Thin),

View File

@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.deduce_sig_from_projection(None, &pb) self.deduce_sig_from_projection(None, &pb)
}) })
.next(); .next();
let kind = object_type let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id());
.principal()
.and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
(sig, kind) (sig, kind)
} }
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),

View File

@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
.include_raw_pointers() .include_raw_pointers()
.filter_map(|(ty, _)| .filter_map(|(ty, _)|
match ty.sty { match ty.sty {
ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)), ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())),
_ => None, _ => None,
} }
) )

View File

@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
match self_ty.sty { match self_ty.sty {
ty::Dynamic(ref data, ..) => { ty::Dynamic(ref data, ..) => {
if let Some(p) = data.principal() { let p = data.principal();
self.assemble_inherent_candidates_from_object(self_ty, p); self.assemble_inherent_candidates_from_object(self_ty, p);
self.assemble_inherent_impl_candidates_for_type(p.def_id()); self.assemble_inherent_impl_candidates_for_type(p.def_id());
}
} }
ty::Adt(def, _) => { ty::Adt(def, _) => {
self.assemble_inherent_impl_candidates_for_type(def.did); self.assemble_inherent_impl_candidates_for_type(def.did);

View File

@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty::Adt(def, _) => def.did.is_local(), ty::Adt(def, _) => def.did.is_local(),
ty::Foreign(did) => did.is_local(), ty::Foreign(did) => did.is_local(),
ty::Dynamic(ref tr, ..) => tr.principal() ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(),
.map_or(false, |p| p.def_id().is_local()),
ty::Param(_) => true, ty::Param(_) => true,

View File

@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::Foreign(did) => { ty::Foreign(did) => {
self.check_def_id(item, did); self.check_def_id(item, did);
} }
ty::Dynamic(ref data, ..) if data.principal().is_some() => { ty::Dynamic(ref data, ..) => {
self.check_def_id(item, data.principal().unwrap().def_id()); self.check_def_id(item, data.principal().def_id());
} }
ty::Char => { ty::Char => {
self.check_primitive_impl(def_id, self.check_primitive_impl(def_id,

View File

@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
// This is something like impl Trait1 for Trait2. Illegal // This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe. // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) { if !tcx.is_object_safe(data.principal().def_id()) {
// This is an error, but it will be reported by wfcheck. Ignore it here. // This is an error, but it will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
} else { } else {
let mut supertrait_def_ids = let mut supertrait_def_ids =
traits::supertrait_def_ids(tcx, traits::supertrait_def_ids(tcx, data.principal().def_id());
data.principal().unwrap().def_id());
if supertrait_def_ids.any(|d| d == trait_def_id) { if supertrait_def_ids.any(|d| d == trait_def_id) {
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap()); let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
struct_span_err!(tcx.sess, struct_span_err!(tcx.sess,

View File

@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>(
debug!("Dynamic"); debug!("Dynamic");
debug!("field_ty = {}", &field_ty); debug!("field_ty = {}", &field_ty);
debug!("ty in field = {}", &ty); debug!("ty in field = {}", &ty);
if let Some(ex_trait_ref) = obj.principal() { let ex_trait_ref = obj.principal();
// Here, we are passing the type `usize` as a // Here, we are passing the type `usize` as a
// placeholder value with the function // placeholder value with the function
// `with_self_ty`, since there is no concrete type // `with_self_ty`, since there is no concrete type
// `Self` for a `dyn Trait` at this // `Self` for a `dyn Trait` at this
// stage. Therefore when checking explicit // stage. Therefore when checking explicit
// predicates in `check_explicit_predicates` we // predicates in `check_explicit_predicates` we
// need to ignore checking the explicit_map for // need to ignore checking the explicit_map for
// Self type. // Self type.
let substs = ex_trait_ref let substs = ex_trait_ref
.with_self_ty(tcx, tcx.types.usize) .with_self_ty(tcx, tcx.types.usize)
.skip_binder() .skip_binder()
.substs; .substs;
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
&ex_trait_ref.skip_binder().def_id, &ex_trait_ref.skip_binder().def_id,
substs, substs,
required_predicates, required_predicates,
explicit_map, explicit_map,
IgnoreSelfTy(true), IgnoreSelfTy(true),
); );
}
} }
ty::Projection(obj) => { ty::Projection(obj) => {

View File

@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
let contra = self.contravariant(variance); let contra = self.contravariant(variance);
self.add_constraints_from_region(current, r, contra); self.add_constraints_from_region(current, r, contra);
if let Some(p) = data.principal() { let poly_trait_ref = data
let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err); .principal()
self.add_constraints_from_trait_ref( .with_self_ty(self.tcx(), self.tcx().types.err);
current, *poly_trait_ref.skip_binder(), variance); self.add_constraints_from_trait_ref(
} current, *poly_trait_ref.skip_binder(), variance);
for projection in data.projection_bounds() { for projection in data.projection_bounds() {
self.add_constraints_from_ty( self.add_constraints_from_ty(

View File

@ -2632,47 +2632,44 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
} }
} }
ty::Dynamic(ref obj, ref reg) => { ty::Dynamic(ref obj, ref reg) => {
if let Some(principal) = obj.principal() { let principal = obj.principal();
let did = principal.def_id(); let did = principal.def_id();
inline::record_extern_fqn(cx, did, TypeKind::Trait);
let mut typarams = vec![];
reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
for did in obj.auto_traits() {
let empty = cx.tcx.intern_substs(&[]);
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
Some(did), false, vec![], empty);
inline::record_extern_fqn(cx, did, TypeKind::Trait); inline::record_extern_fqn(cx, did, TypeKind::Trait);
let bound = GenericBound::TraitBound(PolyTrait {
trait_: ResolvedPath {
path,
typarams: None,
did,
is_generic: false,
},
generic_params: Vec::new(),
}, hir::TraitBoundModifier::None);
typarams.push(bound);
}
let mut typarams = vec![]; let mut bindings = vec![];
reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); for pb in obj.projection_bounds() {
for did in obj.auto_traits() { bindings.push(TypeBinding {
let empty = cx.tcx.intern_substs(&[]); name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
let path = external_path(cx, &cx.tcx.item_name(did).as_str(), ty: pb.skip_binder().ty.clean(cx)
Some(did), false, vec![], empty); });
inline::record_extern_fqn(cx, did, TypeKind::Trait); }
let bound = GenericBound::TraitBound(PolyTrait {
trait_: ResolvedPath {
path,
typarams: None,
did,
is_generic: false,
},
generic_params: Vec::new(),
}, hir::TraitBoundModifier::None);
typarams.push(bound);
}
let mut bindings = vec![]; let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
for pb in obj.projection_bounds() { false, bindings, principal.skip_binder().substs);
bindings.push(TypeBinding { ResolvedPath {
name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), path,
ty: pb.skip_binder().ty.clean(cx) typarams: Some(typarams),
}); did,
} is_generic: false,
let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
false, bindings, principal.skip_binder().substs);
ResolvedPath {
path,
typarams: Some(typarams),
did,
is_generic: false,
}
} else {
Never
} }
} }
ty::Tuple(ref t) => Tuple(t.clean(cx)), ty::Tuple(ref t) => Tuple(t.clean(cx)),