Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check the invariant for principal inside the method #55032

Merged
merged 2 commits into from
Oct 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
match ty.sty {
ty::Ref(..) => true,
ty::Adt(def, _) => def.is_fundamental(),
ty::Dynamic(ref data, ..) => {
data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
}
ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"),
_ => false
}
}
Expand Down Expand Up @@ -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::Foreign(did) => def_id_is_local(did, in_crate),

ty::Dynamic(ref tt, ..) => {
tt.principal().map_or(false, |p|
def_id_is_local(p.def_id(), in_crate)
)
}
ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),

ty::Error => true,

Expand Down
27 changes: 8 additions & 19 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
return;
}

match data.principal() {
Some(p) => p.with_self_ty(this.tcx(), self_ty),
None => return,
}
data.principal().with_self_ty(this.tcx(), self_ty)
}
ty::Infer(ty::TyVar(_)) => {
debug!("assemble_candidates_from_object_ty: ambiguous");
Expand Down Expand Up @@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
//
// We always upcast when we can because of reason
// #2 (region bounds).
match (data_a.principal(), data_b.principal()) {
(Some(a), Some(b)) => {
a.def_id() == b.def_id()
&& data_b.auto_traits()
// 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,
}
data_a.principal().def_id() == data_b.principal().def_id()
&& data_b.auto_traits()
// All of a's auto traits need to be in b's auto traits.
.all(|b| data_a.auto_traits().any(|a| a == b))
}

// T -> Trait.
Expand Down Expand Up @@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
.shallow_resolve(*obligation.self_ty().skip_binder());
let poly_trait_ref = match self_ty.sty {
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"),
};
Expand Down Expand Up @@ -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)) => {
// See assemble_candidates_for_unsizing for more info.
let existential_predicates = data_a.map_bound(|data_a| {
let principal = data_a.principal();
let iter = principal
.into_iter()
.map(ty::ExistentialPredicate::Trait)
let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
.chain(
data_a
.projection_bounds()
Expand Down Expand Up @@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// T -> Trait.
(_, &ty::Dynamic(ref data, r)) => {
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)) {
return Err(TraitNotObjectSafe(did));
}
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::FnDef(..) => "fn item".into(),
ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(ref inner, ..) => {
inner.principal().map_or_else(|| "trait".into(),
|p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into()
}
ty::Closure(..) => "closure".into(),
ty::Generator(..) => "generator".into(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
ty::RawPtr(_) => Some(PtrSimplifiedType),
ty::Dynamic(ref trait_info, ..) => {
trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
Some(TraitSimplifiedType(trait_info.principal().def_id()))
}
ty::Ref(_, ty, _) => {
// since we introduce auto-refs during method lookup, we
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
match ty.sty {
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::Slice(subty) => characteristic_def_id_of_type(subty),
Expand Down
16 changes: 7 additions & 9 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}

impl<'tcx> List<ExistentialPredicate<'tcx>> {
pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
match self.get(0) {
Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
_ => None,
pub fn principal(&self) -> ExistentialTraitRef<'tcx> {
match self[0] {
ExistentialPredicate::Trait(tr) => tr,
other => bug!("first predicate is {:?}", other),
}
}

Expand All @@ -589,8 +589,8 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
}

impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
self.skip_binder().principal().map(Binder::bind)
pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> {
Binder::bind(self.skip_binder().principal())
}

#[inline]
Expand Down Expand Up @@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
Dynamic(ref obj, region) => {
let mut v = vec![region];
if let Some(p) = obj.principal() {
v.extend(p.skip_binder().substs.regions());
}
v.extend(obj.principal().skip_binder().substs.regions());
v
}
Adt(_, substs) | Opaque(_, substs) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {

let cause = self.cause(traits::MiscObligation);
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(
component_traits.map(|did| traits::Obligation::new(
cause.clone(),
Expand Down
20 changes: 10 additions & 10 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,16 +621,16 @@ define_print! {
// Use a type that can't appear in defaults of type parameters.
let dummy_self = tcx.mk_infer(ty::FreshTy(0));

if let Some(p) = self.principal() {
let principal = tcx.lift(&p).expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self);
let projections = self.projection_bounds().map(|p| {
tcx.lift(&p)
.expect("could not lift projection for printing")
.with_self_ty(tcx, dummy_self)
}).collect::<Vec<_>>();
cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
}
let principal = tcx
.lift(&self.principal())
.expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self);
let projections = self.projection_bounds().map(|p| {
tcx.lift(&p)
.expect("could not lift projection for printing")
.with_self_ty(tcx, dummy_self)
}).collect::<Vec<_>>();
cx.parameterized(f, principal.substs, principal.def_id, &projections)?;

// Builtin bounds.
for did in self.auto_traits() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
/// Cache instances of monomorphic and polymorphic items
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
/// Cache generated vtables
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>),
&'a Value>>,
/// Cache of constant strings,
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
Expand Down
7 changes: 1 addition & 6 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,7 @@ fn trait_pointer_metadata(
// But it does not describe the trait's methods.

let containing_scope = match trait_type.sty {
ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() {
let def_id = principal.def_id();
Some(get_namespace_for_item(cx, def_id))
} else {
NO_SCOPE_METADATA
},
ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
_ => {
bug!("debuginfo: Unexpected trait-object type in \
trait_pointer_metadata(): {:?}",
Expand Down
14 changes: 6 additions & 8 deletions src/librustc_codegen_llvm/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
}
},
ty::Dynamic(ref trait_data, ..) => {
if let Some(principal) = trait_data.principal() {
let principal = cx.tcx.normalize_erasing_late_bound_regions(
ty::ParamEnv::reveal_all(),
&principal,
);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
}
let principal = cx.tcx.normalize_erasing_late_bound_regions(
ty::ParamEnv::reveal_all(),
&trait_data.principal(),
);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
},
ty::FnDef(..) | ty::FnPtr(_) => {
let sig = t.fn_sig(cx.tcx);
Expand Down
24 changes: 10 additions & 14 deletions src/librustc_codegen_llvm/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex {
pub fn get_vtable(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> &'ll Value {
let tcx = cx.tcx;

Expand All @@ -86,23 +86,19 @@ pub fn get_vtable(
// Not in the cache. Build it.
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 mut components: Vec<_> = [
let components: Vec<_> = [
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
C_usize(cx, size.bytes()),
C_usize(cx, align.abi())
].iter().cloned().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);
}
].iter().cloned().chain(methods).collect();

let vtable_const = C_struct(cx, &components, false);
let align = cx.data_layout().pointer_align;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
}
(_, &ty::Dynamic(ref data, _)) => {
// 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,
src_pointee_ty,
);
Expand Down
30 changes: 14 additions & 16 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());

if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
if let Some(principal) = trait_ty.principal() {
let poly_trait_ref = principal.with_self_ty(tcx, impl_ty);
assert!(!poly_trait_ref.has_escaping_regions());

// Walk all methods of the trait, including those of its supertraits
let methods = tcx.vtable_methods(poly_trait_ref);
let methods = methods.iter().cloned().filter_map(|method| method)
.map(|(def_id, substs)| ty::Instance::resolve(
tcx,
ty::ParamEnv::reveal_all(),
def_id,
substs).unwrap())
.filter(|&instance| should_monomorphize_locally(tcx, &instance))
.map(|instance| create_fn_mono_item(instance));
output.extend(methods);
}
let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
assert!(!poly_trait_ref.has_escaping_regions());

// Walk all methods of the trait, including those of its supertraits
let methods = tcx.vtable_methods(poly_trait_ref);
let methods = methods.iter().cloned().filter_map(|method| method)
.map(|(def_id, substs)| ty::Instance::resolve(
tcx,
ty::ParamEnv::reveal_all(),
def_id,
substs).unwrap())
.filter(|&instance| should_monomorphize_locally(tcx, &instance))
.map(|instance| create_fn_mono_item(instance));
output.extend(methods);
// Also add the destructor
visit_drop_use(tcx, impl_ty, false, output);
}
Expand Down
13 changes: 7 additions & 6 deletions src/librustc_mir/monomorphize/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
output.push(']');
},
ty::Dynamic(ref trait_data, ..) => {
if let Some(principal) = trait_data.principal() {
self.push_def_path(principal.def_id(), output);
self.push_type_params(principal.skip_binder().substs,
trait_data.projection_bounds(),
output);
}
let principal = trait_data.principal();
self.push_def_path(principal.def_id(), output);
self.push_type_params(
principal.skip_binder().substs,
trait_data.projection_bounds(),
output,
);
},
ty::Foreign(did) => self.push_def_path(did, output),
ty::FnDef(..) |
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
let ty_def_id = match self.tcx.type_of(item_def_id).sty {
ty::Adt(adt, _) => adt.did,
ty::Foreign(did) => did,
ty::Dynamic(ref obj, ..) if obj.principal().is_some() =>
obj.principal().unwrap().def_id(),
ty::Dynamic(ref obj, ..) => obj.principal().def_id(),
ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
_ => return Some(AccessLevel::Public)
};
Expand Down Expand Up @@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.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::FnDef(def_id, ..) |
ty::Closure(def_id, ..) |
Expand Down Expand Up @@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
let ty_def_id = match ty.sty {
ty::Adt(adt, _) => Some(adt.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) => {
if self.required_visibility == ty::Visibility::Invisible {
// Conservatively approximate the whole type alias as public without
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ enum PointerKind<'tcx> {
/// No metadata attached, ie pointer to sized type or foreign type
Thin,
/// A trait object
Vtable(Option<DefId>),
Vtable(DefId),
/// Slice
Length,
/// The unsize info of this projection
Expand Down Expand Up @@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Ok(match t.sty {
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
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() => {
match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin),
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.deduce_sig_from_projection(None, &pb)
})
.next();
let kind = object_type
.principal()
.and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id());
(sig, kind)
}
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
Expand Down
Loading