Skip to content

Commit dc5fced

Browse files
committed
---
yaml --- r: 49865 b: refs/heads/auto c: 2fef18a h: refs/heads/master i: 49863: 14fc9e5 v: v3
1 parent f49bc94 commit dc5fced

File tree

11 files changed

+289
-172
lines changed

11 files changed

+289
-172
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1414
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1515
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1616
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
17-
refs/heads/auto: 1e1efbf2c355c4ddb1356abe535d79525bad72ba
17+
refs/heads/auto: 2fef18abf2b6a9b3c336b1da5b8a08a22438ad4c
1818
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167

branches/auto/src/librustc/back/link.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -818,11 +818,7 @@ pub fn link_binary(sess: Session,
818818
do cstore::iter_crate_data(cstore) |crate_num, _| {
819819
let link_args = csearch::get_link_args_for_crate(cstore, crate_num);
820820
do vec::consume(link_args) |_, link_arg| {
821-
// Linker arguments that don't begin with - are likely file names,
822-
// so they should not be necessary.
823-
if link_arg.starts_with("-") {
824-
cc_args.push(link_arg);
825-
}
821+
cc_args.push(link_arg);
826822
}
827823
}
828824

branches/auto/src/librustc/middle/check_const.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ pub fn check_expr(sess: Session,
9191
v: visit::vt<bool>) {
9292
if is_const {
9393
match e.node {
94-
expr_unary(box(_), _) | expr_unary(uniq(_), _) |
95-
expr_unary(deref, _) => {
94+
expr_unary(deref, _) => { }
95+
expr_unary(box(_), _) | expr_unary(uniq(_), _) => {
9696
sess.span_err(e.span,
9797
~"disallowed operator in constant expression");
9898
return;

branches/auto/src/librustc/middle/trans/consts.rs

Lines changed: 112 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use core::prelude::*;
1212

13+
use back::abi;
1314
use lib::llvm::{llvm, ValueRef, TypeRef, Bool, True, False};
1415
use metadata::csearch;
1516
use middle::const_eval;
@@ -94,30 +95,56 @@ pub fn const_vec(cx: @CrateContext, e: @ast::expr, es: &[@ast::expr])
9495
}
9596
}
9697

97-
pub fn const_deref(cx: @CrateContext, v: ValueRef) -> ValueRef {
98+
fn const_addr_of(cx: @CrateContext, cv: ValueRef) -> ValueRef {
9899
unsafe {
99-
let v = match cx.const_globals.find(&(v as int)) {
100-
Some(v) => v,
101-
None => v
100+
let gv = do str::as_c_str("const") |name| {
101+
llvm::LLVMAddGlobal(cx.llmod, val_ty(cv), name)
102102
};
103+
llvm::LLVMSetInitializer(gv, cv);
104+
llvm::LLVMSetGlobalConstant(gv, True);
105+
gv
106+
}
107+
}
108+
109+
fn const_deref_ptr(cx: @CrateContext, v: ValueRef) -> ValueRef {
110+
let v = match cx.const_globals.find(&(v as int)) {
111+
Some(v) => v,
112+
None => v
113+
};
114+
unsafe {
103115
fail_unless!(llvm::LLVMIsGlobalConstant(v) == True);
104-
let v = llvm::LLVMGetInitializer(v);
105-
v
116+
llvm::LLVMGetInitializer(v)
106117
}
107118
}
108119

109-
pub fn const_autoderef(cx: @CrateContext, ty: ty::t, v: ValueRef)
110-
-> (ty::t, ValueRef) {
111-
let mut t1 = ty;
112-
let mut v1 = v;
113-
loop {
114-
// Only rptrs can be autoderef'ed in a const context.
115-
match ty::get(t1).sty {
116-
ty::ty_rptr(_, mt) => {
117-
t1 = mt.ty;
118-
v1 = const_deref(cx, v1);
119-
}
120-
_ => return (t1,v1)
120+
fn const_deref_newtype(cx: @CrateContext, v: ValueRef, t: ty::t)
121+
-> ValueRef {
122+
let repr = adt::represent_type(cx, t);
123+
adt::const_get_field(cx, repr, v, 0, 0)
124+
}
125+
126+
fn const_deref(cx: @CrateContext, v: ValueRef, t: ty::t, explicit: bool)
127+
-> (ValueRef, ty::t) {
128+
match ty::deref(cx.tcx, t, explicit) {
129+
Some(ref mt) => {
130+
fail_unless!(mt.mutbl != ast::m_mutbl);
131+
let dv = match ty::get(t).sty {
132+
ty::ty_ptr(*) | ty::ty_rptr(*) => {
133+
const_deref_ptr(cx, v)
134+
}
135+
ty::ty_enum(*) | ty::ty_struct(*) => {
136+
const_deref_newtype(cx, v, t)
137+
}
138+
_ => {
139+
cx.sess.bug(fmt!("Unexpected dereferenceable type %s",
140+
ty_to_str(cx.tcx, t)))
141+
}
142+
};
143+
(dv, mt.ty)
144+
}
145+
None => {
146+
cx.sess.bug(fmt!("Can't dereference const of type %s",
147+
ty_to_str(cx.tcx, t)))
121148
}
122149
}
123150
}
@@ -142,15 +169,68 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
142169
}
143170

144171
pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
145-
let ety = ty::expr_ty_adjusted(cx.tcx, e);
146-
let llty = type_of::sizing_type_of(cx, ety);
147-
let llconst = const_expr_unchecked(cx, e);
172+
let mut llconst = const_expr_unadjusted(cx, e);
173+
let ety = ty::expr_ty(cx.tcx, e);
174+
match cx.tcx.adjustments.find(&e.id) {
175+
None => { }
176+
Some(@ty::AutoAddEnv(ty::re_static, ast::BorrowedSigil)) => {
177+
llconst = C_struct(~[llconst, C_null(T_opaque_box_ptr(cx))])
178+
}
179+
Some(@ty::AutoAddEnv(ref r, ref s)) => {
180+
cx.sess.span_bug(e.span, fmt!("unexpected const function: \
181+
region %? sigil %?", *r, *s))
182+
}
183+
Some(@ty::AutoDerefRef(ref adj)) => {
184+
let mut ty = ety;
185+
let mut maybe_ptr = None;
186+
for adj.autoderefs.times {
187+
let (dv, dt) = const_deref(cx, llconst, ty, false);
188+
maybe_ptr = Some(llconst);
189+
llconst = dv;
190+
ty = dt;
191+
}
192+
193+
match adj.autoref {
194+
None => { }
195+
Some(ref autoref) => {
196+
fail_unless!(autoref.region == ty::re_static);
197+
fail_unless!(autoref.mutbl != ast::m_mutbl);
198+
// Don't copy data to do a deref+ref.
199+
let llptr = match maybe_ptr {
200+
Some(ptr) => ptr,
201+
None => const_addr_of(cx, llconst)
202+
};
203+
match autoref.kind {
204+
ty::AutoPtr => {
205+
llconst = llptr;
206+
}
207+
ty::AutoBorrowVec => {
208+
let size = machine::llsize_of(cx,
209+
val_ty(llconst));
210+
fail_unless!(abi::slice_elt_base == 0);
211+
fail_unless!(abi::slice_elt_len == 1);
212+
llconst = C_struct(~[llptr, size]);
213+
}
214+
_ => {
215+
cx.sess.span_bug(e.span,
216+
fmt!("unimplemented const \
217+
autoref %?", autoref))
218+
}
219+
}
220+
}
221+
}
222+
}
223+
}
224+
225+
let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
226+
let llty = type_of::sizing_type_of(cx, ety_adjusted);
148227
let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
149228
let tsize = machine::llsize_of_alloc(cx, llty);
150229
if csize != tsize {
151230
unsafe {
231+
// XXX these values could use some context
152232
llvm::LLVMDumpValue(llconst);
153-
llvm::LLVMDumpValue(C_null(llty));
233+
llvm::LLVMDumpValue(C_undef(llty));
154234
}
155235
cx.sess.bug(fmt!("const %s of type %s has size %u instead of %u",
156236
expr_repr(cx.tcx, e), ty_to_str(cx.tcx, ety),
@@ -159,7 +239,7 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
159239
llconst
160240
}
161241

162-
fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
242+
fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
163243
unsafe {
164244
let _icx = cx.insn_ctxt("const_expr");
165245
return match /*bad*/copy e.node {
@@ -223,7 +303,10 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
223303
return match u {
224304
ast::box(_) |
225305
ast::uniq(_) |
226-
ast::deref => const_deref(cx, te),
306+
ast::deref => {
307+
let (dv, _dt) = const_deref(cx, te, ty, true);
308+
dv
309+
}
227310
ast::not => {
228311
match ty::get(ty).sty {
229312
ty::ty_bool => {
@@ -243,20 +326,18 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
243326
}
244327
}
245328
ast::expr_field(base, field, _) => {
246-
let bt = ty::expr_ty(cx.tcx, base);
329+
let bt = ty::expr_ty_adjusted(cx.tcx, base);
247330
let brepr = adt::represent_type(cx, bt);
248331
let bv = const_expr(cx, base);
249-
let (bt, bv) = const_autoderef(cx, bt, bv);
250332
do expr::with_field_tys(cx.tcx, bt, None) |discr, field_tys| {
251333
let ix = ty::field_idx_strict(cx.tcx, field, field_tys);
252334
adt::const_get_field(cx, brepr, bv, discr, ix)
253335
}
254336
}
255337

256338
ast::expr_index(base, index) => {
257-
let bt = ty::expr_ty(cx.tcx, base);
339+
let bt = ty::expr_ty_adjusted(cx.tcx, base);
258340
let bv = const_expr(cx, base);
259-
let (bt, bv) = const_autoderef(cx, bt, bv);
260341
let iv = match const_eval::eval_const_expr(cx.tcx, index) {
261342
const_eval::const_int(i) => i as u64,
262343
const_eval::const_uint(u) => u,
@@ -275,7 +356,7 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
275356
let llunitty = type_of::type_of(cx, unit_ty);
276357
let unit_sz = machine::llsize_of(cx, llunitty);
277358

278-
(const_deref(cx, const_get_elt(cx, bv, [0])),
359+
(const_deref_ptr(cx, const_get_elt(cx, bv, [0])),
279360
llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
280361
unit_sz))
281362
},
@@ -355,13 +436,7 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
355436
}
356437
}
357438
ast::expr_addr_of(ast::m_imm, sub) => {
358-
let cv = const_expr(cx, sub);
359-
let gv = do str::as_c_str("const") |name| {
360-
llvm::LLVMAddGlobal(cx.llmod, val_ty(cv), name)
361-
};
362-
llvm::LLVMSetInitializer(gv, cv);
363-
llvm::LLVMSetGlobalConstant(gv, True);
364-
gv
439+
const_addr_of(cx, const_expr(cx, sub))
365440
}
366441
ast::expr_tup(es) => {
367442
let ety = ty::expr_ty(cx.tcx, e);
@@ -420,26 +495,12 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
420495
fail_unless!(pth.types.len() == 0);
421496
match cx.tcx.def_map.find(&e.id) {
422497
Some(ast::def_fn(def_id, _purity)) => {
423-
let f = if !ast_util::is_local(def_id) {
498+
if !ast_util::is_local(def_id) {
424499
let ty = csearch::get_type(cx.tcx, def_id).ty;
425500
base::trans_external_path(cx, def_id, ty)
426501
} else {
427502
fail_unless!(ast_util::is_local(def_id));
428503
base::get_item_val(cx, def_id.node)
429-
};
430-
let ety = ty::expr_ty_adjusted(cx.tcx, e);
431-
match ty::get(ety).sty {
432-
ty::ty_bare_fn(*) | ty::ty_ptr(*) => {
433-
llvm::LLVMConstPointerCast(f, T_ptr(T_i8()))
434-
}
435-
ty::ty_closure(*) => {
436-
C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
437-
}
438-
_ => {
439-
cx.sess.span_bug(e.span, fmt!(
440-
"unexpected const fn type: %s",
441-
ty_to_str(cx.tcx, ety)))
442-
}
443504
}
444505
}
445506
Some(ast::def_const(def_id)) => {

0 commit comments

Comments
 (0)