Skip to content

Commit b8ef74a

Browse files
author
Jakub Bukaj
committed
---
yaml --- r: 161078 b: refs/heads/try c: 655eb44 h: refs/heads/master v: v3
1 parent fd89bc2 commit b8ef74a

File tree

11 files changed

+160
-42
lines changed

11 files changed

+160
-42
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 4eb72d268f337a8f117c86a2ac1b98336cab9e9d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: c9f6d696420107f82304b992cf623b806995fe18
5-
refs/heads/try: b64c7b83dd08c7c3afc643564d65975d57785172
5+
refs/heads/try: 655eb44df3a7edd87d365f64cbfca061223c5232
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
88
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

branches/try/src/doc/reference.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,17 +3557,14 @@ The machine types are the following:
35573557

35583558
#### Machine-dependent integer types
35593559

3560-
The Rust type `uint` [^rustuint] is an
3561-
unsigned integer type with target-machine-dependent size. Its size, in
3562-
bits, is equal to the number of bits required to hold any memory address on
3563-
the target machine.
3564-
3565-
The Rust type `int` [^rustint] is a two's complement signed integer type with
3566-
target-machine-dependent size. Its size, in bits, is equal to the size of the
3567-
rust type `uint` on the same target machine.
3568-
3569-
[^rustuint]: A Rust `uint` is analogous to a C99 `uintptr_t`.
3570-
[^rustint]: A Rust `int` is analogous to a C99 `intptr_t`.
3560+
The `uint` type is an unsigned integer type with the same number of bits as the
3561+
platform's pointer type. It can represent every memory address in the process.
3562+
3563+
The `int` type is a signed integer type with the same number of bits as the
3564+
platform's pointer type. The theoretical upper bound on object and array size
3565+
is the maximum `int` value. This ensures that `int` can be used to calculate
3566+
differences between pointers into an object or array and can address every byte
3567+
within an object along with one byte past the end.
35713568

35723569
### Textual types
35733570

branches/try/src/librustc/middle/ty.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3396,14 +3396,6 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
33963396
}
33973397
}
33983398

3399-
pub fn deref_or_dont<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
3400-
match ty.sty {
3401-
ty_uniq(ty) => ty,
3402-
ty_rptr(_, mt) | ty_ptr(mt) => mt.ty,
3403-
_ => ty
3404-
}
3405-
}
3406-
34073399
pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
34083400
match ty.sty {
34093401
ty_open(ty) => mk_rptr(cx, ReStatic, mt {ty: ty, mutbl:ast::MutImmutable}),
@@ -5989,3 +5981,59 @@ impl DebruijnIndex {
59895981
DebruijnIndex { depth: self.depth + amount }
59905982
}
59915983
}
5984+
5985+
impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
5986+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
5987+
match *self {
5988+
AdjustAddEnv(ref trait_store) => {
5989+
format!("AdjustAddEnv({})", trait_store)
5990+
}
5991+
AdjustDerefRef(ref data) => {
5992+
data.repr(tcx)
5993+
}
5994+
}
5995+
}
5996+
}
5997+
5998+
impl<'tcx> Repr<'tcx> for UnsizeKind<'tcx> {
5999+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6000+
match *self {
6001+
UnsizeLength(n) => format!("UnsizeLength({})", n),
6002+
UnsizeStruct(ref k, n) => format!("UnsizeStruct({},{})", k.repr(tcx), n),
6003+
UnsizeVtable(ref a, ref b) => format!("UnsizeVtable({},{})", a.repr(tcx), b.repr(tcx)),
6004+
}
6005+
}
6006+
}
6007+
6008+
impl<'tcx> Repr<'tcx> for AutoDerefRef<'tcx> {
6009+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6010+
format!("AutoDerefRef({}, {})", self.autoderefs, self.autoref.repr(tcx))
6011+
}
6012+
}
6013+
6014+
impl<'tcx> Repr<'tcx> for AutoRef<'tcx> {
6015+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6016+
match *self {
6017+
AutoPtr(a, b, ref c) => {
6018+
format!("AutoPtr({},{},{})", a.repr(tcx), b, c.repr(tcx))
6019+
}
6020+
AutoUnsize(ref a) => {
6021+
format!("AutoUnsize({})", a.repr(tcx))
6022+
}
6023+
AutoUnsizeUniq(ref a) => {
6024+
format!("AutoUnsizeUniq({})", a.repr(tcx))
6025+
}
6026+
AutoUnsafe(ref a, ref b) => {
6027+
format!("AutoUnsafe({},{})", a, b.repr(tcx))
6028+
}
6029+
}
6030+
}
6031+
}
6032+
6033+
impl<'tcx> Repr<'tcx> for TyTrait<'tcx> {
6034+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6035+
format!("TyTrait({},{})",
6036+
self.principal.repr(tcx),
6037+
self.bounds.repr(tcx))
6038+
}
6039+
}

branches/try/src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17071707
node_id: ast::NodeId,
17081708
span: Span,
17091709
adj: ty::AutoAdjustment<'tcx>) {
1710-
debug!("write_adjustment(node_id={}, adj={})", node_id, adj);
1710+
debug!("write_adjustment(node_id={}, adj={})", node_id, adj.repr(self.tcx()));
17111711

17121712
if adj.is_identity() {
17131713
return;

branches/try/src/librustc_trans/trans/adt.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -475,17 +475,17 @@ fn ensure_struct_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
475475
scapegoat: Ty<'tcx>) {
476476
let mut offset = 0;
477477
for &llty in fields.iter() {
478-
// Invariant: offset < ccx.max_obj_size() <= 1<<61
478+
// Invariant: offset < ccx.obj_size_bound() <= 1<<61
479479
if !packed {
480480
let type_align = machine::llalign_of_min(ccx, llty);
481481
offset = roundup(offset, type_align);
482482
}
483-
// type_align is a power-of-2, so still offset < ccx.max_obj_size()
484-
// llsize_of_alloc(ccx, llty) is also less than ccx.max_obj_size()
483+
// type_align is a power-of-2, so still offset < ccx.obj_size_bound()
484+
// llsize_of_alloc(ccx, llty) is also less than ccx.obj_size_bound()
485485
// so the sum is less than 1<<62 (and therefore can't overflow).
486486
offset += machine::llsize_of_alloc(ccx, llty);
487487

488-
if offset >= ccx.max_obj_size() {
488+
if offset >= ccx.obj_size_bound() {
489489
ccx.report_overbig_object(scapegoat);
490490
}
491491
}
@@ -504,11 +504,11 @@ fn ensure_enum_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
504504
let discr_size = machine::llsize_of_alloc(ccx, ll_inttype(ccx, discr));
505505
let (field_size, field_align) = union_size_and_align(fields);
506506

507-
// field_align < 1<<32, discr_size <= 8, field_size < MAX_OBJ_SIZE <= 1<<61
507+
// field_align < 1<<32, discr_size <= 8, field_size < OBJ_SIZE_BOUND <= 1<<61
508508
// so the sum is less than 1<<62 (and can't overflow).
509509
let total_size = roundup(discr_size, field_align) + field_size;
510510

511-
if total_size >= ccx.max_obj_size() {
511+
if total_size >= ccx.obj_size_bound() {
512512
ccx.report_overbig_object(scapegoat);
513513
}
514514
}

branches/try/src/librustc_trans/trans/context.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,23 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
705705
&self.local.trait_cache
706706
}
707707

708-
pub fn max_obj_size(&self) -> u64 {
709-
1<<31 /* FIXME #18069: select based on architecture */
708+
/// Return exclusive upper bound on object size.
709+
///
710+
/// The theoretical maximum object size is defined as the maximum positive `int` value. This
711+
/// ensures that the `offset` semantics remain well-defined by allowing it to correctly index
712+
/// every address within an object along with one byte past the end, along with allowing `int`
713+
/// to store the difference between any two pointers into an object.
714+
///
715+
/// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer to
716+
/// represent object size in bits. It would need to be 1 << 61 to account for this, but is
717+
/// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
718+
/// address space on 64-bit ARMv8 and x86_64.
719+
pub fn obj_size_bound(&self) -> u64 {
720+
match self.sess().target.target.target_word_size[] {
721+
"32" => 1 << 31,
722+
"64" => 1 << 47,
723+
_ => unreachable!() // error handled by config::build_target_config
724+
}
710725
}
711726

712727
pub fn report_overbig_object(&self, obj: Ty<'tcx>) -> ! {

branches/try/src/librustc_trans/trans/expr.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
194194
}
195195
Some(adj) => { adj }
196196
};
197-
debug!("unadjusted datum for expr {}: {}",
198-
expr.id, datum.to_string(bcx.ccx()));
197+
debug!("unadjusted datum for expr {}: {}, adjustment={}",
198+
expr.repr(bcx.tcx()),
199+
datum.to_string(bcx.ccx()),
200+
adjustment.repr(bcx.tcx()));
199201
match adjustment {
200202
AdjustAddEnv(..) => {
201203
datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
@@ -265,9 +267,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
265267
&AutoPtr(_, _, ref a) | &AutoUnsafe(_, ref a) => {
266268
debug!(" AutoPtr");
267269
match a {
268-
&Some(box ref a) => datum = unpack_datum!(bcx,
269-
apply_autoref(a, bcx, expr, datum)),
270-
_ => {}
270+
&Some(box ref a) => {
271+
datum = unpack_datum!(bcx, apply_autoref(a, bcx, expr, datum));
272+
}
273+
&None => {}
271274
}
272275
unpack_datum!(bcx, ref_ptr(bcx, expr, datum))
273276
}
@@ -293,6 +296,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
293296
expr: &ast::Expr,
294297
datum: Datum<'tcx, Expr>)
295298
-> DatumBlock<'blk, 'tcx, Expr> {
299+
debug!("ref_ptr(expr={}, datum={})",
300+
expr.repr(bcx.tcx()),
301+
datum.to_string(bcx.ccx()));
302+
296303
if !ty::type_is_sized(bcx.tcx(), datum.ty) {
297304
debug!("Taking address of unsized type {}",
298305
bcx.ty_to_string(datum.ty));
@@ -307,34 +314,36 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
307314
// Retrieve the information we are losing (making dynamic) in an unsizing
308315
// adjustment.
309316
// When making a dtor, we need to do different things depending on the
310-
// ownership of the object.. mk_ty is a function for turning unsized_type
317+
// ownership of the object.. mk_ty is a function for turning `unadjusted_ty`
311318
// into a type to be destructed. If we want to end up with a Box pointer,
312319
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
313320
// borrowed reference then it should be T -> &T.
314321
fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
315322
kind: &ty::UnsizeKind<'tcx>,
316323
id: ast::NodeId,
317-
unsized_ty: Ty<'tcx>,
324+
unadjusted_ty: Ty<'tcx>,
318325
mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef {
326+
debug!("unsized_info(kind={}, id={}, unadjusted_ty={})",
327+
kind, id, unadjusted_ty.repr(bcx.tcx()));
319328
match kind {
320329
&ty::UnsizeLength(len) => C_uint(bcx.ccx(), len),
321-
&ty::UnsizeStruct(box ref k, tp_index) => match unsized_ty.sty {
330+
&ty::UnsizeStruct(box ref k, tp_index) => match unadjusted_ty.sty {
322331
ty::ty_struct(_, ref substs) => {
323332
let ty_substs = substs.types.get_slice(subst::TypeSpace);
324333
// The dtor for a field treats it like a value, so mk_ty
325334
// should just be the identity function.
326335
unsized_info(bcx, k, id, ty_substs[tp_index], |t| t)
327336
}
328337
_ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
329-
bcx.ty_to_string(unsized_ty)).as_slice())
338+
bcx.ty_to_string(unadjusted_ty)).as_slice())
330339
},
331340
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
332-
let substs = principal.substs.with_self_ty(unsized_ty).erase_regions();
341+
let substs = principal.substs.with_self_ty(unadjusted_ty).erase_regions();
333342
let trait_ref =
334343
Rc::new(ty::TraitRef { def_id: principal.def_id,
335344
substs: substs });
336345
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs);
337-
let box_ty = mk_ty(unsized_ty);
346+
let box_ty = mk_ty(unadjusted_ty);
338347
PointerCast(bcx,
339348
meth::get_vtable(bcx, box_ty, trait_ref),
340349
Type::vtable_ptr(bcx.ccx()))
@@ -350,7 +359,9 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
350359
let tcx = bcx.tcx();
351360
let datum_ty = datum.ty;
352361
let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
362+
debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx()));
353363
let dest_ty = ty::mk_open(tcx, unsized_ty);
364+
debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
354365
// Closures for extracting and manipulating the data and payload parts of
355366
// the fat pointer.
356367
let base = match k {
@@ -366,7 +377,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
366377
let info = |bcx, _val| unsized_info(bcx,
367378
k,
368379
expr.id,
369-
ty::deref_or_dont(datum_ty),
380+
datum_ty,
370381
|t| ty::mk_rptr(tcx,
371382
ty::ReStatic,
372383
ty::mt{

branches/try/src/librustc_trans/trans/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn ensure_array_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
3434
scapegoat: Ty<'tcx>) {
3535
let esz = machine::llsize_of_alloc(ccx, llet);
3636
match esz.checked_mul(size) {
37-
Some(n) if n < ccx.max_obj_size() => {}
37+
Some(n) if n < ccx.obj_size_bound() => {}
3838
_ => { ccx.report_overbig_object(scapegoat) }
3939
}
4040
}

branches/try/src/test/compile-fail/huge-enum.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
// FIXME: work properly with higher limits
1414

15+
#[cfg(target_word_size = "32")]
1516
fn main() {
1617
let big: Option<[u32, ..(1<<29)-1]> = None;
1718
}
19+
20+
#[cfg(target_word_size = "64")]
21+
fn main() {
22+
let big: Option<[u32, ..(1<<45)-1]> = None;
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::mem::size_of;
12+
13+
#[cfg(target_word_size = "32")]
14+
pub fn main() {
15+
assert_eq!(size_of::<[u8, ..(1 << 31) - 1]>(), (1 << 31) - 1);
16+
}
17+
18+
#[cfg(target_word_size = "64")]
19+
pub fn main() {
20+
assert_eq!(size_of::<[u8, ..(1 << 47) - 1]>(), (1 << 47) - 1);
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::io;
12+
13+
fn f(wr: &mut Writer) {
14+
wr.write_str("hello").ok().expect("failed");
15+
}
16+
17+
fn main() {
18+
let mut wr = box io::stdout() as Box<Writer + 'static>;
19+
f(&mut wr);
20+
}

0 commit comments

Comments
 (0)