diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2014-08-04 14:20:11 +0200 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2014-08-26 12:38:51 +1200 |
| commit | 3e626375d8d2226a203bf6ea6e98dab14774c59f (patch) | |
| tree | 9be8320420b1c904670b7e12ccff8bc3080b2eec /src/libsyntax | |
| parent | 37a94b80f207e86017e54056ced2dc9674907ae3 (diff) | |
| download | rust-3e626375d8d2226a203bf6ea6e98dab14774c59f.tar.gz rust-3e626375d8d2226a203bf6ea6e98dab14774c59f.zip | |
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.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 78 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/util/small_vector.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 3 |
8 files changed, 35 insertions, 97 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 42d9430d732..7d5787092a5 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -395,16 +395,6 @@ pub enum Mutability { } #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub enum ExprVstore { - /// ~[1, 2, 3, 4] - ExprVstoreUniq, - /// &[1, 2, 3, 4] - ExprVstoreSlice, - /// &mut [1, 2, 3, 4] - ExprVstoreMutSlice, -} - -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum BinOp { BiAdd, BiSub, @@ -522,7 +512,6 @@ pub struct Expr { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Expr_ { - ExprVstore(Gc<Expr>, ExprVstore), /// First expr is the place; second expr is the value. ExprBox(Gc<Expr>, Gc<Expr>), ExprVec(Vec<Gc<Expr>>), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index f7eddca4b7a..909f8f1e78c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -143,12 +143,10 @@ pub trait AstBuilder { fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr>; fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr>; - fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr>; fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>; fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr>; fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>; fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>; - fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>; fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>; fn expr_none(&self, sp: Span) -> Gc<ast::Expr>; @@ -654,9 +652,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_lit(sp, ast::LitBool(value)) } - fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr> { - self.expr(sp, ast::ExprVstore(expr, vst)) - } fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> { self.expr(sp, ast::ExprVec(exprs)) } @@ -669,15 +664,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { Vec::new()) } fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> { - self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice) + self.expr_addr_of(sp, self.expr_vec(sp, exprs)) } fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> { self.expr_lit(sp, ast::LitStr(s, ast::CookedStr)) } - fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> { - self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq) - } - fn expr_cast(&self, sp: Span, expr: Gc<ast::Expr>, ty: P<ast::Ty>) -> Gc<ast::Expr> { self.expr(sp, ast::ExprCast(expr, ty)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index fb96b4b83d7..4a0787aeb9e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1088,9 +1088,6 @@ pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> { pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> { let id = folder.new_id(e.id); let node = match e.node { - ExprVstore(e, v) => { - ExprVstore(folder.fold_expr(e), v) - } ExprBox(p, e) => { ExprBox(folder.fold_expr(p), folder.fold_expr(e)) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 17a27a5a39e..585b98925cc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1137,7 +1137,8 @@ mod test { let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap(); let docs = item.attrs.iter().filter(|a| a.name().get() == "doc") .map(|a| a.value_str().unwrap().get().to_string()).collect::<Vec<_>>(); - assert_eq!(docs.as_slice(), &["/// doc comment".to_string(), "/// line 2".to_string()]); + let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; + assert_eq!(docs.as_slice(), b); let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2409912abe4..00513f7f67c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,9 +27,8 @@ use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex}; use ast::{ExprLit, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn}; -use ast::{ExprVec, ExprVstore, ExprVstoreSlice}; -use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, Field, FnDecl}; -use ast::{ExprVstoreUniq, Once, Many}; +use ast::{ExprVec, ExprWhile, ExprForLoop, Field, FnDecl}; +use ast::{Once, Many}; use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod}; @@ -1428,13 +1427,16 @@ impl<'a> Parser<'a> { } else if self.token == token::TILDE { // OWNED POINTER self.bump(); - let last_span = self.last_span; + let span = self.last_span; match self.token { - token::LBRACKET => - self.obsolete(last_span, ObsoleteOwnedVector), - _ => self.obsolete(last_span, ObsoleteOwnedType), - }; - TyUniq(self.parse_ty(true)) + token::IDENT(ref ident, _) + if "str" == token::get_ident(*ident).get() => { + // This is OK (for now). + } + token::LBRACKET => {} // Also OK. + _ => self.obsolete(span, ObsoleteOwnedType) + } + TyUniq(self.parse_ty(false)) } else if self.token == token::BINOP(token::STAR) { // STAR POINTER (bare pointer?) self.bump(); @@ -2549,16 +2551,7 @@ impl<'a> Parser<'a> { let m = self.parse_mutability(); let e = self.parse_prefix_expr(); hi = e.span.hi; - // HACK: turn &[...] into a &-vec - ex = match e.node { - ExprVec(..) if m == MutImmutable => { - ExprVstore(e, ExprVstoreSlice) - } - ExprVec(..) if m == MutMutable => { - ExprVstore(e, ExprVstoreMutSlice) - } - _ => ExprAddrOf(m, e) - }; + ex = ExprAddrOf(m, e); } token::AT => { self.bump(); @@ -2570,25 +2563,18 @@ impl<'a> Parser<'a> { } token::TILDE => { self.bump(); + let span = self.last_span; + match self.token { + token::LIT_STR(_) => { + // This is OK (for now). + } + token::LBRACKET => {} // Also OK. + _ => self.obsolete(span, ObsoleteOwnedExpr) + } let e = self.parse_prefix_expr(); hi = e.span.hi; - // HACK: turn ~[...] into a ~-vec - let last_span = self.last_span; - ex = match e.node { - ExprVec(..) | ExprRepeat(..) => { - self.obsolete(last_span, ObsoleteOwnedVector); - ExprVstore(e, ExprVstoreUniq) - } - ExprLit(lit) if lit_is_str(lit) => { - self.obsolete(last_span, ObsoleteOwnedExpr); - ExprVstore(e, ExprVstoreUniq) - } - _ => { - self.obsolete(last_span, ObsoleteOwnedExpr); - self.mk_unary(UnUniq, e) - } - }; + ex = self.mk_unary(UnUniq, e); } token::IDENT(_, _) => { if self.is_keyword(keywords::Box) { @@ -2607,24 +2593,10 @@ impl<'a> Parser<'a> { } } - // Otherwise, we use the unique pointer default. - let subexpression = self.parse_prefix_expr(); - hi = subexpression.span.hi; - // HACK: turn `box [...]` into a boxed-vec - ex = match subexpression.node { - ExprVec(..) | ExprRepeat(..) => { - let last_span = self.last_span; - self.obsolete(last_span, ObsoleteOwnedVector); - ExprVstore(subexpression, ExprVstoreUniq) - } - ExprLit(lit) if lit_is_str(lit) => { - ExprVstore(subexpression, ExprVstoreUniq) - } - _ => self.mk_unary(UnUniq, subexpression) - }; - } else { - return self.parse_dot_or_call_expr() - } + // Otherwise, we use the unique pointer default. + let subexpression = self.parse_prefix_expr(); + hi = subexpression.span.hi; + ex = self.mk_unary(UnUniq, subexpression); } _ => return self.parse_dot_or_call_expr() } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6fe44078447..d5b6c5652a0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -159,6 +159,7 @@ impl<'a> State<'a> { } pub fn to_string(f: |&mut State| -> IoResult<()>) -> String { + use std::raw::TraitObject; let mut s = rust_printer(box MemWriter::new()); f(&mut s).unwrap(); eof(&mut s.s).unwrap(); @@ -166,7 +167,8 @@ pub fn to_string(f: |&mut State| -> IoResult<()>) -> String { // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer` // that we "know" to be a `MemWriter` that works around the lack of checked // downcasts. - let (_, wr): (uint, Box<MemWriter>) = mem::transmute_copy(&s.s.out); + let obj: TraitObject = mem::transmute_copy(&s.s.out); + let wr: Box<MemWriter> = mem::transmute(obj.data); let result = String::from_utf8(Vec::from_slice(wr.get_ref().as_slice())).unwrap(); mem::forget(wr); @@ -1321,16 +1323,6 @@ impl<'a> State<'a> { } } - pub fn print_expr_vstore(&mut self, t: ast::ExprVstore) -> IoResult<()> { - match t { - ast::ExprVstoreUniq => word(&mut self.s, "box "), - ast::ExprVstoreSlice => word(&mut self.s, "&"), - ast::ExprVstoreMutSlice => { - try!(word(&mut self.s, "&")); - word(&mut self.s, "mut") - } - } - } fn print_call_post(&mut self, args: &[Gc<ast::Expr>]) -> IoResult<()> { try!(self.popen()); @@ -1355,10 +1347,6 @@ impl<'a> State<'a> { try!(self.ibox(indent_unit)); try!(self.ann.pre(self, NodeExpr(expr))); match expr.node { - ast::ExprVstore(ref e, v) => { - try!(self.print_expr_vstore(v)); - try!(self.print_expr(&**e)); - }, ast::ExprBox(ref p, ref e) => { try!(word(&mut self.s, "box")); try!(word(&mut self.s, "(")); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 43367611ab2..517c5e5bf47 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -64,7 +64,10 @@ impl<T> SmallVector<T> { pub fn as_slice<'a>(&'a self) -> &'a [T] { match self.repr { - Zero => &[], + Zero => { + let result: &[T] = &[]; + result + } One(ref v) => slice::ref_slice(v), Many(ref vs) => vs.as_slice() } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9e371143311..6c6f59f0df6 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -729,9 +729,6 @@ pub fn walk_mac<E, V: Visitor<E>>(_: &mut V, _: &Mac, _: E) { pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, env: E) { match expression.node { - ExprVstore(ref subexpression, _) => { - visitor.visit_expr(&**subexpression, env.clone()) - } ExprBox(ref place, ref subexpression) => { visitor.visit_expr(&**place, env.clone()); visitor.visit_expr(&**subexpression, env.clone()) |
