Auto merge of #23452 - nikomatsakis:unsafety-subtyping, r=nrc

Safe fns are no longer subtypes of unsafe fns, but you can coerce from one to the other.

This is a [breaking-change] in that impl fns must now be declared `unsafe` if the trait is declared `unsafe`. In some rare cases, the subtyping change may also direct affect you, but no such cases were encountered in practice.

Fixes #23449.

r? @nrc
This commit is contained in:
bors 2015-03-18 03:22:12 +00:00
commit c10918905f
19 changed files with 191 additions and 159 deletions

View file

@ -0,0 +1,21 @@
// Copyright 2013-2014 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 safe fns are not a subtype of unsafe fns.
fn foo(x: Option<fn(i32)>) -> Option<unsafe fn(i32)> {
x //~ ERROR mismatched types
}
fn bar(x: fn(i32)) -> unsafe fn(i32) {
x // OK, coercion!
}
fn main() { }

View file

@ -0,0 +1,22 @@
// Copyright 2013-2014 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 safe fns are not a subtype of unsafe fns.
trait Foo {
unsafe fn len(&self) -> u32;
}
impl Foo for u32 {
fn len(&self) -> u32 { *self }
//~^ ERROR incompatible type for trait: expected unsafe fn, found normal fn
}
fn main() { }

View file

@ -30,9 +30,9 @@ fn main() {
//~| expected non-variadic fn
//~| found variadic function
let y: unsafe extern "C" fn(f: isize, x: u8, ...) = bar;
let y: extern "C" fn(f: isize, x: u8, ...) = bar;
//~^ ERROR: mismatched types
//~| expected `unsafe extern "C" fn(isize, u8, ...)`
//~| expected `extern "C" fn(isize, u8, ...)`
//~| found `extern "C" fn(isize, u8) {bar}`
//~| expected variadic fn
//~| found non-variadic function

View file

@ -0,0 +1,25 @@
// Copyright 2013-2014 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 safe fns are not a subtype of unsafe fns.
fn foo(x: i32) -> i32 {
x * 22
}
fn bar(x: fn(i32) -> i32) -> unsafe fn(i32) -> i32 {
x // OK, coercion!
}
fn main() {
let f = bar(foo);
let x = unsafe { f(2) };
assert_eq!(x, 44);
}