Skip to content

Commit

Permalink
Merge remote branch 'nmatsakis/issue-4808-representation-of-extern-fn…
Browse files Browse the repository at this point in the history
…' into incoming
  • Loading branch information
pcwalton committed Mar 1, 2013
2 parents 9519ee5 + febdb49 commit 02a4b5b
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 128 deletions.
14 changes: 11 additions & 3 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,17 @@ impl tr for ast::def {

impl tr for ty::AutoAdjustment {
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
ty::AutoAdjustment {
autoderefs: self.autoderefs,
autoref: self.autoref.map(|ar| ar.tr(xcx)),
match self {
&ty::AutoAddEnv(r, s) => {
ty::AutoAddEnv(r.tr(xcx), s)
}

&ty::AutoDerefRef(ref adr) => {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adr.autoderefs,
autoref: adr.autoref.map(|ar| ar.tr(xcx)),
})
}
}
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/librustc/middle/borrowck/gather_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,27 @@ pub impl GatherLoanCtxt {
expr_repr(self.tcx(), expr), adjustment);
let _i = indenter();

match adjustment.autoref {
None => {
match *adjustment {
ty::AutoAddEnv(*) => {
debug!("autoaddenv -- no autoref");
return;
}

ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, _ }) => {
debug!("no autoref");
return;
}

Some(ref autoref) => {
ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(ref autoref),
autoderefs: autoderefs}) => {
let mcx = &mem_categorization_ctxt {
tcx: self.tcx(),
method_map: self.bccx.method_map};
let mut cmt = mcx.cat_expr_autoderefd(expr, adjustment);
let mut cmt = mcx.cat_expr_autoderefd(expr, autoderefs);
debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt));

match autoref.kind {
Expand Down
17 changes: 14 additions & 3 deletions src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,20 @@ pub impl BorrowckCtxt {
}

fn cat_expr_autoderefd(&self, expr: @ast::expr,
adj: @ty::AutoAdjustment)
-> cmt {
cat_expr_autoderefd(self.tcx, self.method_map, expr, adj)
adj: @ty::AutoAdjustment) -> cmt {
match *adj {
ty::AutoAddEnv(*) => {
// no autoderefs
cat_expr_unadjusted(self.tcx, self.method_map, expr)
}

ty::AutoDerefRef(
ty::AutoDerefRef {
autoderefs: autoderefs, _}) => {
cat_expr_autoderefd(self.tcx, self.method_map, expr,
autoderefs)
}
}
}

fn cat_def(&self,
Expand Down
46 changes: 28 additions & 18 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,12 @@ pub fn cat_expr_autoderefd(
tcx: ty::ctxt,
method_map: typeck::method_map,
expr: @ast::expr,
adj: @ty::AutoAdjustment) -> cmt {

autoderefs: uint) -> cmt
{
let mcx = &mem_categorization_ctxt {
tcx: tcx, method_map: method_map
};
return mcx.cat_expr_autoderefd(expr, adj);
return mcx.cat_expr_autoderefd(expr, autoderefs);
}

pub fn cat_def(
Expand Down Expand Up @@ -361,28 +361,38 @@ pub impl mem_categorization_ctxt {
self.cat_expr_unadjusted(expr)
}

Some(adjustment) => {
match adjustment.autoref {
Some(_) => {
// Equivalent to &*expr or something similar.
// This is an rvalue, effectively.
let expr_ty = ty::expr_ty(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}
None => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, adjustment)
}
}
Some(@ty::AutoAddEnv(*)) => {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}

Some(
@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), _})) => {
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}

Some(
@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, autoderefs: autoderefs})) => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, autoderefs)
}
}
}

fn cat_expr_autoderefd(&self,
expr: @ast::expr,
adjustment: &ty::AutoAdjustment) -> cmt {
autoderefs: uint) -> cmt {
let mut cmt = self.cat_expr_unadjusted(expr);
for uint::range(1, adjustment.autoderefs+1) |deref| {
for uint::range(1, autoderefs+1) |deref| {
cmt = self.cat_deref(expr, cmt, deref);
}
return cmt;
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,9 @@ pub impl VisitContext {
// those adjustments is to take a reference, then it's only
// reading the underlying expression, not moving it.
let comp_mode = match self.tcx.adjustments.find(&expr.id) {
Some(adj) if adj.autoref.is_some() => Read,
Some(@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), _})) => Read,
_ => expr_mode.component_mode(expr)
};

Expand Down
28 changes: 22 additions & 6 deletions src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,25 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
}

// any other expressions are closures:
return closure_callee(&expr::trans_to_datum(bcx, expr));

fn closure_callee(db: &DatumBlock) -> Callee {
return Callee {bcx: db.bcx, data: Closure(db.datum)};
return datum_callee(bcx, expr);

fn datum_callee(bcx: block, expr: @ast::expr) -> Callee {
let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
match ty::get(datum.ty).sty {
ty::ty_bare_fn(*) => {
let llval = datum.to_appropriate_llval(bcx);
return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
}
ty::ty_closure(*) => {
return Callee {bcx: bcx, data: Closure(datum)};
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
fmt!("Type of callee is neither bare-fn nor closure: %s",
bcx.ty_to_str(datum.ty)));
}
}
}

fn fn_callee(bcx: block, fd: FnData) -> Callee {
Expand Down Expand Up @@ -129,7 +144,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
ast::def_binding(*) |
ast::def_upvar(*) |
ast::def_self(*) => {
closure_callee(&expr::trans_to_datum(bcx, ref_expr))
datum_callee(bcx, ref_expr)
}
ast::def_mod(*) | ast::def_foreign_mod(*) |
ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
Expand Down Expand Up @@ -392,7 +407,6 @@ pub fn trans_lang_call_with_type_params(bcx: block,
fty);
let mut llfnty = type_of::type_of(callee.bcx.ccx(),
substituted);
llfnty = lib::llvm::struct_tys(llfnty)[0];
new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
}
_ => fail!()
Expand Down Expand Up @@ -715,6 +729,8 @@ pub fn trans_arg_expr(bcx: block,
}

ast::by_copy => {
debug!("by copy arg with type %s, storing to scratch",
ty_to_str(ccx.tcx, arg_datum.ty));
let scratch = scratch_datum(bcx, arg_datum.ty, false);

arg_datum.store_to_datum(bcx, arg_expr.id,
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,12 @@ pub fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
node_id_type(bcx, ex.id)
}

pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t {
let tcx = bcx.tcx();
let t = ty::expr_ty_adjusted(tcx, ex);
monomorphize_type(bcx, t)
}

pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
let tcx = bcx.tcx();
let params = ty::node_id_to_type_params(tcx, id);
Expand Down
Loading

0 comments on commit 02a4b5b

Please sign in to comment.