From 9089cf2ec9297a3b558d24352cde6a5206a08444 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 18 Jul 2013 17:12:46 -0700 Subject: [PATCH] librustc: Forbid `&` pointers (other than `&'static`) inside `@` boxes. This makes custom borrowing implementations for custom smart pointers sound. --- src/libextra/fun_treemap.rs | 17 ++++++++-- src/libextra/list.rs | 4 +-- src/libextra/serialize.rs | 4 +-- src/librustc/metadata/encoder.rs | 12 ++++--- src/librustc/middle/kind.rs | 4 +++ src/librustc/middle/subst.rs | 2 +- src/librustc/middle/ty.rs | 2 +- src/libstd/clone.rs | 4 +-- src/libstd/num/num.rs | 4 +-- src/libstd/rand.rs | 2 +- src/libsyntax/ext/base.rs | 3 +- src/libsyntax/util/interner.rs | 2 +- src/test/auxiliary/cci_nested_lib.rs | 12 ++++--- src/test/compile-fail/box-static-bound.rs | 10 ++++++ src/test/compile-fail/kindck-owned-trait.rs | 1 + src/test/compile-fail/kindck-owned.rs | 3 +- src/test/run-pass/alignment-gep-tup-like-2.rs | 8 +++-- src/test/run-pass/generic-box.rs | 2 +- src/test/run-pass/generic-exterior-box.rs | 2 +- src/test/run-pass/infer-with-expected.rs | 4 +-- src/test/run-pass/issue-3447.rs | 17 +++++----- .../run-pass/kindck-owned-trait-contains-1.rs | 8 ++--- src/test/run-pass/log-linearized.rs | 4 +-- src/test/run-pass/regions-trait.rs | 34 ------------------- 24 files changed, 84 insertions(+), 81 deletions(-) create mode 100644 src/test/compile-fail/box-static-bound.rs delete mode 100644 src/test/run-pass/regions-trait.rs diff --git a/src/libextra/fun_treemap.rs b/src/libextra/fun_treemap.rs index 7074d76536a..edbe323ec2d 100644 --- a/src/libextra/fun_treemap.rs +++ b/src/libextra/fun_treemap.rs @@ -31,10 +31,17 @@ enum TreeNode { } /// Create a treemap -pub fn init() -> Treemap { @Empty } +pub fn init() -> Treemap { + @Empty +} /// Insert a value into the map -pub fn insert(m: Treemap, k: K, v: V) -> Treemap { +pub fn insert( + m: Treemap, + k: K, + v: V) + -> Treemap { @match m { @Empty => Node(@k, @v, @Empty, @Empty), @Node(kk, vv, left, right) => cond!( @@ -46,7 +53,11 @@ pub fn insert(m: Treemap, k: K, v: V) -> Treemap { } /// Find a value based on the key -pub fn find(m: Treemap, k: K) -> Option { +pub fn find( + m: Treemap, + k: K) + -> Option { match *m { Empty => None, Node(kk, v, left, right) => cond!( diff --git a/src/libextra/list.rs b/src/libextra/list.rs index 03481760579..8f7ade7228b 100644 --- a/src/libextra/list.rs +++ b/src/libextra/list.rs @@ -25,7 +25,7 @@ pub enum MutList { } /// Create a list from a vector -pub fn from_vec(v: &[T]) -> @List { +pub fn from_vec(v: &[T]) -> @List { v.rev_iter().fold(@Nil::, |t, h| @Cons((*h).clone(), t)) } @@ -109,7 +109,7 @@ pub fn head(ls: @List) -> T { } /// Appends one list to another -pub fn append(l: @List, m: @List) -> @List { +pub fn append(l: @List, m: @List) -> @List { match *l { Nil => return m, Cons(ref x, xs) => { diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 62c1f6631d2..679e5e46547 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -423,7 +423,7 @@ impl> Encodable for @T { } } -impl> Decodable for @T { +impl + 'static> Decodable for @T { fn decode(d: &mut D) -> @T { @Decodable::decode(d) } @@ -435,7 +435,7 @@ impl> Encodable for @mut T { } } -impl> Decodable for @mut T { +impl + 'static> Decodable for @mut T { fn decode(d: &mut D) -> @mut T { @mut Decodable::decode(d) } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index ab42e84e2ac..d9be85189a2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1259,8 +1259,9 @@ fn encode_info_for_items(ecx: &EncodeContext, // Path and definition ID indexing -fn create_index(index: ~[entry]) - -> ~[@~[entry]] { +fn create_index( + index: ~[entry]) + -> ~[@~[entry]] { let mut buckets: ~[@mut ~[entry]] = ~[]; for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; for index.iter().advance |elt| { @@ -1275,9 +1276,10 @@ fn create_index(index: ~[entry]) return buckets_frozen; } -fn encode_index(ebml_w: &mut writer::Encoder, - buckets: ~[@~[entry]], - write_fn: &fn(@io::Writer, &T)) { +fn encode_index( + ebml_w: &mut writer::Encoder, + buckets: ~[@~[entry]], + write_fn: &fn(@io::Writer, &T)) { let writer = ebml_w.writer; ebml_w.start_tag(tag_index); let mut bucket_locs: ~[uint] = ~[]; diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index deafe85a2c9..acb01e5bf67 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -285,6 +285,10 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { } match e.node { + expr_unary(_, box(_), interior) => { + let interior_type = ty::expr_ty(cx.tcx, interior); + let _ = check_durable(cx.tcx, interior_type, interior.span); + } expr_cast(source, _) => { check_cast_for_escaping_regions(cx, source, e); match ty::get(ty::expr_ty(cx.tcx, e)).sty { diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 5a3bb9c55d5..d43cea2c733 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -79,7 +79,7 @@ impl Subst for ~[T] { } } -impl Subst for @T { +impl Subst for @T { fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @T { match self { &@ref t => @t.subst(tcx, substs) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 50f331f7e7d..0c2ec8c19d0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -858,7 +858,7 @@ fn mk_rcache() -> creader_cache { return @mut HashMap::new(); } -pub fn new_ty_hash() -> @mut HashMap { +pub fn new_ty_hash() -> @mut HashMap { @mut HashMap::new() } diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index f24bc002a2b..ccab40b2db2 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -112,7 +112,7 @@ impl DeepClone for ~T { } // FIXME: #6525: should also be implemented for `T: Send + DeepClone` -impl DeepClone for @T { +impl DeepClone for @T { /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. #[inline] @@ -120,7 +120,7 @@ impl DeepClone for @T { } // FIXME: #6525: should also be implemented for `T: Send + DeepClone` -impl DeepClone for @mut T { +impl DeepClone for @mut T { /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. #[inline] diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index fc199876902..f35f495def3 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -446,12 +446,12 @@ pub fn pow_with_uint+Mul>(radix: uint, pow: uin total } -impl Zero for @mut T { +impl Zero for @mut T { fn zero() -> @mut T { @mut Zero::zero() } fn is_zero(&self) -> bool { (**self).is_zero() } } -impl Zero for @T { +impl Zero for @T { fn zero() -> @T { @Zero::zero() } fn is_zero(&self) -> bool { (**self).is_zero() } } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 76dbc629168..3574b9c60e6 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -242,7 +242,7 @@ impl Rand for ~T { fn rand(rng: &mut R) -> ~T { ~rng.gen() } } -impl Rand for @T { +impl Rand for @T { #[inline] fn rand(rng: &mut R) -> @T { @rng.gen() } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 230640767c9..2f86a0460d1 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -414,8 +414,7 @@ pub enum MapChain { // get the map from an env frame -impl MapChain{ - +impl MapChain{ // Constructor. I don't think we need a zero-arg one. fn new(init: ~HashMap) -> @mut MapChain { @mut BaseMapChain(init) diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 3d2e0632a33..014186c9ff4 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -21,7 +21,7 @@ pub struct Interner { } // when traits can extend traits, we should extend index to get [] -impl Interner { +impl Interner { pub fn new() -> Interner { Interner { map: @mut HashMap::new(), diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs index d53b7d825cb..b8e831c4503 100644 --- a/src/test/auxiliary/cci_nested_lib.rs +++ b/src/test/auxiliary/cci_nested_lib.rs @@ -18,11 +18,15 @@ pub struct alist { data: @mut ~[Entry] } -pub fn alist_add(lst: &alist, k: A, v: B) { +pub fn alist_add(lst: &alist, k: A, v: B) { lst.data.push(Entry{key:k, value:v}); } -pub fn alist_get(lst: &alist, k: A) -> B { +pub fn alist_get( + lst: &alist, + k: A) + -> B { let eq_fn = lst.eq_fn; for lst.data.iter().advance |entry| { if eq_fn(entry.key.clone(), k.clone()) { @@ -33,13 +37,13 @@ pub fn alist_get(lst: &alist, k: A) -> B { } #[inline] -pub fn new_int_alist() -> alist { +pub fn new_int_alist() -> alist { fn eq_int(a: int, b: int) -> bool { a == b } return alist {eq_fn: eq_int, data: @mut ~[]}; } #[inline] -pub fn new_int_alist_2() -> alist { +pub fn new_int_alist_2() -> alist { #[inline] fn eq_int(a: int, b: int) -> bool { a == b } return alist {eq_fn: eq_int, data: @mut ~[]}; diff --git a/src/test/compile-fail/box-static-bound.rs b/src/test/compile-fail/box-static-bound.rs new file mode 100644 index 00000000000..69d7bedbd37 --- /dev/null +++ b/src/test/compile-fail/box-static-bound.rs @@ -0,0 +1,10 @@ +fn f(x: T) -> @T { + @x //~ ERROR value may contain borrowed pointers +} + +fn g(x: T) -> @T { + @x // ok +} + +fn main() {} + diff --git a/src/test/compile-fail/kindck-owned-trait.rs b/src/test/compile-fail/kindck-owned-trait.rs index 73d59ff8af2..ef9cbfe5dd9 100644 --- a/src/test/compile-fail/kindck-owned-trait.rs +++ b/src/test/compile-fail/kindck-owned-trait.rs @@ -14,6 +14,7 @@ fn to_foo(t: T) -> @foo { @t as @foo //~^ ERROR value may contain borrowed pointers; add `'static` bound //~^^ ERROR cannot pack type + //~^^^ ERROR value may contain borrowed pointers } fn to_foo2(t: T) -> @foo { diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index c3c929a2288..2dfdb2629f7 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -23,5 +23,6 @@ fn main() { copy2(&x); //~ ERROR does not fulfill `'static` copy2(@3); - copy2(@&x); //~ ERROR does not fulfill `'static` + copy2(@&x); //~ ERROR value may contain borrowed pointers + //~^ ERROR does not fulfill `'static` } diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 1d910023a63..e924c31bad6 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -18,12 +18,16 @@ struct Rec { rec: Option<@mut RecEnum> } -fn make_cycle(a: A) { +fn make_cycle(a: A) { let g: @mut RecEnum = @mut RecEnum(Rec {val: a, rec: None}); g.rec = Some(g); } -fn f(a: A, b: B) -> @fn() -> (A, B) { +fn f( + a: A, + b: B) + -> @fn() -> (A, B) { let result: @fn() -> (A, B) = || (a.clone(), b.clone()); result } diff --git a/src/test/run-pass/generic-box.rs b/src/test/run-pass/generic-box.rs index a3e933f3ceb..ce1582b3c3c 100644 --- a/src/test/run-pass/generic-box.rs +++ b/src/test/run-pass/generic-box.rs @@ -10,7 +10,7 @@ -fn box(x: Box) -> @Box { return @x; } +fn box(x: Box) -> @Box { return @x; } struct Box {x: T, y: T, z: T} diff --git a/src/test/run-pass/generic-exterior-box.rs b/src/test/run-pass/generic-exterior-box.rs index b7fe704749c..795c73007d5 100644 --- a/src/test/run-pass/generic-exterior-box.rs +++ b/src/test/run-pass/generic-exterior-box.rs @@ -12,7 +12,7 @@ struct Recbox {x: @T} -fn reclift(t: T) -> Recbox { return Recbox {x: @t}; } +fn reclift(t: T) -> Recbox { return Recbox {x: @t}; } pub fn main() { let foo: int = 17; diff --git a/src/test/run-pass/infer-with-expected.rs b/src/test/run-pass/infer-with-expected.rs index 9dfe7e45c11..6f2fd54bc9c 100644 --- a/src/test/run-pass/infer-with-expected.rs +++ b/src/test/run-pass/infer-with-expected.rs @@ -14,12 +14,12 @@ // happen.) fn eat_tup(_r: ~@(int, @fn(Pair) -> int)) {} -fn eat_rec(_r: @~Rec) {} +fn eat_rec(_r: ~Rec) {} struct Rec<'self> { a: int, b: &'self fn(Pair) -> int } struct Pair { x: int, y: int } pub fn main() { eat_tup(~@(10, |a| a.x )); - eat_rec(@~Rec{a: 10, b: |a| a.x }); + eat_rec(~Rec{a: 10, b: |a| a.x }); } diff --git a/src/test/run-pass/issue-3447.rs b/src/test/run-pass/issue-3447.rs index 711dfd3778b..64483ab80a4 100644 --- a/src/test/run-pass/issue-3447.rs +++ b/src/test/run-pass/issue-3447.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct list<'self, T> { - element: &'self T, - next: Option<@mut list<'self, T>> +static S: &'static str = "str"; + +struct list { + element: T, + next: Option<@mut list> } -impl<'self, T> list<'self, T>{ - pub fn addEnd(&mut self, element: &'self T) { +impl list { + pub fn addEnd(&mut self, element: T) { let newList = list { element: element, next: None @@ -25,10 +27,9 @@ impl<'self, T> list<'self, T>{ } pub fn main() { - let s = @"str"; let ls = list { - element: &s, + element: S, next: None }; - println(*ls.element); + println(ls.element); } diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs index 1370aea6df5..29a89a65a9b 100644 --- a/src/test/run-pass/kindck-owned-trait-contains-1.rs +++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs @@ -10,19 +10,19 @@ trait repeat { fn get(&self) -> A; } -impl repeat for @A { +impl repeat for @A { fn get(&self) -> A { (**self).clone() } } -fn repeater(v: @A) -> @repeat: { +fn repeater(v: @A) -> @repeat: { // Note: owned kind is not necessary as A appears in the trait type @v as @repeat: // No } pub fn main() { - let x = &3; + let x = 3; let y = repeater(@x); - assert_eq!(*x, *(y.get())); + assert_eq!(x, y.get()); } diff --git a/src/test/run-pass/log-linearized.rs b/src/test/run-pass/log-linearized.rs index 0f388489000..97b8c77c315 100644 --- a/src/test/run-pass/log-linearized.rs +++ b/src/test/run-pass/log-linearized.rs @@ -19,12 +19,12 @@ struct Smallintmap {v: ~[option]} struct V { v: ~[option] } -fn mk() -> @mut Smallintmap { +fn mk() -> @mut Smallintmap { let mut v: ~[option] = ~[]; return @mut Smallintmap {v: v}; } -fn f() { +fn f() { let mut sim = mk::(); error!(sim); } diff --git a/src/test/run-pass/regions-trait.rs b/src/test/run-pass/regions-trait.rs deleted file mode 100644 index 049d5305ca4..00000000000 --- a/src/test/run-pass/regions-trait.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct Ctxt { v: uint } - -trait get_ctxt<'self> { - fn get_ctxt(&self) -> &'self Ctxt; -} - -struct HasCtxt<'self> { c: &'self Ctxt } - -impl<'self> get_ctxt<'self> for HasCtxt<'self> { - fn get_ctxt(&self) -> &'self Ctxt { - self.c - } -} - -fn get_v(gc: @get_ctxt:) -> uint { - gc.get_ctxt().v -} - -pub fn main() { - let ctxt = Ctxt { v: 22 }; - let hc = HasCtxt { c: &ctxt }; - - assert_eq!(get_v(@hc as @get_ctxt:), 22); -}