Skip to content
New issue

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

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

Already on GitHub? # to your account

Monomorphic trait coercion #5597

Closed
Closed
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: 10 additions & 0 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ pub fn parse_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
parse_ty(st, conv)
}

pub fn parse_substs_data(data: @~[u8],
crate_num: int,
pos: uint,
tcx: ty::ctxt,
conv: conv_did)
-> ty::substs {
let st = parse_state_from_data(data, crate_num, pos, tcx);
parse_substs(st, conv)
}

pub fn parse_arg_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
conv: conv_did) -> ty::arg {
let st = parse_state_from_data(data, crate_num, pos, tcx);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ fn enc_opt<T>(w: @io::Writer, t: Option<T>, enc_f: &fn(T)) {
}
}

fn enc_substs(w: @io::Writer, cx: @ctxt, substs: ty::substs) {
pub fn enc_substs(w: @io::Writer, cx: @ctxt, substs: ty::substs) {
do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) }
do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) }
w.write_char('[');
Expand Down
190 changes: 177 additions & 13 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,18 +443,25 @@ impl tr for ast::def {
// ______________________________________________________________________
// Encoding and decoding of adjustment information

impl tr for ty::AutoAdjustment {
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
match self {
&ty::AutoAddEnv(r, s) => {
ty::AutoAddEnv(r.tr(xcx), s)
impl tr for ty::SigilAndRegion {
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::SigilAndRegion {
match *self {
ty::BorrowedSigilAndRegion(ref region) => {
ty::BorrowedSigilAndRegion(region.tr(xcx))
}
ty::OwnedSigilAndRegion => ty::OwnedSigilAndRegion,
ty::ManagedSigilAndRegion => ty::ManagedSigilAndRegion,
}
}
}

&ty::AutoDerefRef(ref adr) => {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adr.autoderefs,
autoref: adr.autoref.map(|ar| ar.tr(xcx)),
})
impl tr for ty::AutoDerefRef {
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoDerefRef {
ty::AutoDerefRef {
autoderefs: self.autoderefs,
autoref: match self.autoref {
None => None,
Some(ref autoref) => Some(autoref.tr(xcx)),
}
}
}
Expand Down Expand Up @@ -782,6 +789,10 @@ trait ebml_writer_helpers {
fn emit_bounds(&self, ecx: @e::EncodeContext, bs: ty::param_bounds);
fn emit_tpbt(&self, ecx: @e::EncodeContext,
tpbt: ty::ty_param_bounds_and_ty);
fn emit_substs(&self, ecx: @e::EncodeContext, substs: &ty::substs);
fn emit_auto_adjustment(&self,
ecx: @e::EncodeContext,
adj: ty::AutoAdjustment);
}

impl ebml_writer_helpers for writer::Encoder {
Expand Down Expand Up @@ -831,6 +842,51 @@ impl ebml_writer_helpers for writer::Encoder {
}
}
}

fn emit_substs(&self, ecx: @e::EncodeContext, substs: &ty::substs) {
do self.emit_opaque {
tyencode::enc_substs(self.writer, ecx.ty_str_ctxt(), *substs)
}
}

fn emit_auto_adjustment(&self,
ecx: @e::EncodeContext,
adj: ty::AutoAdjustment) {
do self.emit_enum(~"AutoAdjustment") {
match adj {
ty::AutoAddEnv(region, sigil) => {
do self.emit_enum_variant(~"AutoAddEnv", 0, 2) {
do self.emit_enum_variant_arg(0) {
region.encode(self);
}
do self.emit_enum_variant_arg(1) {
sigil.encode(self);
}
}
}
ty::AutoDerefRef(ref auto_deref_ref) => {
do self.emit_enum_variant(~"AutoDerefRef", 1, 1) {
do self.emit_enum_variant_arg(0) {
auto_deref_ref.encode(self);
}
}
}
ty::AutoObject(ref sigil_and_region, def_id, ref substs) => {
do self.emit_enum_variant(~"AutoObject", 2, 3) {
do self.emit_enum_variant_arg(0) {
sigil_and_region.encode(self);
}
do self.emit_enum_variant_arg(1) {
def_id.encode(self);
}
do self.emit_enum_variant_arg(2) {
self.emit_substs(ecx, substs);
}
}
}
}
}
}
}

trait write_tag_and_id {
Expand Down Expand Up @@ -985,7 +1041,7 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext,
do ebml_w.tag(c::tag_table_adjustments) {
ebml_w.id(id);
do ebml_w.tag(c::tag_table_val) {
(**adj).encode(&ebml_w)
ebml_w.emit_auto_adjustment(ecx, ***adj);
}
}
}
Expand Down Expand Up @@ -1027,6 +1083,9 @@ trait ebml_decoder_decoder_helpers {
fn read_bounds(&self, xcx: @ExtendedDecodeContext) -> @~[ty::param_bound];
fn read_ty_param_bounds_and_ty(&self, xcx: @ExtendedDecodeContext)
-> ty::ty_param_bounds_and_ty;
fn read_substs(&self, xcx: @ExtendedDecodeContext) -> ty::substs;
fn read_auto_adjustment(&self, xcx: @ExtendedDecodeContext)
-> ty::AutoAdjustment;
fn convert_def_id(&self, xcx: @ExtendedDecodeContext,
source: DefIdSource,
did: ast::def_id) -> ast::def_id;
Expand Down Expand Up @@ -1099,6 +1158,111 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
}
}

fn read_substs(&self, xcx: @ExtendedDecodeContext) -> ty::substs {
do self.read_opaque |doc| {
tydecode::parse_substs_data(doc.data,
xcx.dcx.cdata.cnum,
doc.start,
xcx.dcx.tcx,
|s, a| self.convert_def_id(xcx, s, a))
}
}

#[cfg(stage0)]
fn read_auto_adjustment(&self, xcx: @ExtendedDecodeContext)
-> ty::AutoAdjustment {
do self.read_enum("AutoAdjustment") {
do self.read_enum_variant |i| {
match i {
0 => {
let region: ty::Region =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
let sigil: ast::Sigil =
do self.read_enum_variant_arg(1) {
Decodable::decode(self)
};
ty::AutoAddEnv(region.tr(xcx), sigil)
}
1 => {
let auto_deref_ref: ty::AutoDerefRef =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
ty::AutoDerefRef(auto_deref_ref.tr(xcx))
}
2 => {
let sigil_and_region: ty::SigilAndRegion =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
let def_id: ast::def_id =
do self.read_enum_variant_arg(1) {
Decodable::decode(self)
};
let substs: ty::substs =
do self.read_enum_variant_arg(2) {
self.read_substs(xcx)
};
ty::AutoObject(sigil_and_region.tr(xcx),
def_id,
substs)
}
_ => fail!(~"bad enum variant")
}
}
}
}

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn read_auto_adjustment(&self, xcx: @ExtendedDecodeContext)
-> ty::AutoAdjustment {
do self.read_enum("AutoAdjustment") {
static variants: [ &'static str, ..3 ] =
[ "AutoAddEnv", "AutoDerefRef", "AutoObject" ];
do self.read_enum_variant(variants) |i| {
match i {
0 => {
let region: ty::Region =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
let sigil: ast::Sigil =
do self.read_enum_variant_arg(1) {
Decodable::decode(self)
};
ty::AutoAddEnv(region.tr(xcx), sigil)
}
1 => {
let auto_deref_ref: ty::AutoDerefRef =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
ty::AutoDerefRef(auto_deref_ref.tr(xcx))
}
2 => {
let sigil_and_region: ty::SigilAndRegion =
do self.read_enum_variant_arg(0) {
Decodable::decode(self)
};
let def_id: ast::def_id =
do self.read_enum_variant_arg(1) {
Decodable::decode(self)
};
let substs = self.read_substs(xcx);
ty::AutoObject(sigil_and_region.tr(xcx),
def_id,
substs)
}
_ => fail!(~"bad enum variant")
}
}
}
}

fn convert_def_id(&self, xcx: @ExtendedDecodeContext,
source: tydecode::DefIdSource,
did: ast::def_id) -> ast::def_id {
Expand Down Expand Up @@ -1180,8 +1344,8 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
dcx.maps.vtable_map.insert(id,
val_dsr.read_vtable_res(xcx));
} else if tag == (c::tag_table_adjustments as uint) {
let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
adj.tr(xcx);
let adj: @ty::AutoAdjustment =
@val_dsr.read_auto_adjustment(xcx);
dcx.tcx.adjustments.insert(id, adj);
} else if tag == (c::tag_table_capture_map as uint) {
let cvars =
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/borrowck/gather_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,12 @@ pub impl GatherLoanCtxt {
return;
}

ty::AutoObject(*) => {
// NB: We need not do something now, but if this borrows
// `@Trait` to `&Trait` then this will need a guarantee.
return;
}

ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, _ }) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ pub impl BorrowckCtxt {
fn cat_expr_autoderefd(&self, expr: @ast::expr,
adj: @ty::AutoAdjustment) -> cmt {
match *adj {
ty::AutoAddEnv(*) => {
ty::AutoAddEnv(*) | ty::AutoObject(*) => {
// no autoderefs
cat_expr_unadjusted(self.tcx, self.method_map, expr)
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,12 @@ pub impl mem_categorization_ctxt {
self.cat_expr_unadjusted(expr)
}

Some(&@ty::AutoObject(*)) => {
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}

Some(&@ty::AutoAddEnv(*)) => {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
}
}
}
Some(&@ty::AutoObject(*)) => {
cx.sess.span_unimpl(e.span, ~"unimplemented const object");
}
}

let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
Expand Down
Loading