auto merge of #18688 : bkoropoff/rust/unboxed-closure-subst-fixes, r=nikomatsakis

This resolves some issues that remained after adding support for monomorphizing unboxed closures in trans.

There were a few places where a set of substitutions for an unboxed closure type were dropped on the floor and later recalculated from scratch based on the def ID, but this failed spectacularly when the closure originated from a different param environment.  The substitutions are now plumbed through end-to-end.  Closes #18661

There was also a conflict in the meaning of the self param space within the body of the unboxed closure.  Trans attempted to insert the unboxed closure type as the self type, but this could conflict with the self type from the param environment when an unboxed closure was used within a default method on a trait.  Since the body of an unboxed closure cannot refer to its own self type or value, there's no need for it to actually use the self space.  The downstream consumers of the substitutions in trans do not seem to need it either since they look up the type of the closure some other way, so I just stopped setting it.  Closes #18685.

r? @pcwalton @nikomatsakis
This commit is contained in:
bors 2014-11-07 20:41:29 +00:00
commit 6ee56c9a5f
9 changed files with 99 additions and 50 deletions

View file

@ -0,0 +1,28 @@
// 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 param substitutions from the correct environment are
// used when translating unboxed closure calls.
#![feature(unboxed_closures)]
pub fn inside<F: Fn()>(c: F) {
c.call(());
}
// Use different number of type parameters and closure type to trigger
// an obvious ICE when param environments are mixed up
pub fn outside<A,B>() {
inside(|&:| {});
}
fn main() {
outside::<(),()>();
}

View file

@ -0,0 +1,30 @@
// 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 the self param space is not used in a conflicting
// manner by unboxed closures within a default method on a trait
#![feature(unboxed_closures, overloaded_calls)]
trait Tr {
fn foo(&self);
fn bar(&self) {
(|:| { self.foo() })()
}
}
impl Tr for () {
fn foo(&self) {}
}
fn main() {
().bar();
}