Rollup merge of #23895 - nikomatsakis:fn-trait-inheritance-add-impls, r=pnkfelix
The primary purpose of this PR is to add blanket impls for the `Fn` traits of the following (simplified) form:
impl<F:Fn> Fn for &F
impl<F:FnMut> FnMut for &mut F
However, this wound up requiring two changes:
1. A slight hack so that `x()` where `x: &mut F` is translated to `FnMut::call_mut(&mut *x, ())` vs `FnMut::call_mut(&mut x, ())`. This is achieved by just autoderef'ing one time when calling something whose type is `&F` or `&mut F`.
2. Making the infinite recursion test in trait matching a bit more tailored. This involves adding a notion of "matching" types that looks to see if types are potentially unifiable (it's an approximation).
The PR also includes various small refactorings to the inference code that are aimed at moving the unification and other code into a library (I've got that particular change in a branch, these changes just lead the way there by removing unnecessary dependencies between the compiler and the more general unification code).
Note that per rust-lang/rfcs#1023, adding impls like these would be a breaking change in the future.
cc @japaric
cc @alexcrichton
cc @aturon
Fixes #23015.
This commit is contained in:
commit
debac97a10
35 changed files with 1635 additions and 1278 deletions
|
|
@ -23,10 +23,6 @@ pub fn main() {
|
|||
let f2: &Fat<[isize; 3]> = &f1;
|
||||
let f3: &Fat<[usize]> = f2;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `&Fat<[usize]>`
|
||||
//~| found `&Fat<[isize; 3]>`
|
||||
//~| expected usize
|
||||
//~| found isize
|
||||
|
||||
// With a trait.
|
||||
let f1 = Fat { ptr: Foo };
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
|
|||
// which fails to type check.
|
||||
|
||||
ss
|
||||
//~^ ERROR cannot infer
|
||||
//~| ERROR mismatched types
|
||||
//~^ ERROR lifetime of the source pointer does not outlive lifetime bound
|
||||
//~| ERROR cannot infer
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
|
|||
// `Box<SomeTrait>` defaults to a `'static` bound, so this return
|
||||
// is illegal.
|
||||
|
||||
ss.r //~ ERROR mismatched types
|
||||
ss.r //~ ERROR lifetime of the source pointer does not outlive lifetime bound
|
||||
}
|
||||
|
||||
fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
|
||||
|
|
@ -38,7 +38,7 @@ fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
|
|||
fn store1<'b>(ss: &mut SomeStruct, b: Box<SomeTrait+'b>) {
|
||||
// Here we override the lifetimes explicitly, and so naturally we get an error.
|
||||
|
||||
ss.r = b; //~ ERROR mismatched types
|
||||
ss.r = b; //~ ERROR lifetime of the source pointer does not outlive lifetime bound
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'b> {
|
|||
|
||||
fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
|
||||
// A outlives 'a AND 'b...but not 'c.
|
||||
box v as Box<SomeTrait+'a> //~ ERROR mismatched types
|
||||
box v as Box<SomeTrait+'a> //~ ERROR lifetime of the source pointer does not outlive
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ fn foo2<'a:'b,'b>(x: &'b mut (Dummy+'a)) -> &'b mut (Dummy+'b) {
|
|||
|
||||
fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
|
||||
// Without knowing 'a:'b, we can't coerce
|
||||
x //~ ERROR mismatched types
|
||||
x //~ ERROR lifetime of the source pointer does not outlive
|
||||
//~^ ERROR cannot infer
|
||||
}
|
||||
|
||||
|
|
|
|||
37
src/test/run-pass/unboxed-closures-blanket-fn-mut.rs
Normal file
37
src/test/run-pass/unboxed-closures-blanket-fn-mut.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 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.
|
||||
|
||||
// Test that you can supply `&F` where `F: FnMut()`.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(lang_items, unboxed_closures)]
|
||||
|
||||
fn a<F:FnMut() -> i32>(mut f: F) -> i32 {
|
||||
f()
|
||||
}
|
||||
|
||||
fn b(f: &mut FnMut() -> i32) -> i32 {
|
||||
a(f)
|
||||
}
|
||||
|
||||
fn c<F:FnMut() -> i32>(f: &mut F) -> i32 {
|
||||
a(f)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let z: isize = 7;
|
||||
|
||||
let x = b(&mut || 22);
|
||||
assert_eq!(x, 22);
|
||||
|
||||
let x = c(&mut || 22);
|
||||
assert_eq!(x, 22);
|
||||
}
|
||||
37
src/test/run-pass/unboxed-closures-blanket-fn.rs
Normal file
37
src/test/run-pass/unboxed-closures-blanket-fn.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 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.
|
||||
|
||||
// Test that you can supply `&F` where `F: Fn()`.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(lang_items, unboxed_closures)]
|
||||
|
||||
fn a<F:Fn() -> i32>(f: F) -> i32 {
|
||||
f()
|
||||
}
|
||||
|
||||
fn b(f: &Fn() -> i32) -> i32 {
|
||||
a(f)
|
||||
}
|
||||
|
||||
fn c<F:Fn() -> i32>(f: &F) -> i32 {
|
||||
a(f)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let z: isize = 7;
|
||||
|
||||
let x = b(&|| 22);
|
||||
assert_eq!(x, 22);
|
||||
|
||||
let x = c(&|| 22);
|
||||
assert_eq!(x, 22);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue