Make TyTrait embed a TraitRef
, so that when we extend TraitRef, it naturally carries over to object types.
I wanted to embed an `Rc<TraitRef>`, but I was foiled by the current static rules, which prohibit non-Sync values from being stored in static locations. This means that the constants for `ty_int` and so forth cannot be initialized.
This commit is contained in:
parent
0a3cbf8cf4
commit
c18a1327e3
@ -389,11 +389,10 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
|
||||
}
|
||||
'x' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let def = parse_def(st, NominalType, |x,y| conv(x,y));
|
||||
let substs = parse_substs(st, |x,y| conv(x,y));
|
||||
let trait_ref = parse_trait_ref(st, |x,y| conv(x,y));
|
||||
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_trait(st.tcx, def, substs, bounds);
|
||||
return ty::mk_trait(st.tcx, trait_ref, bounds);
|
||||
}
|
||||
'p' => {
|
||||
let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
|
||||
|
@ -231,13 +231,10 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
ref bounds
|
||||
}) => {
|
||||
mywrite!(w, "x[{}|", (cx.ds)(def_id));
|
||||
enc_substs(w, cx, substs);
|
||||
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||
ref bounds }) => {
|
||||
mywrite!(w, "x[");
|
||||
enc_trait_ref(w, cx, principal);
|
||||
enc_existential_bounds(w, cx, bounds);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
|
@ -1085,16 +1085,19 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
|
||||
this.emit_enum_variant_arg(1, |this| idx.encode(this))
|
||||
})
|
||||
}
|
||||
ty::UnsizeVtable(ty::TyTrait { def_id,
|
||||
bounds: ref b,
|
||||
ref substs },
|
||||
ty::UnsizeVtable(ty::TyTrait { ref principal,
|
||||
bounds: ref b },
|
||||
self_ty) => {
|
||||
this.emit_enum_variant("UnsizeVtable", 2, 4, |this| {
|
||||
this.emit_enum_variant_arg(
|
||||
0, |this| Ok(this.emit_existential_bounds(ecx, b)));
|
||||
this.emit_enum_variant_arg(1, |this| def_id.encode(this));
|
||||
this.emit_enum_variant_arg(2, |this| Ok(this.emit_ty(ecx, self_ty)));
|
||||
this.emit_enum_variant_arg(3, |this| Ok(this.emit_substs(ecx, substs)))
|
||||
this.emit_enum_variant_arg(0, |this| {
|
||||
try!(this.emit_struct_field("principal", 0, |this| {
|
||||
Ok(this.emit_trait_ref(ecx, &*principal))
|
||||
}));
|
||||
this.emit_struct_field("bounds", 1, |this| {
|
||||
Ok(this.emit_existential_bounds(ecx, b))
|
||||
})
|
||||
});
|
||||
this.emit_enum_variant_arg(1, |this| Ok(this.emit_ty(ecx, self_ty)))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1693,18 +1696,19 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
|
||||
ty::UnsizeStruct(box uk, idx)
|
||||
}
|
||||
2 => {
|
||||
let b =
|
||||
this.read_enum_variant_arg(
|
||||
0, |this| Ok(this.read_existential_bounds(dcx))).unwrap();
|
||||
let def_id: ast::DefId =
|
||||
this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
|
||||
let ty_trait = try!(this.read_enum_variant_arg(0, |this| {
|
||||
let principal = try!(this.read_struct_field("principal", 0, |this| {
|
||||
Ok(this.read_trait_ref(dcx))
|
||||
}));
|
||||
Ok(ty::TyTrait {
|
||||
principal: (*principal).clone(),
|
||||
bounds: try!(this.read_struct_field("bounds", 1, |this| {
|
||||
Ok(this.read_existential_bounds(dcx))
|
||||
})),
|
||||
})
|
||||
}));
|
||||
let self_ty =
|
||||
this.read_enum_variant_arg(2, |this| Ok(this.read_ty(dcx))).unwrap();
|
||||
let substs = this.read_enum_variant_arg(3,
|
||||
|this| Ok(this.read_substs(dcx))).unwrap();
|
||||
let ty_trait = ty::TyTrait { def_id: def_id.tr(dcx),
|
||||
bounds: b,
|
||||
substs: substs };
|
||||
this.read_enum_variant_arg(1, |this| Ok(this.read_ty(dcx))).unwrap();
|
||||
ty::UnsizeVtable(ty_trait, self_ty)
|
||||
}
|
||||
_ => panic!("bad enum variant for ty::UnsizeKind")
|
||||
|
@ -143,7 +143,7 @@ pub fn ty_is_local(tcx: &ty::ctxt,
|
||||
}
|
||||
|
||||
ty::ty_trait(ref tt) => {
|
||||
tt.def_id.krate == ast::LOCAL_CRATE
|
||||
tt.principal.def_id.krate == ast::LOCAL_CRATE
|
||||
}
|
||||
|
||||
// Type parameters may be bound to types that are not local to
|
||||
|
@ -423,8 +423,8 @@ impl TypeMap {
|
||||
|
||||
from_def_id_and_substs(self,
|
||||
cx,
|
||||
trait_data.def_id,
|
||||
&trait_data.substs,
|
||||
trait_data.principal.def_id,
|
||||
&trait_data.principal.substs,
|
||||
&mut unique_type_id);
|
||||
},
|
||||
ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
|
||||
@ -2813,7 +2813,7 @@ fn trait_pointer_metadata(cx: &CrateContext,
|
||||
// But it does not describe the trait's methods.
|
||||
|
||||
let def_id = match ty::get(trait_type).sty {
|
||||
ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, .. }) => principal.def_id,
|
||||
_ => {
|
||||
let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
|
||||
cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
|
||||
@ -3739,8 +3739,8 @@ fn push_debuginfo_type_name(cx: &CrateContext,
|
||||
output.push(']');
|
||||
},
|
||||
ty::ty_trait(ref trait_data) => {
|
||||
push_item_name(cx, trait_data.def_id, false, output);
|
||||
push_type_params(cx, &trait_data.substs, output);
|
||||
push_item_name(cx, trait_data.principal.def_id, false, output);
|
||||
push_type_params(cx, &trait_data.principal.substs, output);
|
||||
},
|
||||
ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
|
||||
if fn_style == ast::UnsafeFn {
|
||||
|
@ -324,10 +324,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
_ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
|
||||
bcx.ty_to_string(unsized_ty)).as_slice())
|
||||
},
|
||||
&ty::UnsizeVtable(ty::TyTrait { def_id, ref substs, .. }, _) => {
|
||||
let substs = substs.with_self_ty(unsized_ty);
|
||||
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
|
||||
let substs = principal.substs.with_self_ty(unsized_ty);
|
||||
let trait_ref =
|
||||
Rc::new(ty::TraitRef { def_id: def_id,
|
||||
Rc::new(ty::TraitRef { def_id: principal.def_id,
|
||||
substs: substs });
|
||||
let trait_ref =
|
||||
trait_ref.subst(bcx.tcx(), &bcx.fcx.param_substs.substs);
|
||||
|
@ -378,14 +378,14 @@ pub fn type_of_adjust(cx: &ctxt, adj: &AutoAdjustment) -> Option<t> {
|
||||
fn type_of_autoref(cx: &ctxt, autoref: &AutoRef) -> Option<t> {
|
||||
match autoref {
|
||||
&AutoUnsize(ref k) => match k {
|
||||
&UnsizeVtable(TyTrait { def_id, ref substs, bounds }, _) => {
|
||||
Some(mk_trait(cx, def_id, substs.clone(), bounds))
|
||||
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
|
||||
Some(mk_trait(cx, (*principal).clone(), bounds))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
&AutoUnsizeUniq(ref k) => match k {
|
||||
&UnsizeVtable(TyTrait { def_id, ref substs, bounds }, _) => {
|
||||
Some(mk_uniq(cx, mk_trait(cx, def_id, substs.clone(), bounds)))
|
||||
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
|
||||
Some(mk_uniq(cx, mk_trait(cx, (*principal).clone(), bounds)))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
@ -983,12 +983,12 @@ pub enum sty {
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
pub struct TyTrait {
|
||||
pub def_id: DefId,
|
||||
pub substs: Substs,
|
||||
// Principal trait reference.
|
||||
pub principal: TraitRef, // would use Rc<TraitRef>, but it runs afoul of some static rules
|
||||
pub bounds: ExistentialBounds
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Hash, Show)]
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
pub struct TraitRef {
|
||||
pub def_id: DefId,
|
||||
pub substs: Substs,
|
||||
@ -1643,8 +1643,8 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
||||
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
|
||||
flags = flags | sflags(substs);
|
||||
}
|
||||
&ty_trait(box TyTrait { ref substs, ref bounds, .. }) => {
|
||||
flags = flags | sflags(substs);
|
||||
&ty_trait(box TyTrait { ref principal, ref bounds }) => {
|
||||
flags = flags | sflags(&principal.substs);
|
||||
flags = flags | flags_for_bounds(bounds);
|
||||
}
|
||||
&ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => {
|
||||
@ -1874,14 +1874,12 @@ pub fn mk_ctor_fn(cx: &ctxt,
|
||||
|
||||
|
||||
pub fn mk_trait(cx: &ctxt,
|
||||
did: ast::DefId,
|
||||
substs: Substs,
|
||||
principal: ty::TraitRef,
|
||||
bounds: ExistentialBounds)
|
||||
-> t {
|
||||
// take a copy of substs so that we own the vectors inside
|
||||
let inner = box TyTrait {
|
||||
def_id: did,
|
||||
substs: substs,
|
||||
principal: principal,
|
||||
bounds: bounds
|
||||
};
|
||||
mk_t(cx, ty_trait(inner))
|
||||
@ -1934,9 +1932,15 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
|
||||
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
|
||||
maybe_walk_ty(tm.ty, f);
|
||||
}
|
||||
ty_enum(_, ref substs) | ty_struct(_, ref substs) | ty_unboxed_closure(_, _, ref substs) |
|
||||
ty_trait(box TyTrait { ref substs, .. }) => {
|
||||
for subty in (*substs).types.iter() {
|
||||
ty_trait(box TyTrait { ref principal, .. }) => {
|
||||
for subty in principal.substs.types.iter() {
|
||||
maybe_walk_ty(*subty, |x| f(x));
|
||||
}
|
||||
}
|
||||
ty_enum(_, ref substs) |
|
||||
ty_struct(_, ref substs) |
|
||||
ty_unboxed_closure(_, _, ref substs) => {
|
||||
for subty in substs.types.iter() {
|
||||
maybe_walk_ty(*subty, |x| f(x));
|
||||
}
|
||||
}
|
||||
@ -3554,8 +3558,8 @@ pub fn unsize_ty(cx: &ctxt,
|
||||
format!("UnsizeStruct with bad sty: {}",
|
||||
ty_to_string(cx, ty)).as_slice())
|
||||
},
|
||||
&UnsizeVtable(TyTrait { def_id, ref substs, bounds }, _) => {
|
||||
mk_trait(cx, def_id, substs.clone(), bounds)
|
||||
&UnsizeVtable(TyTrait { ref principal, bounds }, _) => {
|
||||
mk_trait(cx, (*principal).clone(), bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3808,7 +3812,7 @@ pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
|
||||
ty_bare_fn(_) => "extern fn".to_string(),
|
||||
ty_closure(_) => "fn".to_string(),
|
||||
ty_trait(ref inner) => {
|
||||
format!("trait {}", item_path_str(cx, inner.def_id))
|
||||
format!("trait {}", item_path_str(cx, inner.principal.def_id))
|
||||
}
|
||||
ty_struct(id, _) => {
|
||||
format!("struct {}", item_path_str(cx, id))
|
||||
@ -4230,11 +4234,14 @@ pub fn try_add_builtin_trait(
|
||||
|
||||
pub fn ty_to_def_id(ty: t) -> Option<ast::DefId> {
|
||||
match get(ty).sty {
|
||||
ty_trait(box TyTrait { def_id: id, .. }) |
|
||||
ty_trait(ref tt) =>
|
||||
Some(tt.principal.def_id),
|
||||
ty_struct(id, _) |
|
||||
ty_enum(id, _) |
|
||||
ty_unboxed_closure(id, _, _) => Some(id),
|
||||
_ => None
|
||||
ty_unboxed_closure(id, _, _) =>
|
||||
Some(id),
|
||||
_ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -5213,9 +5220,9 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_trait(box TyTrait { def_id: d, bounds, .. }) => {
|
||||
ty_trait(box TyTrait { ref principal, bounds }) => {
|
||||
byte!(17);
|
||||
did(&mut state, d);
|
||||
did(&mut state, principal.def_id);
|
||||
hash!(bounds);
|
||||
}
|
||||
ty_struct(d, _) => {
|
||||
@ -5504,12 +5511,13 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
|
||||
typ: t) {
|
||||
walk_ty(typ, |typ| {
|
||||
match get(typ).sty {
|
||||
ty_rptr(region, _) => accumulator.push(region),
|
||||
ty_rptr(region, _) => {
|
||||
accumulator.push(region)
|
||||
}
|
||||
ty_trait(ref t) => {
|
||||
accumulator.push_all(t.principal.substs.regions().as_slice());
|
||||
}
|
||||
ty_enum(_, ref substs) |
|
||||
ty_trait(box TyTrait {
|
||||
ref substs,
|
||||
..
|
||||
}) |
|
||||
ty_struct(_, ref substs) => {
|
||||
accum_substs(accumulator, substs);
|
||||
}
|
||||
|
@ -373,12 +373,11 @@ impl TypeFoldable for ty::UnsizeKind {
|
||||
match *self {
|
||||
ty::UnsizeLength(len) => ty::UnsizeLength(len),
|
||||
ty::UnsizeStruct(box ref k, n) => ty::UnsizeStruct(box k.fold_with(folder), n),
|
||||
ty::UnsizeVtable(ty::TyTrait{bounds, def_id, ref substs}, self_ty) => {
|
||||
ty::UnsizeVtable(ty::TyTrait{ref principal, bounds}, self_ty) => {
|
||||
ty::UnsizeVtable(
|
||||
ty::TyTrait {
|
||||
principal: principal.fold_with(folder),
|
||||
bounds: bounds.fold_with(folder),
|
||||
def_id: def_id,
|
||||
substs: substs.fold_with(folder)
|
||||
},
|
||||
self_ty.fold_with(folder))
|
||||
}
|
||||
@ -529,15 +528,10 @@ pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
ty::ty_enum(tid, ref substs) => {
|
||||
ty::ty_enum(tid, substs.fold_with(this))
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
bounds
|
||||
}) => {
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id: def_id,
|
||||
substs: substs.fold_with(this),
|
||||
bounds: this.fold_existential_bounds(bounds),
|
||||
principal: (*principal).fold_with(this),
|
||||
bounds: bounds.fold_with(this),
|
||||
})
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
|
@ -405,11 +405,11 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC,
|
||||
associated_type: Option<ty::t>,
|
||||
path: &ast::Path,
|
||||
binder_id: ast::NodeId)
|
||||
-> Rc<ty::TraitRef>
|
||||
-> ty::TraitRef
|
||||
where AC: AstConv<'tcx>,
|
||||
RS: RegionScope {
|
||||
let trait_def = this.get_trait_def(trait_def_id);
|
||||
Rc::new(ty::TraitRef {
|
||||
ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: ast_path_substs(this,
|
||||
rscope,
|
||||
@ -419,7 +419,7 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC,
|
||||
associated_type,
|
||||
path,
|
||||
binder_id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
||||
@ -702,26 +702,17 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
||||
None,
|
||||
path,
|
||||
id);
|
||||
let bounds = match *opt_bounds {
|
||||
None => {
|
||||
conv_existential_bounds(this,
|
||||
rscope,
|
||||
path.span,
|
||||
[result.clone()].as_slice(),
|
||||
[].as_slice())
|
||||
}
|
||||
Some(ref bounds) => {
|
||||
conv_existential_bounds(this,
|
||||
rscope,
|
||||
path.span,
|
||||
[result.clone()].as_slice(),
|
||||
bounds.as_slice())
|
||||
}
|
||||
};
|
||||
let empty_vec = [];
|
||||
let bounds = match *opt_bounds { None => empty_vec.as_slice(),
|
||||
Some(ref bounds) => bounds.as_slice() };
|
||||
let existential_bounds = conv_existential_bounds(this,
|
||||
rscope,
|
||||
path.span,
|
||||
&[Rc::new(result.clone())],
|
||||
bounds);
|
||||
let tr = ty::mk_trait(tcx,
|
||||
result.def_id,
|
||||
result.substs.clone(),
|
||||
bounds);
|
||||
result,
|
||||
existential_bounds);
|
||||
return match ptr_ty {
|
||||
Uniq => {
|
||||
return ty::mk_uniq(tcx, tr);
|
||||
@ -943,11 +934,10 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
||||
let bounds = conv_existential_bounds(this,
|
||||
rscope,
|
||||
ast_ty.span,
|
||||
&[result.clone()],
|
||||
&[Rc::new(result.clone())],
|
||||
ast_bounds);
|
||||
ty::mk_trait(tcx,
|
||||
result.def_id,
|
||||
result.substs.clone(),
|
||||
result,
|
||||
bounds)
|
||||
}
|
||||
def::DefTy(did, _) | def::DefStruct(did) => {
|
||||
|
@ -632,9 +632,9 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
|
||||
let span = self.self_expr.map_or(self.span, |e| e.span);
|
||||
check::autoderef(self.fcx, span, self_ty, None, NoPreference, |self_ty, _| {
|
||||
match get(self_ty).sty {
|
||||
ty_trait(box TyTrait { def_id, ref substs, bounds, .. }) => {
|
||||
self.push_inherent_candidates_from_object(self_ty, def_id, substs, bounds);
|
||||
self.push_inherent_impl_candidates_for_type(def_id);
|
||||
ty_trait(box TyTrait { ref principal, bounds, .. }) => {
|
||||
self.push_inherent_candidates_from_object(self_ty, &*principal, bounds);
|
||||
self.push_inherent_impl_candidates_for_type(principal.def_id);
|
||||
}
|
||||
ty_enum(did, _) |
|
||||
ty_struct(did, _) |
|
||||
@ -744,24 +744,23 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
|
||||
|
||||
fn push_inherent_candidates_from_object(&mut self,
|
||||
self_ty: ty::t,
|
||||
did: DefId,
|
||||
substs: &subst::Substs,
|
||||
principal: &ty::TraitRef,
|
||||
_bounds: ty::ExistentialBounds) {
|
||||
debug!("push_inherent_candidates_from_object(self_ty={})",
|
||||
self_ty.repr(self.tcx()));
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
||||
// 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,
|
||||
substs: rcvr_substs.clone()
|
||||
});
|
||||
// It is illegal to invoke a method on a trait instance that
|
||||
// refers to the `Self` type. An error will be reported by
|
||||
// `enforce_object_limitations()` if the method refers to the
|
||||
// `Self` type anywhere other than the receiver. 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 = principal.substs.with_self_ty(self_ty);
|
||||
let trait_ref = Rc::new(TraitRef { def_id: principal.def_id,
|
||||
substs: rcvr_substs.clone() });
|
||||
|
||||
self.push_inherent_candidates_from_bounds_inner(
|
||||
&[trait_ref.clone()],
|
||||
@ -796,7 +795,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
|
||||
method_ty: m,
|
||||
origin: MethodTraitObject(MethodObject {
|
||||
trait_ref: new_trait_ref,
|
||||
object_trait_id: did,
|
||||
object_trait_id: principal.def_id,
|
||||
method_num: method_num,
|
||||
real_index: vtable_index
|
||||
})
|
||||
@ -1151,17 +1150,19 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
|
||||
fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodResult> {
|
||||
debug!("auto_slice_trait");
|
||||
match ty::get(ty).sty {
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: trt_did,
|
||||
substs: ref trt_substs,
|
||||
bounds: b,
|
||||
.. }) => {
|
||||
ty_trait(box ty::TyTrait { ref principal,
|
||||
bounds: b,
|
||||
.. }) => {
|
||||
let trt_did = principal.def_id;
|
||||
let trt_substs = &principal.substs;
|
||||
let tcx = self.tcx();
|
||||
self.search_for_some_kind_of_autorefd_method(
|
||||
|r, m| AutoPtr(r, m, None),
|
||||
autoderefs, [MutImmutable, MutMutable],
|
||||
|m, r| {
|
||||
let tr = ty::mk_trait(tcx, trt_did, trt_substs.clone(), b);
|
||||
let principal = ty::TraitRef::new(trt_did,
|
||||
trt_substs.clone());
|
||||
let tr = ty::mk_trait(tcx, principal, b);
|
||||
ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
|
||||
})
|
||||
}
|
||||
|
@ -140,11 +140,11 @@ pub fn check_object_safety(tcx: &ty::ctxt, object_trait: &ty::TyTrait, span: Spa
|
||||
// `call_once` which is the method which takes self by value. What could go
|
||||
// wrong?
|
||||
match tcx.lang_items.fn_once_trait() {
|
||||
Some(def_id) if def_id == object_trait.def_id => return,
|
||||
Some(def_id) if def_id == object_trait.principal.def_id => return,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let trait_items = ty::trait_items(tcx, object_trait.def_id);
|
||||
let trait_items = ty::trait_items(tcx, object_trait.principal.def_id);
|
||||
|
||||
let mut errors = Vec::new();
|
||||
for item in trait_items.iter() {
|
||||
@ -158,7 +158,7 @@ pub fn check_object_safety(tcx: &ty::ctxt, object_trait: &ty::TyTrait, span: Spa
|
||||
|
||||
let mut errors = errors.iter().flat_map(|x| x.iter()).peekable();
|
||||
if errors.peek().is_some() {
|
||||
let trait_name = ty::item_path_str(tcx, object_trait.def_id);
|
||||
let trait_name = ty::item_path_str(tcx, object_trait.principal.def_id);
|
||||
span_err!(tcx.sess, span, E0038,
|
||||
"cannot convert to a trait object because trait `{}` is not object-safe",
|
||||
trait_name);
|
||||
@ -241,8 +241,7 @@ pub fn register_object_cast_obligations(fcx: &FnCtxt,
|
||||
// needs some refactoring so there is a more convenient type to pass around.
|
||||
let object_trait_ty =
|
||||
ty::mk_trait(fcx.tcx(),
|
||||
object_trait.def_id,
|
||||
object_trait.substs.clone(),
|
||||
object_trait.principal.clone(),
|
||||
object_trait.bounds);
|
||||
|
||||
debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
|
||||
@ -252,13 +251,13 @@ pub fn register_object_cast_obligations(fcx: &FnCtxt,
|
||||
// Take the type parameters from the object type, but set
|
||||
// the Self type (which is unknown, for the object type)
|
||||
// to be the type we are casting from.
|
||||
let mut object_substs = object_trait.substs.clone();
|
||||
let mut object_substs = object_trait.principal.substs.clone();
|
||||
assert!(object_substs.self_ty().is_none());
|
||||
object_substs.types.push(SelfSpace, referent_ty);
|
||||
|
||||
// Create the obligation for casting from T to Trait.
|
||||
let object_trait_ref =
|
||||
Rc::new(ty::TraitRef { def_id: object_trait.def_id,
|
||||
Rc::new(ty::TraitRef { def_id: object_trait.principal.def_id,
|
||||
substs: object_substs });
|
||||
let object_obligation =
|
||||
Obligation::new(
|
||||
|
@ -112,8 +112,8 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
|
||||
ty_rptr(_, ty::mt {ty, ..}) |
|
||||
ty_uniq(ty) => {
|
||||
match ty::get(ty).sty {
|
||||
ty_trait(box ty::TyTrait { def_id, .. }) => {
|
||||
Some(def_id)
|
||||
ty_trait(box ty::TyTrait { ref principal, .. }) => {
|
||||
Some(principal.def_id)
|
||||
}
|
||||
_ => {
|
||||
panic!("get_base_type() returned a type that wasn't an \
|
||||
@ -121,8 +121,8 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_trait(box ty::TyTrait { def_id, .. }) => {
|
||||
Some(def_id)
|
||||
ty_trait(box ty::TyTrait { ref principal, .. }) => {
|
||||
Some(principal.def_id)
|
||||
}
|
||||
_ => {
|
||||
panic!("get_base_type() returned a type that wasn't an \
|
||||
|
@ -18,6 +18,7 @@ use middle::ty;
|
||||
use syntax::ast::{Item, ItemImpl};
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::visit;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
@ -30,6 +31,17 @@ struct OrphanChecker<'cx, 'tcx:'cx> {
|
||||
tcx: &'cx ty::ctxt<'tcx>
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
|
||||
fn check_def_id(&self, span: Span, def_id: ast::DefId) {
|
||||
if def_id.krate != ast::LOCAL_CRATE {
|
||||
span_err!(self.tcx.sess, span, E0116,
|
||||
"cannot associate methods with a type outside the \
|
||||
crate the type is defined in; define and implement \
|
||||
a trait or new type instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
||||
fn visit_item(&mut self, item: &'v ast::Item) {
|
||||
let def_id = ast_util::local_def(item.id);
|
||||
@ -41,14 +53,11 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
||||
let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
|
||||
match ty::get(self_ty).sty {
|
||||
ty::ty_enum(def_id, _) |
|
||||
ty::ty_struct(def_id, _) |
|
||||
ty::ty_trait(box ty::TyTrait{ def_id, ..}) => {
|
||||
if def_id.krate != ast::LOCAL_CRATE {
|
||||
span_err!(self.tcx.sess, item.span, E0116,
|
||||
"cannot associate methods with a type outside the \
|
||||
crate the type is defined in; define and implement \
|
||||
a trait or new type instead");
|
||||
}
|
||||
ty::ty_struct(def_id, _) => {
|
||||
self.check_def_id(item.span, def_id);
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait{ ref principal, ..}) => {
|
||||
self.check_def_id(item.span, principal.def_id);
|
||||
}
|
||||
_ => {
|
||||
span_err!(self.tcx.sess, item.span, E0118,
|
||||
|
@ -1335,13 +1335,13 @@ pub fn instantiate_trait_ref<'tcx,AC>(this: &AC,
|
||||
ast_trait_ref.ref_id) {
|
||||
def::DefTrait(trait_did) => {
|
||||
let trait_ref =
|
||||
astconv::ast_path_to_trait_ref(this,
|
||||
&rscope,
|
||||
trait_did,
|
||||
Some(self_ty),
|
||||
associated_type,
|
||||
&ast_trait_ref.path,
|
||||
ast_trait_ref.ref_id);
|
||||
Rc::new(astconv::ast_path_to_trait_ref(this,
|
||||
&rscope,
|
||||
trait_did,
|
||||
Some(self_ty),
|
||||
associated_type,
|
||||
&ast_trait_ref.path,
|
||||
ast_trait_ref.ref_id));
|
||||
|
||||
this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
|
||||
trait_ref.clone());
|
||||
|
@ -413,15 +413,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
let ty = ty::mk_vec(tcx, t_a, None);
|
||||
Some((ty, ty::UnsizeLength(len)))
|
||||
}
|
||||
(&ty::ty_trait(..), &ty::ty_trait(..)) => None,
|
||||
(_, &ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds })) => {
|
||||
let ty = ty::mk_trait(tcx,
|
||||
def_id,
|
||||
substs.clone(),
|
||||
bounds);
|
||||
Some((ty, ty::UnsizeVtable(ty::TyTrait { def_id: def_id,
|
||||
bounds: bounds,
|
||||
substs: substs.clone() },
|
||||
(&ty::ty_trait(..), &ty::ty_trait(..)) => {
|
||||
None
|
||||
}
|
||||
(_, &ty::ty_trait(box ty::TyTrait { ref principal, bounds })) => {
|
||||
// FIXME what is the purpose of `ty`?
|
||||
let ty = ty::mk_trait(tcx, (*principal).clone(), bounds);
|
||||
Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: (*principal).clone(),
|
||||
bounds: bounds },
|
||||
ty_a)))
|
||||
}
|
||||
(&ty::ty_struct(did_a, ref substs_a), &ty::ty_struct(did_b, ref substs_b))
|
||||
@ -524,16 +523,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
match *sty_a {
|
||||
ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty::get(ty).sty {
|
||||
ty::ty_trait(box ty::TyTrait {
|
||||
def_id,
|
||||
ref substs,
|
||||
bounds,
|
||||
..
|
||||
}) =>
|
||||
{
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
|
||||
|
||||
let tr = ty::mk_trait(tcx, def_id, substs.clone(), bounds);
|
||||
// FIXME what is purpose of this type `tr`?
|
||||
let tr = ty::mk_trait(tcx, (*principal).clone(), bounds);
|
||||
try!(self.subtype(mk_ty(tr), b));
|
||||
Ok(Some(AdjustDerefRef(AutoDerefRef {
|
||||
autoderefs: 1,
|
||||
|
@ -461,15 +461,11 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t
|
||||
}
|
||||
|
||||
(&ty::ty_trait(ref a_),
|
||||
&ty::ty_trait(ref b_))
|
||||
if a_.def_id == b_.def_id => {
|
||||
&ty::ty_trait(ref b_)) => {
|
||||
debug!("Trying to match traits {} and {}", a, b);
|
||||
let substs = try!(this.substs(a_.def_id, &a_.substs, &b_.substs));
|
||||
let principal = try!(this.trait_refs(&a_.principal, &b_.principal));
|
||||
let bounds = try!(this.existential_bounds(a_.bounds, b_.bounds));
|
||||
Ok(ty::mk_trait(tcx,
|
||||
a_.def_id,
|
||||
substs.clone(),
|
||||
bounds))
|
||||
Ok(ty::mk_trait(tcx, principal, bounds))
|
||||
}
|
||||
|
||||
(&ty::ty_struct(a_id, ref a_substs), &ty::ty_struct(b_id, ref b_substs))
|
||||
|
@ -856,16 +856,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
-> ty::TraitRef {
|
||||
// make up a dummy type just to reuse/abuse the resolve machinery
|
||||
let dummy0 = ty::mk_trait(self.tcx,
|
||||
trait_ref.def_id,
|
||||
trait_ref.substs.clone(),
|
||||
(*trait_ref).clone(),
|
||||
ty::region_existential_bound(ty::ReStatic));
|
||||
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
|
||||
match ty::get(dummy1).sty {
|
||||
ty::ty_trait(box ty::TyTrait { ref def_id, ref substs, .. }) => {
|
||||
ty::TraitRef {
|
||||
def_id: *def_id,
|
||||
substs: (*substs).clone(),
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, .. }) => {
|
||||
(*principal).clone()
|
||||
}
|
||||
_ => {
|
||||
self.tcx.sess.bug(
|
||||
|
@ -778,14 +778,14 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
variance);
|
||||
}
|
||||
|
||||
ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
|
||||
let trait_def = ty::lookup_trait_def(self.tcx(), def_id);
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
|
||||
let trait_def = ty::lookup_trait_def(self.tcx(), principal.def_id);
|
||||
let generics = &trait_def.generics;
|
||||
|
||||
// Traits DO have a Self type parameter, but it is
|
||||
// erased from object types.
|
||||
assert!(!generics.types.is_empty_in(subst::SelfSpace) &&
|
||||
substs.types.is_empty_in(subst::SelfSpace));
|
||||
principal.substs.types.is_empty_in(subst::SelfSpace));
|
||||
|
||||
// Traits never declare region parameters in the self
|
||||
// space.
|
||||
@ -801,10 +801,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_region(bounds.region_bound, contra);
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
def_id,
|
||||
principal.def_id,
|
||||
generics.types.get_slice(subst::TypeSpace),
|
||||
generics.regions.get_slice(subst::TypeSpace),
|
||||
substs,
|
||||
&principal.substs,
|
||||
variance);
|
||||
}
|
||||
|
||||
|
@ -435,12 +435,12 @@ pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
|
||||
parameterized(cx, base.as_slice(), substs, &generics)
|
||||
}
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: did, ref substs, ref bounds
|
||||
ref principal, ref bounds
|
||||
}) => {
|
||||
let base = ty::item_path_str(cx, did);
|
||||
let trait_def = ty::lookup_trait_def(cx, did);
|
||||
let base = ty::item_path_str(cx, principal.def_id);
|
||||
let trait_def = ty::lookup_trait_def(cx, principal.def_id);
|
||||
let ty = parameterized(cx, base.as_slice(),
|
||||
substs, &trait_def.generics);
|
||||
&principal.substs, &trait_def.generics);
|
||||
let bound_str = bounds.user_string(cx);
|
||||
let bound_sep = if bound_str.is_empty() { "" } else { "+" };
|
||||
format!("{}{}{}",
|
||||
|
Loading…
x
Reference in New Issue
Block a user