about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-08-07 13:25:23 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-08-12 17:58:22 -0400
commit788a802dad3f273b74150b732d24d37a695d29f6 (patch)
treeaf418f292ef4e3fe2c3317543c4b2e49486772c9
parentd15997750211421cc1367faba574b3d9b2dc2432 (diff)
downloadrust-788a802dad3f273b74150b732d24d37a695d29f6.tar.gz
rust-788a802dad3f273b74150b732d24d37a695d29f6.zip
New tests --- projection outlives relation
-rw-r--r--src/test/compile-fail/associated-types-outlives.rs38
-rw-r--r--src/test/compile-fail/regions-close-associated-type-into-object.rs9
-rw-r--r--src/test/compile-fail/regions-implied-bounds-projection-gap-1.rs40
-rw-r--r--src/test/compile-fail/regions-implied-bounds-projection-gap-2.rs33
-rw-r--r--src/test/compile-fail/regions-implied-bounds-projection-gap-3.rs33
-rw-r--r--src/test/compile-fail/regions-implied-bounds-projection-gap-4.rs33
-rw-r--r--src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs39
-rw-r--r--src/test/compile-fail/regions-outlives-nominal-type-enum.rs56
-rw-r--r--src/test/compile-fail/regions-outlives-nominal-type-struct.rs56
-rw-r--r--src/test/compile-fail/regions-outlives-projection-container-hrtb.rs (renamed from src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs)11
-rw-r--r--src/test/compile-fail/regions-outlives-projection-container-wc.rs (renamed from src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs)0
-rw-r--r--src/test/compile-fail/regions-outlives-projection-container.rs (renamed from src/test/compile-fail/regions-assoc-type-outlives-container.rs)11
-rw-r--r--src/test/compile-fail/regions-outlives-projection-trait-def.rs31
-rw-r--r--src/test/compile-fail/regions-outlives-scalar.rs23
-rw-r--r--src/test/compile-fail/traits-issue-23003-overflow.rs15
15 files changed, 405 insertions, 23 deletions
diff --git a/src/test/compile-fail/associated-types-outlives.rs b/src/test/compile-fail/associated-types-outlives.rs
new file mode 100644
index 00000000000..f070ab6799c
--- /dev/null
+++ b/src/test/compile-fail/associated-types-outlives.rs
@@ -0,0 +1,38 @@
+// Copyright 2015 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.
+
+// Regression test for issue #24622. The older associated types code
+// was erroneously assuming that all projections outlived the current
+// fn body, causing this (invalid) code to be accepted.
+
+pub trait Foo<'a> {
+    type Bar;
+}
+
+impl<'a, T:'a> Foo<'a> for T {
+    type Bar = &'a T;
+}
+
+fn denormalise<'a, T>(t: &'a T) -> <T as Foo<'a>>::Bar {
+    t
+}
+
+pub fn free_and_use<T: for<'a> Foo<'a>,
+                    F: for<'a> FnOnce(<T as Foo<'a>>::Bar)>(x: T, f: F) {
+    let y;
+    'body: loop { // lifetime annotations added for clarity
+        's: loop { y = denormalise(&x); break }
+        drop(x); //~ ERROR cannot move out of `x` because it is borrowed
+        return f(y);
+    }
+}
+
+pub fn main() {
+}
diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs
index fdc97ecaf21..61897aac187 100644
--- a/src/test/compile-fail/regions-close-associated-type-into-object.rs
+++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs
@@ -72,13 +72,12 @@ fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
     where T::Item : Clone
 {
     // This case is kind of interesting. It's the same as `ok3` but
-    // without the explicit declaration. In principle, it seems like
-    // we ought to be able to infer that `T::Item : 'a` because we
-    // invoked `v.as_self()` which yielded a value of type `&'a
-    // T::Item`. But we're not that smart at present.
+    // without the explicit declaration. This is valid because `T: 'a
+    // => T::Item: 'a`, and the former we can deduce from our argument
+    // of type `&'a T`.
 
     let item = Clone::clone(v.as_item());
-    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live
+    Box::new(item)
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-1.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-1.rs
new file mode 100644
index 00000000000..65594ab8f2e
--- /dev/null
+++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-1.rs
@@ -0,0 +1,40 @@
+// 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.
+
+// Illustrates the "projection gap": in this test, even though we know
+// that `T::Foo: 'x`, that does not tell us that `T: 'x`, because
+// there might be other ways for the caller of `func` to show that
+// `T::Foo: 'x` holds (e.g., where-clause).
+
+trait Trait1<'x> {
+    type Foo;
+}
+
+// calling this fn should trigger a check that the type argument
+// supplied is well-formed.
+fn wf<T>() { }
+
+fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
+{
+    wf::<&'x T>();
+    //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn caller2<'x, T:Trait1<'x>>(t: &'x T)
+{
+    wf::<&'x T::Foo>(); // OK
+}
+
+fn caller3<'x, T:Trait1<'x>>(t: &'x T::Foo)
+{
+    wf::<&'x T::Foo>(); // OK
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-2.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-2.rs
new file mode 100644
index 00000000000..b3037a1e187
--- /dev/null
+++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-2.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Along with the other tests in this series, illustrates the
+// "projection gap": in this test, we know that `T: 'x`, and that is
+// enough to conclude that `T::Foo: 'x`.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+trait Trait1<'x> {
+    type Foo;
+}
+
+// calling this fn should trigger a check that the type argument
+// supplied is well-formed.
+fn wf<T>() { }
+
+fn func<'x, T:Trait1<'x>>(t: &'x T)
+{
+    wf::<&'x T::Foo>();
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-3.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-3.rs
new file mode 100644
index 00000000000..a2e6de21376
--- /dev/null
+++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-3.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Along with the other tests in this series, illustrates the
+// "projection gap": in this test, we know that `T::Foo: 'x`, and that
+// is (naturally) enough to conclude that `T::Foo: 'x`.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+trait Trait1<'x> {
+    type Foo;
+}
+
+// calling this fn should trigger a check that the type argument
+// supplied is well-formed.
+fn wf<T>() { }
+
+fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
+{
+    wf::<&'x T::Foo>();
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-4.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-4.rs
new file mode 100644
index 00000000000..b8582f8c26b
--- /dev/null
+++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-4.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Along with the other tests in this series, illustrates the
+// "projection gap": in this test, we know that `T: 'x`, and that
+// is (naturally) enough to conclude that `T: 'x`.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+trait Trait1<'x> {
+    type Foo;
+}
+
+// calling this fn should trigger a check that the type argument
+// supplied is well-formed.
+fn wf<T>() { }
+
+fn func<'x, T:Trait1<'x>>(t: &'x T)
+{
+    wf::<&'x T>();
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs
new file mode 100644
index 00000000000..47985f931dd
--- /dev/null
+++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs
@@ -0,0 +1,39 @@
+// 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.
+
+// The "projection gap" is particularly "fun" around higher-ranked
+// projections.  This is because the current code is hard-coded to say
+// that a projection that contains escaping regions, like `<T as
+// Trait2<'y, 'z>>::Foo` where `'z` is bound, can only be found to
+// outlive a region if all components that appear free (`'y`, where)
+// outlive that region. However, we DON'T add those components to the
+// implied bounds set, but rather we treat projections with escaping
+// regions as opaque entities, just like projections without escaping
+// regions.
+
+trait Trait1<T> { }
+
+trait Trait2<'a, 'b> {
+    type Foo;
+}
+
+fn wf<T>() { }
+
+// As a side-effect of the conservative process above, this argument
+// is not automatically considered well-formed, since for it to be WF,
+// we would need to know that `'y: 'x`, but we do not infer that.
+fn callee<'x, 'y, T>(
+    t: &'x for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
+{
+    wf::<&'x &'y i32>();
+    //~^ ERROR reference has a longer lifetime than the data it references
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/regions-outlives-nominal-type-enum.rs b/src/test/compile-fail/regions-outlives-nominal-type-enum.rs
new file mode 100644
index 00000000000..6fb409326f1
--- /dev/null
+++ b/src/test/compile-fail/regions-outlives-nominal-type-enum.rs
@@ -0,0 +1,56 @@
+// 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 a nominal type (like `Foo<'a>`) outlives `'b` if its
+// arguments (like `'a`) outlive `'b`.
+//
+// Rule OutlivesNominalType from RFC 1214.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+mod variant_enum_region {
+    enum Foo<'a> {
+        V { x: &'a i32 }
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<'b>
+    }
+}
+
+mod rev_variant_enum_region {
+    enum Foo<'a> {
+        V { x: fn(&'a i32) }
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<'b>
+    }
+}
+
+mod variant_enum_type {
+    enum Foo<T> {
+        V { x: T }
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<&'b i32>
+    }
+}
+
+mod rev_variant_enum_type {
+    enum Foo<T> {
+        V { x: fn(T) }
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<&'b i32>
+    }
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/regions-outlives-nominal-type-struct.rs b/src/test/compile-fail/regions-outlives-nominal-type-struct.rs
new file mode 100644
index 00000000000..fb3fdddae88
--- /dev/null
+++ b/src/test/compile-fail/regions-outlives-nominal-type-struct.rs
@@ -0,0 +1,56 @@
+// 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 a nominal type (like `Foo<'a>`) outlives `'b` if its
+// arguments (like `'a`) outlive `'b`.
+//
+// Rule OutlivesNominalType from RFC 1214.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+mod variant_struct_region {
+    struct Foo<'a> {
+        x: &'a i32,
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<'b>
+    }
+}
+
+mod rev_variant_struct_region {
+    struct Foo<'a> {
+        x: fn(&'a i32),
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<'b>
+    }
+}
+
+mod variant_struct_type {
+    struct Foo<T> {
+        x: T
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<&'b i32>
+    }
+}
+
+mod rev_variant_struct_type {
+    struct Foo<T> {
+        x: fn(T)
+    }
+    struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
+        f: &'a Foo<&'b i32>
+    }
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-outlives-projection-container-hrtb.rs
index 0d3d2e296be..b8c4a7f8a8c 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
+++ b/src/test/compile-fail/regions-outlives-projection-container-hrtb.rs
@@ -37,10 +37,10 @@ pub struct WithHrAssoc<T>
 }
 
 fn with_assoc<'a,'b>() {
-    // We get no error here because the where clause has a higher-ranked assoc type,
-    // which could not be projected from.
+    // We get an error because beacuse 'b:'a does not hold:
 
     let _: &'a WithHrAssoc<TheType<'b>> = loop { };
+    //~^ ERROR reference has a longer lifetime
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -57,12 +57,13 @@ pub struct WithHrAssocSub<T>
 }
 
 fn with_assoc_sub<'a,'b>() {
-    // Same here, because although the where clause is not HR, it
-    // extends a trait in a HR way.
+    // The error here is just because `'b:'a` must hold for the type
+    // below to be well-formed, it is not related to the HR relation.
 
     let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
+    //~^ ERROR reference has a longer lifetime
 }
 
 #[rustc_error]
-fn main() { //~ ERROR compilation successful
+fn main() {
 }
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-outlives-projection-container-wc.rs
index 2ceaea98d27..2ceaea98d27 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
+++ b/src/test/compile-fail/regions-outlives-projection-container-wc.rs
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-outlives-projection-container.rs
index e3e57ff1711..6f5ebf2d1ce 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs
+++ b/src/test/compile-fail/regions-outlives-projection-container.rs
@@ -59,11 +59,10 @@ fn with_assoc1<'a,'b>() where 'b : 'a {
 }
 
 fn without_assoc<'a,'b>() {
-    // Here there are no associated types and the `'b` appearing in
-    // `TheType<'b>` is purely covariant, so there is no requirement
-    // that `'b:'a` holds.
+    // Here there are no associated types but there is a requirement
+    // that `'b:'a` holds because the `'b` appears in `TheType<'b>`.
 
-    let _: &'a WithoutAssoc<TheType<'b>> = loop { };
+    let _: &'a WithoutAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
 }
 
 fn call_with_assoc<'a,'b>() {
@@ -72,13 +71,13 @@ fn call_with_assoc<'a,'b>() {
     // no data.
 
     call::<&'a WithAssoc<TheType<'b>>>();
-    //~^ ERROR cannot infer
+    //~^ ERROR reference has a longer lifetime
 }
 
 fn call_without_assoc<'a,'b>() {
     // As `without_assoc`, but in a distinct scenario.
 
-    call::<&'a WithoutAssoc<TheType<'b>>>();
+    call::<&'a WithoutAssoc<TheType<'b>>>(); //~ ERROR reference has a longer lifetime
 }
 
 fn call<T>() { }
diff --git a/src/test/compile-fail/regions-outlives-projection-trait-def.rs b/src/test/compile-fail/regions-outlives-projection-trait-def.rs
new file mode 100644
index 00000000000..04682a77297
--- /dev/null
+++ b/src/test/compile-fail/regions-outlives-projection-trait-def.rs
@@ -0,0 +1,31 @@
+// 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 `<F as Foo<'a>>::Type: 'b`, where `trait Foo<'a> { Type:
+// 'a; }`, does not require that `F: 'b`.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+trait SomeTrait<'a> {
+    type Type: 'a;
+}
+
+impl<'a: 'c, 'c, T> SomeTrait<'a> for &'c T where T: SomeTrait<'a> {
+    type Type = <T as SomeTrait<'a>>::Type;
+    //          ~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //                       |
+    // Note that this type must outlive 'a, due to the trait
+    // definition.  If we fall back to OutlivesProjectionComponents
+    // here, then we would require that `T:'a`, which is too strong.
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/regions-outlives-scalar.rs b/src/test/compile-fail/regions-outlives-scalar.rs
new file mode 100644
index 00000000000..94f7a350cf7
--- /dev/null
+++ b/src/test/compile-fail/regions-outlives-scalar.rs
@@ -0,0 +1,23 @@
+// 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 scalar values outlive all regions.
+// Rule OutlivesScalar from RFC 1214.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+struct Foo<'a> {
+    x: &'a i32,
+    y: &'static i32
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/traits-issue-23003-overflow.rs b/src/test/compile-fail/traits-issue-23003-overflow.rs
index ea41775f310..80d2884ee60 100644
--- a/src/test/compile-fail/traits-issue-23003-overflow.rs
+++ b/src/test/compile-fail/traits-issue-23003-overflow.rs
@@ -9,10 +9,11 @@
 // except according to those terms.
 
 // A variant of traits-issue-23003 in which an infinite series of
-// types are required. This currently creates an overflow. This test
-// is included to ensure that some controlled failure, at least,
-// results -- but it might be that we should adjust the rules somewhat
-// to make this legal. -nmatsakis
+// types are required. This test now just compiles fine, since the
+// relevant rules that triggered the overflow were removed.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
 
 use std::marker::PhantomData;
 
@@ -32,7 +33,7 @@ impl<B> Async for Complete<B> {
     type Cancel = Receipt<Complete<Option<B>>>;
 }
 
-fn foo(r: Receipt<Complete<()>>) { }
-//~^ ERROR overflow
+fn foo(_: Receipt<Complete<()>>) { }
 
-fn main() { }
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful