Skip to content

Commit 3e62637

Browse files
committed
DST coercions and DST structs
[breaking-change] 1. The internal layout for traits has changed from (vtable, data) to (data, vtable). If you were relying on this in unsafe transmutes, you might get some very weird and apparently unrelated errors. You should not be doing this! Prefer not to do this at all, but if you must, you should use raw::TraitObject rather than hardcoding rustc's internal representation into your code. 2. The minimal type of reference-to-vec-literals (e.g., `&[1, 2, 3]`) is now a fixed size vec (e.g., `&[int, ..3]`) where it used to be an unsized vec (e.g., `&[int]`). If you want the unszied type, you must explicitly give the type (e.g., `let x: &[_] = &[1, 2, 3]`). Note in particular where multiple blocks must have the same type (e.g., if and else clauses, vec elements), the compiler will not coerce to the unsized type without a hint. E.g., `[&[1], &[1, 2]]` used to be a valid expression of type '[&[int]]'. It no longer type checks since the first element now has type `&[int, ..1]` and the second has type &[int, ..2]` which are incompatible. 3. The type of blocks (including functions) must be coercible to the expected type (used to be a subtype). Mostly this makes things more flexible and not less (in particular, in the case of coercing function bodies to the return type). However, in some rare cases, this is less flexible. TBH, I'm not exactly sure of the exact effects. I think the change causes us to resolve inferred type variables slightly earlier which might make us slightly more restrictive. Possibly it only affects blocks with unreachable code. E.g., `if ... { fail!(); "Hello" }` used to type check, it no longer does. The fix is to add a semicolon after the string.
1 parent 37a94b8 commit 3e62637

File tree

116 files changed

+3243
-1822
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+3243
-1822
lines changed

Diff for: src/liballoc/heap.rs

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
1313
// and `nonnull`
1414

15+
use core::ptr::RawPtr;
1516
#[cfg(not(test))] use core::raw;
1617
#[cfg(not(test))] use util;
1718

@@ -69,6 +70,11 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
6970
/// the value returned by `usable_size` for the requested size.
7071
#[inline]
7172
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
73+
// FIXME(14395) This is only required for DST ~[T], it should be removed once
74+
// we fix that representation to not use null pointers.
75+
if ptr.is_null() {
76+
return;
77+
}
7278
imp::deallocate(ptr, size, align)
7379
}
7480

Diff for: src/libcollections/slice.rs

-60
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ use core::iter::{range_step, MultiplicativeIterator};
9292

9393
use MutableSeq;
9494
use vec::Vec;
95-
#[cfg(not(stage0))]
96-
use raw::Slice;
9795

9896
pub use core::slice::{Chunks, Slice, ImmutableSlice, ImmutablePartialEqSlice};
9997
pub use core::slice::{ImmutableOrdSlice, MutableSlice, Items, MutItems};
@@ -284,64 +282,6 @@ pub trait CloneableVector<T> {
284282

285283
impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
286284
/// Returns a copy of `v`.
287-
#[cfg(not(stage0))]
288-
fn to_owned(&self) -> ~[T] {
289-
use num::CheckedMul;
290-
use option::Expect;
291-
292-
let len = self.len();
293-
294-
if len == 0 {
295-
unsafe {
296-
let slice: Slice<T> = Slice{data: 0 as *T, len: 0};
297-
mem::transmute(slice)
298-
}
299-
} else {
300-
let unit_size = mem::size_of::<T>();
301-
let data_size = if unit_size == 0 {
302-
len
303-
} else {
304-
let data_size = len.checked_mul(&unit_size);
305-
data_size.expect("overflow in from_iter()")
306-
};
307-
308-
unsafe {
309-
// this should pass the real required alignment
310-
let ret = allocate(data_size, 8) as *mut T;
311-
312-
if unit_size > 0 {
313-
// Be careful with the following loop. We want it to be optimized
314-
// to a memcpy (or something similarly fast) when T is Copy. LLVM
315-
// is easily confused, so any extra operations during the loop can
316-
// prevent this optimization.
317-
let mut i = 0;
318-
let p = &mut (*ret) as *mut _ as *mut T;
319-
try_finally(
320-
&mut i, (),
321-
|i, ()| while *i < len {
322-
mem::move_val_init(
323-
&mut(*p.offset(*i as int)),
324-
self.unsafe_ref(*i).clone());
325-
*i += 1;
326-
},
327-
|i| if *i < len {
328-
// we must be failing, clean up after ourselves
329-
for j in range(0, *i as int) {
330-
ptr::read(&*p.offset(j));
331-
}
332-
// FIXME: #13994 (should pass align and size here)
333-
deallocate(ret as *mut u8, 0, 8);
334-
});
335-
}
336-
let slice: Slice<T> = Slice{data: ret as *T, len: len};
337-
mem::transmute(slice)
338-
}
339-
}
340-
}
341-
342-
/// Returns a copy of `v`.
343-
// NOTE: remove after snapshot
344-
#[cfg(stage0)]
345285
#[inline]
346286
fn to_vec(&self) -> Vec<T> { Vec::from_slice(*self) }
347287

Diff for: src/libcore/intrinsics.rs

+7
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ pub trait TyVisitor {
9393
fn visit_char(&mut self) -> bool;
9494

9595
fn visit_estr_slice(&mut self) -> bool;
96+
// NOTE: remove after snapshot
97+
#[cfg(stage0)]
9698
fn visit_estr_fixed(&mut self, n: uint, sz: uint, align: uint) -> bool;
9799

98100
fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
@@ -101,8 +103,13 @@ pub trait TyVisitor {
101103
fn visit_rptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
102104

103105
fn visit_evec_slice(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
106+
// NOTE: remove after snapshot
107+
#[cfg(stage0)]
104108
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
105109
mtbl: uint, inner: *const TyDesc) -> bool;
110+
#[cfg(not(stage0))]
111+
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
112+
inner: *const TyDesc) -> bool;
106113

107114
fn visit_enter_rec(&mut self, n_fields: uint,
108115
sz: uint, align: uint) -> bool;

Diff for: src/libcore/raw.rs

+6
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,16 @@ pub struct Procedure {
5151
///
5252
/// This struct does not have a `Repr` implementation
5353
/// because there is no way to refer to all trait objects generically.
54+
#[cfg(stage0)]
5455
pub struct TraitObject {
5556
pub vtable: *mut (),
5657
pub data: *mut (),
5758
}
59+
#[cfg(not(stage0))]
60+
pub struct TraitObject {
61+
pub data: *(),
62+
pub vtable: *(),
63+
}
5864

5965
/// This trait is meant to map equivalences between raw structs and their
6066
/// corresponding rust values.

Diff for: src/libcore/slice.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,6 @@ pub mod bytes {
16231623

16241624

16251625

1626-
16271626
//
16281627
// Boilerplate traits
16291628
//

Diff for: src/libdebug/reflect.rs

+13
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
193193
true
194194
}
195195

196+
// NOTE: remove after snapshot
197+
#[cfg(stage0)]
196198
fn visit_estr_fixed(&mut self, n: uint,
197199
sz: uint,
198200
align: uint) -> bool {
@@ -237,6 +239,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
237239
true
238240
}
239241

242+
#[cfg(stage0)]
240243
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
241244
mtbl: uint, inner: *const TyDesc) -> bool {
242245
self.align(align);
@@ -246,6 +249,16 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
246249
self.bump(sz);
247250
true
248251
}
252+
#[cfg(not(stage0))]
253+
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
254+
inner: *TyDesc) -> bool {
255+
self.align(align);
256+
if ! self.inner.visit_evec_fixed(n, sz, align, inner) {
257+
return false;
258+
}
259+
self.bump(sz);
260+
true
261+
}
249262

250263
fn visit_enter_rec(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
251264
self.align(align);

Diff for: src/libdebug/repr.rs

+14
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
275275
}
276276

277277
// Type no longer exists, vestigial function.
278+
// NOTE: remove after snapshot
279+
#[cfg(stage0)]
278280
fn visit_estr_fixed(&mut self, _n: uint, _sz: uint,
279281
_align: uint) -> bool { fail!(); }
280282

@@ -328,6 +330,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
328330
})
329331
}
330332

333+
// NOTE: remove after snapshot
334+
#[cfg(stage0)]
331335
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
332336
_: uint, inner: *const TyDesc) -> bool {
333337
let assumed_size = if sz == 0 { n } else { sz };
@@ -336,6 +340,16 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
336340
})
337341
}
338342

343+
#[cfg(not(stage0))]
344+
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
345+
inner: *TyDesc) -> bool {
346+
let assumed_size = if sz == 0 { n } else { sz };
347+
self.get::<()>(|this, b| {
348+
this.write_vec_range(b, assumed_size, inner)
349+
})
350+
}
351+
352+
339353
fn visit_enter_rec(&mut self, _n_fields: uint,
340354
_sz: uint, _align: uint) -> bool {
341355
try!(self, self.writer.write([b'{']));

Diff for: src/libgreen/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl Context {
112112
// the stack limit to 0 to make morestack never fail
113113
None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
114114
}
115-
rust_swap_registers(out_regs, in_regs)
115+
rust_swap_registers(out_regs, in_regs);
116116
}
117117
}
118118
}

Diff for: src/liblibc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ extern {}
302302
/// A wrapper for a nullable pointer. Don't use this except for interacting
303303
/// with libc. Basically Option, but without the dependence on libstd.
304304
// If/when libprim happens, this can be removed in favor of that
305-
pub enum Nullable<T> {
305+
pub enum Nullable<type T> {
306306
Null,
307307
NotNull(T)
308308
}

Diff for: src/librlibc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
// implementations below. If pointer arithmetic is done through integers the
5050
// optimizations start to break down.
5151
extern "rust-intrinsic" {
52-
fn offset<T>(dst: *const T, offset: int) -> *const T;
52+
fn offset<type T>(dst: *const T, offset: int) -> *const T;
5353
}
5454

5555
#[no_mangle]

Diff for: src/librustc/front/test.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,14 @@ fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
477477

478478
box(GC) ast::Expr {
479479
id: ast::DUMMY_NODE_ID,
480-
node: ast::ExprVstore(box(GC) ast::Expr {
481-
id: ast::DUMMY_NODE_ID,
482-
node: ast::ExprVec(cx.testfns.iter().map(|test| {
483-
mk_test_desc_and_fn_rec(cx, test)
480+
node: ast::ExprAddrOf(box(GC) ast::MutImmutable,
481+
box(GC) ast::Expr {
482+
id: ast::DUMMY_NODE_ID,
483+
node: ast::ExprVec(cx.testfns.borrow().iter().map(|test| {
484+
mk_test_desc_and_fn_rec(cx, test)
484485
}).collect()),
485486
span: DUMMY_SP,
486-
}, ast::ExprVstoreSlice),
487+
}),
487488
span: DUMMY_SP,
488489
}
489490
}

Diff for: src/librustc/lint/builtin.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -1240,18 +1240,8 @@ impl LintPass for UnnecessaryAllocation {
12401240
}
12411241

12421242
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
1243-
// Warn if string and vector literals with sigils, or boxing expressions,
1244-
// are immediately borrowed.
1243+
// Warn if boxing expressions are immediately borrowed.
12451244
let allocation = match e.node {
1246-
ast::ExprVstore(e2, ast::ExprVstoreUniq) => {
1247-
match e2.node {
1248-
ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
1249-
VectorAllocation
1250-
}
1251-
ast::ExprVec(..) => VectorAllocation,
1252-
_ => return
1253-
}
1254-
}
12551245
ast::ExprUnary(ast::UnUniq, _) |
12561246
ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
12571247

@@ -1261,19 +1251,19 @@ impl LintPass for UnnecessaryAllocation {
12611251
match cx.tcx.adjustments.borrow().find(&e.id) {
12621252
Some(adjustment) => {
12631253
match *adjustment {
1264-
ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. }) => {
1254+
ty::AutoDerefRef(ty::AutoDerefRef { ref autoref, .. }) => {
12651255
match (allocation, autoref) {
1266-
(VectorAllocation, Some(ty::AutoBorrowVec(..))) => {
1256+
(VectorAllocation, &Some(ty::AutoPtr(_, _, None))) => {
12671257
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
12681258
"unnecessary allocation, the sigil can be removed");
12691259
}
12701260
(BoxAllocation,
1271-
Some(ty::AutoPtr(_, ast::MutImmutable))) => {
1261+
&Some(ty::AutoPtr(_, ast::MutImmutable, None))) => {
12721262
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
12731263
"unnecessary allocation, use & instead");
12741264
}
12751265
(BoxAllocation,
1276-
Some(ty::AutoPtr(_, ast::MutMutable))) => {
1266+
&Some(ty::AutoPtr(_, ast::MutMutable, None))) => {
12771267
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
12781268
"unnecessary allocation, use &mut instead");
12791269
}

Diff for: src/librustc/metadata/tydecode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,9 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
377377
return ty::mk_rptr(st.tcx, r, mt);
378378
}
379379
'V' => {
380-
let mt = parse_mt(st, |x,y| conv(x,y));
380+
let t = parse_ty(st, |x,y| conv(x,y));
381381
let sz = parse_size(st);
382-
return ty::mk_vec(st.tcx, mt, sz);
382+
return ty::mk_vec(st.tcx, t, sz);
383383
}
384384
'v' => {
385385
return ty::mk_str(st.tcx);

Diff for: src/librustc/metadata/tyencode.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
254254
enc_region(w, cx, r);
255255
enc_mt(w, cx, mt);
256256
}
257-
ty::ty_vec(mt, sz) => {
257+
ty::ty_vec(t, sz) => {
258258
mywrite!(w, "V");
259-
enc_mt(w, cx, mt);
259+
enc_ty(w, cx, t);
260260
mywrite!(w, "/");
261261
match sz {
262262
Some(n) => mywrite!(w, "{}|", n),
@@ -292,6 +292,9 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
292292
ty::ty_err => {
293293
mywrite!(w, "e");
294294
}
295+
ty::ty_open(_) => {
296+
cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
297+
}
295298
}
296299
}
297300

0 commit comments

Comments
 (0)