about summary refs log tree commit diff
diff options
context:
space:
mode:
authortiif <pekyuan@gmail.com>2025-07-14 13:38:36 +0000
committertiif <pekyuan@gmail.com>2025-07-15 13:48:30 +0000
commit7dd28181e2243c3715efc7e0ce49848bfd256c86 (patch)
treec844ba01aa9c2fea2b15dc00da6963655adbe6b8
parent7356ff7517f4d95583f8fd6d631441893c87dd3f (diff)
downloadrust-7dd28181e2243c3715efc7e0ce49848bfd256c86.tar.gz
rust-7dd28181e2243c3715efc7e0ce49848bfd256c86.zip
Add tests
-rw-r--r--tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs25
-rw-r--r--tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs19
-rw-r--r--tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs13
-rw-r--r--tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs11
-rw-r--r--tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs20
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs12
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr13
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr13
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs18
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs11
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr13
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs14
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr17
-rw-r--r--tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs42
-rw-r--r--tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr22
-rw-r--r--tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs28
-rw-r--r--tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr17
-rw-r--r--tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs30
-rw-r--r--tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs27
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr17
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs40
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs36
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr18
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs13
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr9
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_codegen.rs13
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr13
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr13
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_coherence.rs17
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs15
-rw-r--r--tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr14
31 files changed, 583 insertions, 0 deletions
diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs
new file mode 100644
index 00000000000..3749deb7627
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs
@@ -0,0 +1,25 @@
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+#[stable(feature = "a", since = "1.1.1" )]
+pub trait Foo {
+    #[stable(feature = "a", since = "1.1.1" )]
+    fn foo();
+}
+#[stable(feature = "a", since = "1.1.1" )]
+pub struct Bar;
+#[stable(feature = "a", since = "1.1.1" )]
+pub struct Moo;
+
+#[unstable_feature_bound(feat_bar)]
+#[unstable(feature = "feat_bar", issue = "none" )]
+impl Foo for Bar {
+    fn foo() {}
+}
+
+#[unstable_feature_bound(feat_moo)]
+#[unstable(feature = "feat_moo", issue = "none" )]
+impl Foo for Moo {
+    fn foo() {}
+}
diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs
new file mode 100644
index 00000000000..8c0d14a1bab
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs
@@ -0,0 +1,19 @@
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+/// Aux crate for unstable impl codegen test.
+
+#[stable(feature = "a", since = "1.1.1" )]
+pub trait Trait {
+    #[stable(feature = "a", since = "1.1.1" )]
+    fn method(&self);
+}
+
+#[unstable_feature_bound(foo)]
+#[unstable(feature = "foo", issue = "none" )]
+impl<T> Trait for T {
+    fn method(&self) {
+        println!("hi");
+    }
+}
diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs
new file mode 100644
index 00000000000..1b0e2b2eec3
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs
@@ -0,0 +1,13 @@
+//@ aux-build:unstable_impl_codegen_aux1.rs
+#![feature(foo)]
+
+extern crate unstable_impl_codegen_aux1 as aux;
+use aux::Trait;
+
+/// Upstream crate for unstable impl codegen test
+/// that depends on aux crate in
+/// unstable_impl_codegen_aux1.rs
+
+pub fn foo<T>(a: T) {
+    a.method();
+}
diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs
new file mode 100644
index 00000000000..2e055101216
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs
@@ -0,0 +1,11 @@
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+#[stable(feature = "a", since = "1.1.1" )]
+pub trait Trait {}
+
+#[unstable_feature_bound(foo)]
+#[unstable(feature = "foo", issue = "none" )]
+impl <T> Trait for T {}
diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs
new file mode 100644
index 00000000000..3a433007b5d
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs
@@ -0,0 +1,20 @@
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+#[stable(feature = "a", since = "1.1.1" )]
+pub trait Trait {
+    #[stable(feature = "a", since = "1.1.1" )]
+    fn foo(&self) {}
+}
+
+#[stable(feature = "a", since = "1.1.1" )]
+impl Trait for Vec<u32> {
+    fn foo(&self) {}
+}
+
+#[unstable_feature_bound(bar)]
+#[unstable(feature = "bar", issue = "none" )]
+impl Trait for Vec<u64> {
+    fn foo(&self) {}
+}
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs
new file mode 100644
index 00000000000..798c2d8562c
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs
@@ -0,0 +1,12 @@
+//@ aux-build:unstable_feature.rs
+extern crate unstable_feature;
+use unstable_feature::{Foo, Bar, Moo};
+
+// FIXME: both `feat_bar` and `feat_moo` are needed to pass this test,
+// but the diagnostic only will point out `feat_bar`.
+
+fn main() {
+    Bar::foo();
+    //~^ ERROR: use of unstable library feature `feat_bar` [E0658]
+    Moo::foo();
+}
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr
new file mode 100644
index 00000000000..673d10ce2ad
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature `feat_bar`
+  --> $DIR/unstable-feature-bound-two-error.rs:9:5
+   |
+LL |     Bar::foo();
+   |     ^^^
+   |
+   = help: add `#![feature(feat_bar)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = note: required for `Bar` to implement `Foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr
new file mode 100644
index 00000000000..ce8d7358cfc
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature `feat_moo`
+  --> $DIR/unstable-feature-cross-crate-exact-symbol.rs:16:5
+   |
+LL |     Moo::foo();
+   |     ^^^
+   |
+   = help: add `#![feature(feat_moo)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = note: required for `Moo` to implement `Foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs
new file mode 100644
index 00000000000..a427bb8eb7e
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs
@@ -0,0 +1,18 @@
+//@ aux-build:unstable_feature.rs
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![cfg_attr(pass, feature(feat_bar, feat_moo))]
+#![cfg_attr(fail, feature(feat_bar))]
+
+extern crate unstable_feature;
+use unstable_feature::{Foo, Bar, Moo};
+
+/// To use impls gated by both `feat_foo` and `feat_moo`,
+/// both features must be enabled.
+
+fn main() {
+    Bar::foo();
+    Moo::foo();
+    //[fail]~^ ERROR:use of unstable library feature `feat_moo` [E0658]
+}
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs
new file mode 100644
index 00000000000..5b09c898a08
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs
@@ -0,0 +1,11 @@
+//@ aux-build:unstable_feature.rs
+//@ check-pass
+#![feature(feat_bar, feat_moo)]
+extern crate unstable_feature;
+use unstable_feature::{Foo, Bar};
+
+/// Bar::foo() should still be usable even if we enable multiple feature.
+
+fn main() {
+    Bar::foo();
+}
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr
new file mode 100644
index 00000000000..87a2ad41fc1
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature `feat_bar`
+  --> $DIR/unstable-feature-cross-crate-require-bound.rs:12:5
+   |
+LL |     Bar::foo();
+   |     ^^^
+   |
+   = help: add `#![feature(feat_bar)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = note: required for `Bar` to implement `Foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs
new file mode 100644
index 00000000000..8be214b5324
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs
@@ -0,0 +1,14 @@
+//@ aux-build:unstable_feature.rs
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![cfg_attr(pass, feature(feat_bar))]
+extern crate unstable_feature;
+use unstable_feature::{Foo, Bar};
+
+/// #[feature(..)] is required to use unstable impl.
+
+fn main() {
+    Bar::foo();
+    //[fail]~^ ERROR: use of unstable library feature `feat_bar` [E0658]
+}
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr
new file mode 100644
index 00000000000..b8cb63ec65f
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr
@@ -0,0 +1,17 @@
+error: unstable feature `feat_moo` is used without being enabled.
+  --> $DIR/unstable-feature-exact-symbol.rs:37:5
+   |
+LL |     Bar::moo();
+   |     ^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_moo)]`
+note: required for `Bar` to implement `Moo`
+  --> $DIR/unstable-feature-exact-symbol.rs:29:6
+   |
+LL | #[unstable_feature_bound(feat_moo)]
+   | ----------------------------------- unsatisfied trait bound introduced here
+LL | impl Moo for Bar {
+   |      ^^^     ^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs
new file mode 100644
index 00000000000..2de9e6a857e
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs
@@ -0,0 +1,42 @@
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![unstable(feature = "feat_foo", issue = "none" )]
+
+/// In staged-api crate, impl that is marked as unstable with
+/// feature name `feat_moo` should not be accessible
+/// if only `feat_foo` is enabled.
+
+pub trait Foo {
+    fn foo();
+}
+
+pub trait Moo {
+    fn moo();
+}
+
+pub struct Bar;
+
+#[unstable_feature_bound(feat_foo)]
+impl Foo for Bar {
+    fn foo() {}
+}
+
+#[unstable_feature_bound(feat_moo)]
+impl Moo for Bar {
+    fn moo() {}
+}
+
+#[cfg_attr(fail, unstable_feature_bound(feat_foo))]
+#[cfg_attr(pass, unstable_feature_bound(feat_foo, feat_moo))]
+fn bar() {
+    Bar::foo();
+    Bar::moo();
+    //[fail]~^ ERROR  unstable feature `feat_moo` is used without being enabled.
+
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr
new file mode 100644
index 00000000000..db9759b4cc3
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr
@@ -0,0 +1,22 @@
+error: unstable feature `feat_foo` is used without being enabled.
+  --> $DIR/unstable-impl-assoc-type.rs:23:16
+   |
+LL |   type Assoc = Self;
+   |                ^^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_foo)]`
+note: required for `Foo` to implement `Bar`
+  --> $DIR/unstable-impl-assoc-type.rs:19:6
+   |
+LL | #[unstable_feature_bound(feat_foo)]
+   | ----------------------------------- unsatisfied trait bound introduced here
+LL | impl Bar for Foo {}
+   |      ^^^     ^^^
+note: required by a bound in `Trait::Assoc`
+  --> $DIR/unstable-impl-assoc-type.rs:13:17
+   |
+LL |     type Assoc: Bar;
+   |                 ^^^ required by this bound in `Trait::Assoc`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs
new file mode 100644
index 00000000000..e31dc688dfa
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs
@@ -0,0 +1,28 @@
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![unstable(feature = "feat_foo", issue = "none" )]
+
+/// Test that you can't leak unstable impls through item bounds on associated types.
+
+trait Bar {}
+
+trait Trait {
+    type Assoc: Bar;
+}
+
+struct Foo;
+
+#[unstable_feature_bound(feat_foo)]
+impl Bar for Foo {}
+
+#[cfg_attr(pass, unstable_feature_bound(feat_foo))]
+impl Trait for Foo {
+  type Assoc = Self;
+  //[fail]~^ ERROR: unstable feature `feat_foo` is used without being enabled.
+
+}
+
+fn main(){}
diff --git a/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr
new file mode 100644
index 00000000000..d56072362fe
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr
@@ -0,0 +1,17 @@
+error: unstable feature `feat_foo` is used without being enabled.
+  --> $DIR/unstable-impl-cannot-use-feature.rs:26:5
+   |
+LL |     Bar::foo();
+   |     ^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_foo)]`
+note: required for `Bar` to implement `Foo`
+  --> $DIR/unstable-impl-cannot-use-feature.rs:20:6
+   |
+LL | #[unstable_feature_bound(feat_foo)]
+   | ----------------------------------- unsatisfied trait bound introduced here
+LL | impl Foo for Bar {
+   |      ^^^     ^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs
new file mode 100644
index 00000000000..0da618445fd
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs
@@ -0,0 +1,30 @@
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![unstable(feature = "feat_foo", issue = "none" )]
+
+#![cfg_attr(fail, feature(feat_foo))]
+
+/// In staged-api crate, using an unstable impl requires
+/// #[unstable_feature_bound(..)], not  #[feature(..)].
+
+pub trait Foo {
+    fn foo();
+}
+pub struct Bar;
+
+#[unstable_feature_bound(feat_foo)]
+impl Foo for Bar {
+    fn foo() {}
+}
+
+#[cfg_attr(pass, unstable_feature_bound(feat_foo))]
+fn bar() {
+    Bar::foo();
+    //[fail]~^ ERROR: unstable feature `feat_foo` is used without being enabled.
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs b/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs
new file mode 100644
index 00000000000..c9a9029b0a0
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![unstable(feature = "feat_foo", issue = "none" )]
+
+/// In staged-api crate, if feat_foo is only needed to use an impl,
+/// having both `feat_foo` and `feat_bar` will still make it pass.
+
+pub trait Foo {
+    fn foo();
+}
+pub struct Bar;
+
+// Annotate the impl as unstable.
+#[unstable_feature_bound(feat_foo)]
+impl Foo for Bar {
+    fn foo() {}
+}
+
+#[unstable_feature_bound(feat_foo, feat_bar)]
+fn bar() {
+    Bar::foo();
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr
new file mode 100644
index 00000000000..f8354256828
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr
@@ -0,0 +1,17 @@
+error: unstable feature `feat_bar` is used without being enabled.
+  --> $DIR/unstable_feature_bound_free_fn.rs:36:5
+   |
+LL |     bar();
+   |     ^^^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_bar)]`
+note: required by a bound in `bar`
+  --> $DIR/unstable_feature_bound_free_fn.rs:29:1
+   |
+LL | #[unstable_feature_bound(feat_bar)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `bar`
+LL | fn bar() {
+   |    --- required by a bound in this function
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs
new file mode 100644
index 00000000000..30e2ab3d65e
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs
@@ -0,0 +1,40 @@
+//@ revisions: pass fail
+//@[pass] check-pass
+
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![stable(feature = "a", since = "1.1.1" )]
+
+/// When a free function with #[unstable_feature_bound(feat_bar)] is called by another
+/// free function, that function should be annotated with
+/// #[unstable_feature_bound(feat_bar)] too.
+
+#[stable(feature = "a", since = "1.1.1")]
+trait Foo {
+    #[stable(feature = "a", since = "1.1.1")]
+    fn foo() {
+    }
+}
+#[stable(feature = "a", since = "1.1.1")]
+pub struct Bar;
+
+#[unstable_feature_bound(feat_bar)]
+#[unstable(feature = "feat_bar", issue = "none" )]
+impl Foo for Bar {
+    fn foo() {}
+}
+
+
+#[unstable_feature_bound(feat_bar)]
+fn bar() {
+    Bar::foo();
+}
+
+#[cfg_attr(pass, unstable_feature_bound(feat_bar))]
+fn bar2() {
+    bar();
+    //[fail]~^ERROR unstable feature `feat_bar` is used without being enabled.
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs
new file mode 100644
index 00000000000..3d6b52ba517
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs
@@ -0,0 +1,36 @@
+#![allow(internal_features)]
+#![feature(staged_api)]
+#![allow(dead_code)]
+#![unstable(feature = "feat_bar", issue = "none" )]
+
+/// Test the behaviour of multiple unstable_feature_bound attribute.
+
+trait Foo {
+    fn foo();
+}
+struct Bar;
+
+#[unstable_feature_bound(feat_bar, feat_koo)]
+#[unstable_feature_bound(feat_foo, feat_moo)]
+impl Foo for Bar {
+    fn foo(){}
+}
+
+#[unstable_feature_bound(feat_bar, feat_koo)]
+#[unstable_feature_bound(feat_foo, feat_moo)]
+fn moo() {
+    Bar::foo();
+}
+
+#[unstable_feature_bound(feat_bar, feat_koo, feat_foo, feat_moo)]
+fn koo() {
+    Bar::foo();
+}
+
+#[unstable_feature_bound(feat_koo, feat_foo, feat_moo)]
+fn boo() {
+    Bar::foo();
+    //~^ ERROR: unstable feature `feat_bar` is used without being enabled.
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr
new file mode 100644
index 00000000000..936c70c1979
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr
@@ -0,0 +1,18 @@
+error: unstable feature `feat_bar` is used without being enabled.
+  --> $DIR/unstable_feature_bound_multi_attr.rs:32:5
+   |
+LL |     Bar::foo();
+   |     ^^^
+   |
+   = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_bar)]`
+note: required for `Bar` to implement `Foo`
+  --> $DIR/unstable_feature_bound_multi_attr.rs:15:6
+   |
+LL | #[unstable_feature_bound(feat_bar, feat_koo)]
+   | --------------------------------------------- unsatisfied trait bound introduced here
+LL | #[unstable_feature_bound(feat_foo, feat_moo)]
+LL | impl Foo for Bar {
+   |      ^^^     ^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs
new file mode 100644
index 00000000000..51e388f7dd3
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs
@@ -0,0 +1,13 @@
+/// Unstable feature bound can only be used only when
+/// #[feature(staged_api)] is enabled.
+
+pub trait Foo {
+}
+pub struct Bar;
+
+#[unstable_feature_bound(feat_bar)]
+//~^ ERROR: stability attributes may not be used outside of the standard library
+impl Foo for Bar {
+}
+
+fn main(){}
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr
new file mode 100644
index 00000000000..35ab89e6ad9
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr
@@ -0,0 +1,9 @@
+error[E0734]: stability attributes may not be used outside of the standard library
+  --> $DIR/unstable_feature_bound_staged_api.rs:8:1
+   |
+LL | #[unstable_feature_bound(feat_bar)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0734`.
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs b/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs
new file mode 100644
index 00000000000..285a64d2250
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs
@@ -0,0 +1,13 @@
+//@ aux-build:unstable_impl_codegen_aux2.rs
+//@ run-pass
+
+/// Downstream crate for unstable impl codegen test
+/// that depends on upstream crate in
+/// unstable_impl_codegen_aux2.rs
+
+extern crate unstable_impl_codegen_aux2 as aux;
+use aux::foo;
+
+fn main() {
+    foo(1_u8);
+}
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr
new file mode 100644
index 00000000000..c3147558b03
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy`
+  --> $DIR/unstable_impl_coherence.rs:14:1
+   |
+LL | impl aux::Trait for LocalTy {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `unstable_impl_coherence_aux`:
+           - impl<T> Trait for T
+             where unstable feature: `foo`;
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr
new file mode 100644
index 00000000000..c3147558b03
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy`
+  --> $DIR/unstable_impl_coherence.rs:14:1
+   |
+LL | impl aux::Trait for LocalTy {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `unstable_impl_coherence_aux`:
+           - impl<T> Trait for T
+             where unstable feature: `foo`;
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs
new file mode 100644
index 00000000000..22100f85f71
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs
@@ -0,0 +1,17 @@
+//@ aux-build:unstable_impl_coherence_aux.rs
+//@ revisions: enabled disabled
+
+#![cfg_attr(enabled, feature(foo))]
+extern crate unstable_impl_coherence_aux as aux;
+use aux::Trait;
+
+/// Coherence test for unstable impl.
+/// No matter feature `foo` is enabled or not, the impl
+/// for aux::Trait will be rejected by coherence checking.
+
+struct LocalTy;
+
+impl aux::Trait for LocalTy {}
+//~^ ERROR: conflicting implementations of trait `Trait` for type `LocalTy`
+
+fn main(){}
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs
new file mode 100644
index 00000000000..acf521d3130
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs
@@ -0,0 +1,15 @@
+//@ aux-build:unstable_impl_method_selection_aux.rs
+
+extern crate unstable_impl_method_selection_aux as aux;
+use aux::Trait;
+
+// The test below should not infer the type based on the fact
+// that `impl Trait for Vec<u64>` is unstable. This would cause breakage
+// in downstream crate once `impl Trait for Vec<u64>` is stabilised.
+
+fn bar() {
+    vec![].foo();
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr
new file mode 100644
index 00000000000..c2bb10f043b
--- /dev/null
+++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr
@@ -0,0 +1,14 @@
+error[E0283]: type annotations needed
+  --> $DIR/unstable_impl_method_selection.rs:11:12
+   |
+LL |     vec![].foo();
+   |            ^^^ cannot infer type for struct `Vec<_>`
+   |
+   = note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate:
+           - impl Trait for Vec<u32>;
+           - impl Trait for Vec<u64>
+             where unstable feature: `bar`;
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0283`.