Skip to content

Commit

Permalink
Privatize TraitObject.principal and add a method accessor, returning …
Browse files Browse the repository at this point in the history
…Option.
  • Loading branch information
Mark-Simulacrum committed Nov 28, 2016
1 parent 0b399e5 commit 46c7a11
Show file tree
Hide file tree
Showing 29 changed files with 142 additions and 103 deletions.
16 changes: 7 additions & 9 deletions src/librustc/traits/coherence.rs
Expand Up @@ -225,14 +225,12 @@ fn ty_is_local(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal) -> bool {

fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool {
match ty.sty {
ty::TyBox(..) | ty::TyRef(..) =>
true,
ty::TyAdt(def, _) =>
def.is_fundamental(),
ty::TyTrait(ref data) =>
tcx.has_attr(data.principal.def_id(), "fundamental"),
_ =>
false
ty::TyBox(..) | ty::TyRef(..) => true,
ty::TyAdt(def, _) => def.is_fundamental(),
ty::TyTrait(ref data) => {
data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
}
_ => false
}
}

Expand Down Expand Up @@ -273,7 +271,7 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)->
}

ty::TyTrait(ref tt) => {
tt.principal.def_id().is_local()
tt.principal().map_or(false, |p| p.def_id().is_local())
}

ty::TyError => {
Expand Down
34 changes: 21 additions & 13 deletions src/librustc/traits/select.rs
Expand Up @@ -1528,7 +1528,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
_ => {}
}

data.principal.with_self_ty(this.tcx(), self_ty)
match data.principal() {
Some(ref p) => p.with_self_ty(this.tcx(), self_ty),
None => return,
}
}
ty::TyInfer(ty::TyVar(_)) => {
debug!("assemble_candidates_from_object_ty: ambiguous");
Expand Down Expand Up @@ -1611,8 +1614,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
//
// We always upcast when we can because of reason
// #2 (region bounds).
data_a.principal.def_id() == data_b.principal.def_id() &&
data_a.builtin_bounds.is_superset(&data_b.builtin_bounds)
match (data_a.principal(), data_b.principal()) {
(Some(ref a), Some(ref b)) => a.def_id() == b.def_id() &&
data_a.builtin_bounds.is_superset(&data_b.builtin_bounds),
_ => false
}
}

// T -> Trait.
Expand Down Expand Up @@ -2167,7 +2173,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
match self_ty.sty {
ty::TyTrait(ref data) => {
// OK to skip the binder, it is reintroduced below
let input_types = data.principal.input_types();
let principal = data.principal().unwrap();
let input_types = principal.input_types();
let assoc_types = data.projection_bounds.iter()
.map(|pb| pb.skip_binder().ty);
let all_types: Vec<_> = input_types.chain(assoc_types)
Expand Down Expand Up @@ -2301,7 +2308,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
let poly_trait_ref = match self_ty.sty {
ty::TyTrait(ref data) => {
data.principal.with_self_ty(self.tcx(), self_ty)
data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
}
_ => {
span_bug!(obligation.cause.span,
Expand Down Expand Up @@ -2471,12 +2478,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
(&ty::TyTrait(ref data_a), &ty::TyTrait(ref data_b)) => {
// See assemble_candidates_for_unsizing for more info.
let new_trait = tcx.mk_trait(ty::TraitObject {
principal: data_a.principal,
region_bound: data_b.region_bound,
builtin_bounds: data_b.builtin_bounds,
projection_bounds: data_a.projection_bounds.clone(),
});
let new_trait = tcx.mk_trait(ty::TraitObject::new(
data_a.principal(),
data_b.region_bound,
data_b.builtin_bounds,
data_a.projection_bounds.clone(),
));
let origin = TypeOrigin::Misc(obligation.cause.span);
let InferOk { obligations, .. } =
self.infcx.sub_types(false, &obligation.cause, new_trait, target)
.map_err(|_| Unimplemented)?;
Expand All @@ -2499,7 +2507,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
data.builtin_bounds.iter().flat_map(|bound| {
tcx.lang_items.from_builtin_kind(bound).ok()
})
.chain(Some(data.principal.def_id()));
.chain(data.principal().map(|ref p| p.def_id()));
if let Some(did) = object_dids.find(|did| {
!tcx.is_object_safe(*did)
}) {
Expand All @@ -2516,7 +2524,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
};

// Create the obligation for casting from T to Trait.
push(data.principal.with_self_ty(tcx, source).to_predicate());
push(data.principal().unwrap().with_self_ty(tcx, source).to_predicate());

// We can only make objects from sized types.
let mut builtin_bounds = data.builtin_bounds;
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/ty/error.rs
Expand Up @@ -215,7 +215,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::TyFnDef(..) => format!("fn item"),
ty::TyFnPtr(_) => "fn pointer".to_string(),
ty::TyTrait(ref inner) => {
format!("trait {}", tcx.item_path_str(inner.principal.def_id()))
inner.principal().map_or_else(|| "trait".to_string(),
|p| format!("trait {}", tcx.item_path_str(p.def_id())))
}
ty::TyClosure(..) => "closure".to_string(),
ty::TyTuple(_) => "tuple".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fast_reject.rs
Expand Up @@ -60,7 +60,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::TyArray(..) | ty::TySlice(_) => Some(ArraySimplifiedType),
ty::TyRawPtr(_) => Some(PtrSimplifiedType),
ty::TyTrait(ref trait_info) => {
Some(TraitSimplifiedType(trait_info.principal.def_id()))
trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
}
ty::TyRef(_, mt) => {
// since we introduce auto-refs during method lookup, we
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/flags.rs
Expand Up @@ -123,7 +123,7 @@ impl FlagComputation {

&ty::TyTrait(ref obj) => {
let mut computation = FlagComputation::new();
computation.add_substs(obj.principal.skip_binder().substs);
computation.add_substs(obj.principal().unwrap().skip_binder().substs);
for projection_bound in &obj.projection_bounds {
let mut proj_computation = FlagComputation::new();
proj_computation.add_existential_projection(&projection_bound.0);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/item_path.rs
Expand Up @@ -316,7 +316,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
match ty.sty {
ty::TyAdt(adt_def, _) => Some(adt_def.did),

ty::TyTrait(ref data) => Some(data.principal.def_id()),
ty::TyTrait(ref data) => data.principal().map(|ref p| p.def_id()),

ty::TyArray(subty, _) |
ty::TySlice(subty) |
Expand Down
13 changes: 6 additions & 7 deletions src/librustc/ty/relate.rs
Expand Up @@ -417,7 +417,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,

(&ty::TyTrait(ref a_obj), &ty::TyTrait(ref b_obj)) =>
{
let principal = relation.relate(&a_obj.principal, &b_obj.principal)?;
let principal = match (a_obj.principal(), b_obj.principal()) {
(Some(ref a_p), Some(ref b_p)) => Some(relation.relate(a_p, b_p)?),
(None, None) => None,
_ => return Err(TypeError::Sorts(expected_found(relation, &a, &b))),
};
let r =
relation.with_cause(
Cause::ExistentialRegionBound,
Expand All @@ -426,12 +430,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
&b_obj.region_bound))?;
let nb = relation.relate(&a_obj.builtin_bounds, &b_obj.builtin_bounds)?;
let pb = relation.relate(&a_obj.projection_bounds, &b_obj.projection_bounds)?;
Ok(tcx.mk_trait(ty::TraitObject {
principal: principal,
region_bound: r,
builtin_bounds: nb,
projection_bounds: pb
}))
Ok(tcx.mk_trait(ty::TraitObject::new(principal, r, nb, pb)))
}

(&ty::TyClosure(a_id, a_substs),
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/ty/structural_impls.rs
Expand Up @@ -429,16 +429,16 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {

impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TraitObject {
principal: self.principal.fold_with(folder),
region_bound: self.region_bound.fold_with(folder),
builtin_bounds: self.builtin_bounds,
projection_bounds: self.projection_bounds.fold_with(folder),
}
ty::TraitObject::new(
self.principal().map(|p| p.fold_with(folder)),
self.region_bound.fold_with(folder),
self.builtin_bounds,
self.projection_bounds.fold_with(folder),
)
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.principal.visit_with(visitor) ||
self.principal().map(|p| p.visit_with(visitor)).unwrap_or(true) ||
self.region_bound.visit_with(visitor) ||
self.projection_bounds.visit_with(visitor)
}
Expand Down
23 changes: 20 additions & 3 deletions src/librustc/ty/sty.rs
Expand Up @@ -277,12 +277,29 @@ impl<'a, 'gcx, 'acx, 'tcx> ClosureSubsts<'tcx> {

#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct TraitObject<'tcx> {
pub principal: PolyExistentialTraitRef<'tcx>,
principal: Option<PolyExistentialTraitRef<'tcx>>,
pub region_bound: &'tcx ty::Region,
pub builtin_bounds: BuiltinBounds,
pub projection_bounds: Vec<PolyExistentialProjection<'tcx>>,
}

impl<'tcx> TraitObject<'tcx> {
pub fn new(principal: Option<PolyExistentialTraitRef<'tcx>>, region_bound: &'tcx ty::Region,
builtin_bounds: BuiltinBounds, projection_bounds: Vec<PolyExistentialProjection<'tcx>>)
-> Self {
TraitObject {
principal: principal,
region_bound: region_bound,
builtin_bounds: builtin_bounds,
projection_bounds: projection_bounds,
}
}

pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
self.principal
}
}

/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause:
///
Expand Down Expand Up @@ -1221,7 +1238,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {

pub fn ty_to_def_id(&self) -> Option<DefId> {
match self.sty {
TyTrait(ref tt) => Some(tt.principal.def_id()),
TyTrait(ref tt) => tt.principal().map(|p| p.def_id()),
TyAdt(def, _) => Some(def.did),
TyClosure(id, _) => Some(id),
_ => None
Expand All @@ -1245,7 +1262,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
TyTrait(ref obj) => {
let mut v = vec![obj.region_bound];
v.extend(obj.principal.skip_binder().substs.regions());
v.extend(obj.principal().unwrap().skip_binder().substs.regions());
v
}
TyAdt(_, substs) | TyAnon(_, substs) => {
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/ty/util.rs
Expand Up @@ -532,7 +532,9 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
self.hash(f.sig.inputs().skip_binder().len());
}
TyTrait(ref data) => {
self.def_id(data.principal.def_id());
if let Some(ref p) = data.principal() {
self.def_id(p.def_id());
}
self.hash(data.builtin_bounds);
}
TyTuple(tys) => {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/ty/walk.rs
Expand Up @@ -93,7 +93,10 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
stack.extend(data.trait_ref.substs.types().rev());
}
ty::TyTrait(ref obj) => {
stack.extend(obj.principal.input_types().rev());
match obj.principal() {
Some(ref p) => stack.extend(p.input_types().rev()),
None => {}
}
stack.extend(obj.projection_bounds.iter().map(|pred| {
pred.0.ty
}).rev());
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/wf.rs
Expand Up @@ -394,7 +394,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
data.builtin_bounds.iter().flat_map(|bound| {
tcx.lang_items.from_builtin_kind(bound).ok()
})
.chain(Some(data.principal.def_id()));
.chain(data.principal().map(|ref p| p.def_id()));
self.out.extend(
component_traits.map(|did| { traits::Obligation::new(
cause.clone(),
Expand Down Expand Up @@ -492,7 +492,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
if !data.has_escaping_regions() {
let implicit_bounds =
object_region_bounds(self.infcx.tcx,
data.principal,
data.principal().unwrap(),
data.builtin_bounds);

let explicit_bound = data.region_bound;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/util/ppaux.rs
Expand Up @@ -339,7 +339,7 @@ impl<'tcx> fmt::Display for ty::TraitObject<'tcx> {
// Use a type that can't appear in defaults of type parameters.
let dummy_self = tcx.mk_infer(ty::FreshTy(0));

let principal = tcx.lift(&self.principal)
let principal = self.principal().and_then(|ref p| tcx.lift(p))
.expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self).0;
let projections = self.projection_bounds.iter().map(|p| {
Expand Down Expand Up @@ -466,7 +466,7 @@ impl<'tcx> fmt::Debug for ty::TraitObject<'tcx> {
};

maybe_continue(f)?;
write!(f, "{:?}", self.principal)?;
write!(f, "{:?}", self.principal())?;

let region_str = format!("{:?}", self.region_bound);
if !region_str.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/base.rs
Expand Up @@ -302,7 +302,7 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
old_info.expect("unsized_info: missing old info for trait upcast")
}
(_, &ty::TyTrait(ref data)) => {
let trait_ref = data.principal.with_self_ty(ccx.tcx(), source);
let trait_ref = data.principal().unwrap().with_self_ty(ccx.tcx(), source);
let trait_ref = ccx.tcx().erase_regions(&trait_ref);
consts::ptrcast(meth::get_vtable(ccx, trait_ref),
Type::vtable_ptr(ccx))
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/collector.rs
Expand Up @@ -1004,7 +1004,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
assert!(!trait_ty.needs_subst() && !impl_ty.needs_subst());

if let ty::TyTrait(ref trait_ty) = trait_ty.sty {
let poly_trait_ref = trait_ty.principal.with_self_ty(scx.tcx(), impl_ty);
let poly_trait_ref = trait_ty.principal().unwrap().with_self_ty(scx.tcx(), impl_ty);
let param_substs = scx.tcx().intern_substs(&[]);

// Walk all methods of the trait, including those of its supertraits
Expand Down
11 changes: 7 additions & 4 deletions src/librustc_trans/debuginfo/metadata.rs
Expand Up @@ -431,8 +431,13 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// type is assigned the correct name, size, namespace, and source location.
// But it does not describe the trait's methods.

let def_id = match trait_type.sty {
ty::TyTrait(ref data) => data.principal.def_id(),
let containing_scope = match trait_type.sty {
ty::TyTrait(ref data) => if let Some(principal) = data.principal() {
let def_id = principal.def_id();
get_namespace_and_span_for_item(cx, def_id).0
} else {
NO_SCOPE_METADATA
},
_ => {
bug!("debuginfo: Unexpected trait-object type in \
trait_pointer_metadata(): {:?}",
Expand All @@ -444,8 +449,6 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let trait_type_name =
compute_debuginfo_type_name(cx, trait_object_type, false);

let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);

let trait_llvm_type = type_of::type_of(cx, trait_object_type);
let file_metadata = unknown_file_metadata(cx);

Expand Down
10 changes: 6 additions & 4 deletions src/librustc_trans/debuginfo/type_names.rs
Expand Up @@ -94,10 +94,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push(']');
},
ty::TyTrait(ref trait_data) => {
let principal = cx.tcx().erase_late_bound_regions_and_normalize(
&trait_data.principal);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
if let Some(principal) = trait_data.principal() {
let principal = cx.tcx().erase_late_bound_regions_and_normalize(
&principal);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
}
},
ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
Expand Down
10 changes: 6 additions & 4 deletions src/librustc_trans/trans_item.rs
Expand Up @@ -458,10 +458,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
output.push(']');
},
ty::TyTrait(ref trait_data) => {
self.push_def_path(trait_data.principal.def_id(), output);
self.push_type_params(trait_data.principal.skip_binder().substs,
&trait_data.projection_bounds,
output);
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);
}
},
ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
Expand Down

0 comments on commit 46c7a11

Please sign in to comment.