Skip to content

Commit febdb49

Browse files
committed
Change bare functions so that they are represented by a single pointer.
The basic idea is that we add a new kind of adjustment, AutoAddEnv, that pads an extern fn into a closure by adding the extra NULL word. Then there are a few misc changes in trans to get the LLVM types to match up. Fixes #4808.
1 parent 85aaf39 commit febdb49

File tree

15 files changed

+311
-128
lines changed

15 files changed

+311
-128
lines changed

src/librustc/middle/astencode.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,17 @@ impl tr for ast::def {
451451
452452
impl tr for ty::AutoAdjustment {
453453
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
454-
ty::AutoAdjustment {
455-
autoderefs: self.autoderefs,
456-
autoref: self.autoref.map(|ar| ar.tr(xcx)),
454+
match self {
455+
&ty::AutoAddEnv(r, s) => {
456+
ty::AutoAddEnv(r.tr(xcx), s)
457+
}
458+
459+
&ty::AutoDerefRef(ref adr) => {
460+
ty::AutoDerefRef(ty::AutoDerefRef {
461+
autoderefs: adr.autoderefs,
462+
autoref: adr.autoref.map(|ar| ar.tr(xcx)),
463+
})
464+
}
457465
}
458466
}
459467
}

src/librustc/middle/borrowck/gather_loans.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -299,17 +299,27 @@ impl GatherLoanCtxt {
299299
expr_repr(self.tcx(), expr), adjustment);
300300
let _i = indenter();
301301

302-
match adjustment.autoref {
303-
None => {
302+
match *adjustment {
303+
ty::AutoAddEnv(*) => {
304+
debug!("autoaddenv -- no autoref");
305+
return;
306+
}
307+
308+
ty::AutoDerefRef(
309+
ty::AutoDerefRef {
310+
autoref: None, _ }) => {
304311
debug!("no autoref");
305312
return;
306313
}
307314

308-
Some(ref autoref) => {
315+
ty::AutoDerefRef(
316+
ty::AutoDerefRef {
317+
autoref: Some(ref autoref),
318+
autoderefs: autoderefs}) => {
309319
let mcx = &mem_categorization_ctxt {
310320
tcx: self.tcx(),
311321
method_map: self.bccx.method_map};
312-
let mut cmt = mcx.cat_expr_autoderefd(expr, adjustment);
322+
let mut cmt = mcx.cat_expr_autoderefd(expr, autoderefs);
313323
debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt));
314324

315325
match autoref.kind {

src/librustc/middle/borrowck/mod.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,20 @@ pub impl BorrowckCtxt {
478478
}
479479

480480
fn cat_expr_autoderefd(&self, expr: @ast::expr,
481-
adj: @ty::AutoAdjustment)
482-
-> cmt {
483-
cat_expr_autoderefd(self.tcx, self.method_map, expr, adj)
481+
adj: @ty::AutoAdjustment) -> cmt {
482+
match *adj {
483+
ty::AutoAddEnv(*) => {
484+
// no autoderefs
485+
cat_expr_unadjusted(self.tcx, self.method_map, expr)
486+
}
487+
488+
ty::AutoDerefRef(
489+
ty::AutoDerefRef {
490+
autoderefs: autoderefs, _}) => {
491+
cat_expr_autoderefd(self.tcx, self.method_map, expr,
492+
autoderefs)
493+
}
494+
}
484495
}
485496

486497
fn cat_def(&self,

src/librustc/middle/mem_categorization.rs

+28-18
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,12 @@ pub fn cat_expr_autoderefd(
241241
tcx: ty::ctxt,
242242
method_map: typeck::method_map,
243243
expr: @ast::expr,
244-
adj: @ty::AutoAdjustment) -> cmt {
245-
244+
autoderefs: uint) -> cmt
245+
{
246246
let mcx = &mem_categorization_ctxt {
247247
tcx: tcx, method_map: method_map
248248
};
249-
return mcx.cat_expr_autoderefd(expr, adj);
249+
return mcx.cat_expr_autoderefd(expr, autoderefs);
250250
}
251251

252252
pub fn cat_def(
@@ -361,28 +361,38 @@ pub impl mem_categorization_ctxt {
361361
self.cat_expr_unadjusted(expr)
362362
}
363363

364-
Some(adjustment) => {
365-
match adjustment.autoref {
366-
Some(_) => {
367-
// Equivalent to &*expr or something similar.
368-
// This is an rvalue, effectively.
369-
let expr_ty = ty::expr_ty(self.tcx, expr);
370-
self.cat_rvalue(expr, expr_ty)
371-
}
372-
None => {
373-
// Equivalent to *expr or something similar.
374-
self.cat_expr_autoderefd(expr, adjustment)
375-
}
376-
}
364+
Some(@ty::AutoAddEnv(*)) => {
365+
// Convert a bare fn to a closure by adding NULL env.
366+
// Result is an rvalue.
367+
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
368+
self.cat_rvalue(expr, expr_ty)
369+
}
370+
371+
Some(
372+
@ty::AutoDerefRef(
373+
ty::AutoDerefRef {
374+
autoref: Some(_), _})) => {
375+
// Equivalent to &*expr or something similar.
376+
// Result is an rvalue.
377+
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
378+
self.cat_rvalue(expr, expr_ty)
379+
}
380+
381+
Some(
382+
@ty::AutoDerefRef(
383+
ty::AutoDerefRef {
384+
autoref: None, autoderefs: autoderefs})) => {
385+
// Equivalent to *expr or something similar.
386+
self.cat_expr_autoderefd(expr, autoderefs)
377387
}
378388
}
379389
}
380390

381391
fn cat_expr_autoderefd(&self,
382392
expr: @ast::expr,
383-
adjustment: &ty::AutoAdjustment) -> cmt {
393+
autoderefs: uint) -> cmt {
384394
let mut cmt = self.cat_expr_unadjusted(expr);
385-
for uint::range(1, adjustment.autoderefs+1) |deref| {
395+
for uint::range(1, autoderefs+1) |deref| {
386396
cmt = self.cat_deref(expr, cmt, deref);
387397
}
388398
return cmt;

src/librustc/middle/moves.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ impl VisitContext {
410410
// those adjustments is to take a reference, then it's only
411411
// reading the underlying expression, not moving it.
412412
let comp_mode = match self.tcx.adjustments.find(&expr.id) {
413-
Some(adj) if adj.autoref.is_some() => Read,
413+
Some(@ty::AutoDerefRef(
414+
ty::AutoDerefRef {
415+
autoref: Some(_), _})) => Read,
414416
_ => expr_mode.component_mode(expr)
415417
};
416418

src/librustc/middle/trans/callee.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,25 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
8282
}
8383

8484
// any other expressions are closures:
85-
return closure_callee(&expr::trans_to_datum(bcx, expr));
86-
87-
fn closure_callee(db: &DatumBlock) -> Callee {
88-
return Callee {bcx: db.bcx, data: Closure(db.datum)};
85+
return datum_callee(bcx, expr);
86+
87+
fn datum_callee(bcx: block, expr: @ast::expr) -> Callee {
88+
let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
89+
match ty::get(datum.ty).sty {
90+
ty::ty_bare_fn(*) => {
91+
let llval = datum.to_appropriate_llval(bcx);
92+
return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
93+
}
94+
ty::ty_closure(*) => {
95+
return Callee {bcx: bcx, data: Closure(datum)};
96+
}
97+
_ => {
98+
bcx.tcx().sess.span_bug(
99+
expr.span,
100+
fmt!("Type of callee is neither bare-fn nor closure: %s",
101+
bcx.ty_to_str(datum.ty)));
102+
}
103+
}
89104
}
90105

91106
fn fn_callee(bcx: block, fd: FnData) -> Callee {
@@ -117,7 +132,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
117132
ast::def_binding(*) |
118133
ast::def_upvar(*) |
119134
ast::def_self(*) => {
120-
closure_callee(&expr::trans_to_datum(bcx, ref_expr))
135+
datum_callee(bcx, ref_expr)
121136
}
122137
ast::def_mod(*) | ast::def_foreign_mod(*) |
123138
ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
@@ -380,7 +395,6 @@ pub fn trans_rtcall_or_lang_call_with_type_params(bcx: block,
380395
fty);
381396
let mut llfnty = type_of::type_of(callee.bcx.ccx(),
382397
substituted);
383-
llfnty = lib::llvm::struct_tys(llfnty)[0];
384398
new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
385399
}
386400
_ => fail!()
@@ -703,6 +717,8 @@ pub fn trans_arg_expr(bcx: block,
703717
}
704718

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

708724
arg_datum.store_to_datum(bcx, arg_expr.id,

src/librustc/middle/trans/common.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,12 @@ pub fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
13441344
node_id_type(bcx, ex.id)
13451345
}
13461346
1347+
pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t {
1348+
let tcx = bcx.tcx();
1349+
let t = ty::expr_ty_adjusted(tcx, ex);
1350+
monomorphize_type(bcx, t)
1351+
}
1352+
13471353
pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
13481354
let tcx = bcx.tcx();
13491355
let params = ty::node_id_to_type_params(tcx, id);

0 commit comments

Comments
 (0)