librustc: Make the compiler ignore purity.
For bootstrapping purposes, this commit does not remove all uses of
the keyword "pure" -- doing so would cause the compiler to no longer
bootstrap due to some syntax extensions ("deriving" in particular).
Instead, it makes the compiler ignore "pure". Post-snapshot, we can
remove "pure" from the language.
There are quite a few (~100) borrow check errors that were essentially
all the result of mutable fields or partial borrows of `@mut`. Per
discussions with Niko I think we want to allow partial borrows of
`@mut` but detect obvious footguns. We should also improve the error
message when `@mut` is erroneously reborrowed.
This commit is contained in:
parent
c4db4faefa
commit
e78f2e2ac5
72 changed files with 373 additions and 540 deletions
|
|
@ -22,17 +22,6 @@ fn match_const_box(v: &const @const Option<int>) -> int {
|
|||
}
|
||||
}
|
||||
|
||||
pure fn pure_process(_i: int) {}
|
||||
|
||||
fn match_const_box_and_do_pure_things(v: &const @const Option<int>) {
|
||||
match *v {
|
||||
@Some(ref i) => {
|
||||
pure_process(*i)
|
||||
}
|
||||
@None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn process(_i: int) {}
|
||||
|
||||
fn match_const_box_and_do_bad_things(v: &const @const Option<int>) {
|
||||
|
|
|
|||
|
|
@ -1,33 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pure fn pure_borrow(_x: &int, _y: ()) {}
|
||||
|
||||
fn test1(x: @mut ~int) {
|
||||
// Here, evaluating the second argument actually invalidates the
|
||||
// first borrow, even though it occurs outside of the scope of the
|
||||
// borrow!
|
||||
pure_borrow(*x, *x = ~5); //~ ERROR illegal borrow unless pure
|
||||
//~^ NOTE impure due to assigning to dereference of mutable @ pointer
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
let mut x = ~1;
|
||||
|
||||
// Same, but for loanable data:
|
||||
|
||||
pure_borrow(x, x = ~5); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
|
||||
//~^ NOTE loan of mutable local variable granted here
|
||||
|
||||
copy x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,16 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pure fn call_first((x, _y): (&fn(), &fn())) {
|
||||
x(); //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
@ -1,64 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[legacy_modes];
|
||||
|
||||
// Test rules governing higher-order pure fns.
|
||||
|
||||
struct S<'self> {
|
||||
f: &'self fn(uint)
|
||||
}
|
||||
|
||||
pure fn range(from: uint, to: uint, f: &fn(uint)) {
|
||||
let mut i = from;
|
||||
while i < to {
|
||||
f(i); // Note: legal to call argument, even if it is not pure.
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
pure fn range2(from: uint, to: uint, f: &fn(uint)) {
|
||||
do range(from, to) |i| {
|
||||
f(i*2u);
|
||||
}
|
||||
}
|
||||
|
||||
pure fn range3(from: uint, to: uint, f: &fn(uint)) {
|
||||
range(from, to, f)
|
||||
}
|
||||
|
||||
pure fn range4(from: uint, to: uint) {
|
||||
range(from, to, print) //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
|
||||
pure fn range5<'a>(from: uint, to: uint, x: S<'a>) {
|
||||
range(from, to, x.f) //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
|
||||
pure fn range6<'a>(from: uint, to: uint, x: @S<'a>) {
|
||||
range(from, to, x.f) //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
|
||||
pure fn range7(from: uint, to: uint) {
|
||||
do range(from, to) |i| {
|
||||
print(i); //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
}
|
||||
|
||||
pure fn range8(from: uint, to: uint) {
|
||||
range(from, to, noop);
|
||||
}
|
||||
|
||||
fn print(i: uint) { error!("i=%u", i); }
|
||||
|
||||
pure fn noop(_i: uint) {}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,35 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct S<'self> {
|
||||
x: &'self fn(uint)
|
||||
}
|
||||
|
||||
pure fn range<'a>(from: uint, to: uint, f: &'a fn(uint) -> bool) {
|
||||
let mut i = from;
|
||||
while i < to {
|
||||
if !f(i) {return;} // Note: legal to call argument, even if it is not pure.
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
pure fn range2<'a>(from: uint, to: uint, f: &'a fn(uint)) {
|
||||
for range(from, to) |i| {
|
||||
f(i*2u);
|
||||
}
|
||||
}
|
||||
|
||||
pure fn range3<'a>(from: uint, to: uint, f: S<'a>) {
|
||||
for range(from, to) |i| {
|
||||
(f.x)(i*2u); //~ ERROR access to impure function prohibited
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,32 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that pure functions cannot modify aliased state.
|
||||
|
||||
struct S {
|
||||
f: int,
|
||||
}
|
||||
|
||||
pure fn modify_in_box(sum: @mut S) {
|
||||
sum.f = 3; //~ ERROR assigning to mutable field prohibited in pure context
|
||||
}
|
||||
|
||||
trait modify_in_box_rec {
|
||||
pure fn modify_in_box_rec(&self, sum: @mut S);
|
||||
}
|
||||
|
||||
impl modify_in_box_rec for int {
|
||||
pure fn modify_in_box_rec(&self, sum: @mut S) {
|
||||
sum.f = *self; //~ ERROR assigning to mutable field prohibited in pure context
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,48 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test rules governing higher-order pure fns.
|
||||
|
||||
fn take<T>(_v: T) {}
|
||||
|
||||
fn assign_to_pure(x: &pure fn(), y: &fn(), z: &unsafe fn()) {
|
||||
take::<&pure fn()>(x);
|
||||
take::<&pure fn()>(y); //~ ERROR expected pure fn but found impure fn
|
||||
take::<&pure fn()>(z); //~ ERROR expected pure fn but found unsafe fn
|
||||
}
|
||||
|
||||
fn assign_to_impure(x: &pure fn(), y: &fn(), z: &unsafe fn()) {
|
||||
take::<&fn()>(x);
|
||||
take::<&fn()>(y);
|
||||
take::<&fn()>(z); //~ ERROR expected impure fn but found unsafe fn
|
||||
}
|
||||
|
||||
fn assign_to_unsafe(x: &pure fn(), y: &fn(), z: &unsafe fn()) {
|
||||
take::<&unsafe fn()>(x);
|
||||
take::<&unsafe fn()>(y);
|
||||
take::<&unsafe fn()>(z);
|
||||
}
|
||||
|
||||
fn assign_to_pure2(x: @pure fn(), y: @fn(), z: @unsafe fn()) {
|
||||
take::<&pure fn()>(x);
|
||||
take::<&pure fn()>(y); //~ ERROR expected pure fn but found impure fn
|
||||
take::<&pure fn()>(z); //~ ERROR expected pure fn but found unsafe fn
|
||||
|
||||
take::<~pure fn()>(x); //~ ERROR expected ~ closure, found @ closure
|
||||
take::<~pure fn()>(y); //~ ERROR expected ~ closure, found @ closure
|
||||
take::<~pure fn()>(z); //~ ERROR expected ~ closure, found @ closure
|
||||
|
||||
take::<~unsafe fn()>(x); //~ ERROR expected ~ closure, found @ closure
|
||||
take::<~unsafe fn()>(y); //~ ERROR expected ~ closure, found @ closure
|
||||
take::<~unsafe fn()>(z); //~ ERROR expected ~ closure, found @ closure
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,16 +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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn something(f: &pure fn()) { f(); }
|
||||
|
||||
fn main() {
|
||||
let mut x = ~[];
|
||||
something(|| x.push(0) ); //~ ERROR access to impure function prohibited in pure context
|
||||
}
|
||||
|
|
@ -9,15 +9,15 @@
|
|||
// except according to those terms.
|
||||
|
||||
trait Mumbo {
|
||||
pure fn jumbo(&self, x: @uint) -> uint;
|
||||
fn jumbo(&self, x: @uint) -> uint;
|
||||
fn jambo(&self, x: @const uint) -> uint;
|
||||
fn jbmbo(&self) -> @uint;
|
||||
}
|
||||
|
||||
impl Mumbo for uint {
|
||||
// Cannot have a larger effect than the trait:
|
||||
fn jumbo(&self, x: @uint) { *self + *x; }
|
||||
//~^ ERROR expected pure fn but found impure fn
|
||||
unsafe fn jumbo(&self, x: @uint) { *self + *x; }
|
||||
//~^ ERROR expected impure fn but found unsafe fn
|
||||
|
||||
// Cannot accept a narrower range of parameters:
|
||||
fn jambo(&self, x: @uint) { *self + *x; }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ pub fn main() {
|
|||
(&"test").test_imm();
|
||||
|
||||
// XXX: Other types of mutable vecs don't currently exist
|
||||
(@mut [1]).test_imm();
|
||||
|
||||
([1]).test_const();
|
||||
(~[1]).test_const();
|
||||
|
|
@ -50,8 +49,6 @@ pub fn main() {
|
|||
(@"test").test_const();
|
||||
(&"test").test_const();
|
||||
|
||||
(@mut [1]).test_const();
|
||||
|
||||
// NB: We don't do this double autoreffing for &mut self because that would
|
||||
// allow creating a mutable pointer to a temporary, which would be a source
|
||||
// of confusion
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ impl<T> BaseIter<(int, &'self T)> for cat<T> {
|
|||
}
|
||||
|
||||
impl<T> Container for cat<T> {
|
||||
pure fn len(&self) -> uint { self.meows as uint }
|
||||
pure fn is_empty(&self) -> bool { self.meows == 0 }
|
||||
pure fn len(&const self) -> uint { self.meows as uint }
|
||||
pure fn is_empty(&const self) -> bool { self.meows == 0 }
|
||||
}
|
||||
|
||||
impl<T> Mutable for cat<T> {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,4 @@ fn negate_imm(y: &int) -> int {
|
|||
negate(y)
|
||||
}
|
||||
|
||||
fn negate_const(y: &const int) -> int {
|
||||
negate(y)
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ struct SpeechMaker {
|
|||
}
|
||||
|
||||
pub impl SpeechMaker {
|
||||
pure fn how_many(&self) -> uint { self.speeches }
|
||||
pure fn how_many(&const self) -> uint { self.speeches }
|
||||
}
|
||||
|
||||
fn foo(speaker: &const SpeechMaker) -> uint {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// xfail-test
|
||||
|
||||
pure fn sum(x: &[int]) -> int {
|
||||
let mut sum = 0;
|
||||
for x.each |y| { sum += *y; }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// xfail-test
|
||||
|
||||
fn foo(v: &[const uint]) -> ~[uint] {
|
||||
v.to_vec()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ struct Refs { refs: ~[int], n: int }
|
|||
|
||||
pub fn main() {
|
||||
let e = @mut Refs{refs: ~[], n: 0};
|
||||
let f: @fn() = || error!(e.n);
|
||||
let f: @fn() = || error!(copy e.n);
|
||||
e.refs += ~[1];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue