about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-10-25 07:19:07 +0200
committerMazdak Farrokhzad <twingoow@gmail.com>2019-11-06 07:34:51 +0100
commit1c7595fd0f509637e8da61e3bac425e4f3fd69fa (patch)
tree34326c1a796ae230ed054add7f215cb48b84d6aa
parente4931eaaa3d95189b30e90d3af9f0db17c41bbb0 (diff)
downloadrust-1c7595fd0f509637e8da61e3bac425e4f3fd69fa.tar.gz
rust-1c7595fd0f509637e8da61e3bac425e4f3fd69fa.zip
gate rustc_on_unimplemented under rustc_attrs
-rw-r--r--src/doc/unstable-book/src/language-features/on-unimplemented.md154
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/librustc/error_codes.rs6
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libsyntax/feature_gate/active.rs3
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs15
-rw-r--r--src/libsyntax/feature_gate/removed.rs3
-rw-r--r--src/test/incremental/issue-59523-on-implemented-is-not-unused.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-on-unimplemented.rs9
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.rs2
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.rs2
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs8
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr (renamed from src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr)8
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-trait.rs2
17 files changed, 34 insertions, 190 deletions
diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md
deleted file mode 100644
index 8db241e4b4e..00000000000
--- a/src/doc/unstable-book/src/language-features/on-unimplemented.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# `on_unimplemented`
-
-The tracking issue for this feature is: [#29628]
-
-[#29628]: https://github.com/rust-lang/rust/issues/29628
-
-------------------------
-
-The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
-attribute, which allows trait definitions to add specialized notes to error
-messages when an implementation was expected but not found. You can refer
-to the trait's generic arguments by name and to the resolved type using
-`Self`.
-
-For example:
-
-```rust,compile_fail
-#![feature(on_unimplemented)]
-
-#[rustc_on_unimplemented="an iterator over elements of type `{A}` \
-    cannot be built from a collection of type `{Self}`"]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-
-fn iterate_chars<I: MyIterator<char>>(i: I) {
-    // ...
-}
-
-fn main() {
-    iterate_chars(&[1, 2, 3][..]);
-}
-```
-
-When the user compiles this, they will see the following;
-
-```txt
-error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]`
-   |
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-`on_unimplemented` also supports advanced filtering for better targeting
-of messages, as well as modifying specific parts of the error message. You
-target the text of:
-
- - the main error message (`message`)
- - the label (`label`)
- - an extra note (`note`)
-
-For example, the following attribute
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    message="message",
-    label="label",
-    note="note"
-)]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-```
-
-Would generate the following output:
-
-```text
-error[E0277]: message
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ label
-   |
-   = note: note
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-To allow more targeted error messages, it is possible to filter the
-application of these fields based on a variety of attributes when using
-`on`:
-
- - `crate_local`: whether the code causing the trait bound to not be
-   fulfilled is part of the user's crate. This is used to avoid suggesting
-   code changes that would require modifying a dependency.
- - Any of the generic arguments that can be substituted in the text can be
-   referred by name as well for filtering, like `Rhs="i32"`, except for
-   `Self`.
- - `_Self`: to filter only on a particular calculated trait resolution, like
-   `Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
-   keyword which cannot appear in attributes.
- - `direct`: user-specified rather than derived obligation.
- - `from_method`: usable both as boolean (whether the flag is present, like
-   `crate_local`) or matching against a particular method. Currently used
-   for `try`.
- - `from_desugaring`: usable both as boolean (whether the flag is present)
-   or matching against a particular desugaring. The desugaring is identified
-   with its variant name in the `DesugaringKind` enum.
-
-For example, the `Iterator` trait can be annotated in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        _Self="&str",
-        note="call `.chars()` or `.as_bytes()` on `{Self}"
-    ),
-    message="`{Self}` is not an iterator",
-    label="`{Self}` is not an iterator",
-    note="maybe try calling `.iter()` or a similar method"
-)]
-pub trait Iterator {}
-```
-
-Which would produce the following outputs:
-
-```text
-error[E0277]: `Foo` is not an iterator
- --> src/main.rs:4:16
-  |
-4 |     for foo in Foo {}
-  |                ^^^ `Foo` is not an iterator
-  |
-  = note: maybe try calling `.iter()` or a similar method
-  = help: the trait `std::iter::Iterator` is not implemented for `Foo`
-  = note: required by `std::iter::IntoIterator::into_iter`
-
-error[E0277]: `&str` is not an iterator
- --> src/main.rs:5:16
-  |
-5 |     for foo in "" {}
-  |                ^^ `&str` is not an iterator
-  |
-  = note: call `.chars()` or `.bytes() on `&str`
-  = help: the trait `std::iter::Iterator` is not implemented for `&str`
-  = note: required by `std::iter::IntoIterator::into_iter`
-```
-
-If you need to filter on multiple attributes, you can use `all`, `any` or
-`not` in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        all(_Self="&str", T="std::string::String"),
-        note="you can coerce a `{T}` into a `{Self}` by writing `&*variable`"
-    )
-)]
-pub trait From<T>: Sized { /* ... */ }
-```
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 94379afc2bd..ddfa6797a57 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -116,7 +116,7 @@
 #![feature(unsize)]
 #![feature(unsized_locals)]
 #![feature(allocator_internals)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(rustc_const_unstable)]
 #![feature(slice_partition_dedup)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice)]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 1b67b05c730..ca431627147 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -89,7 +89,7 @@
 #![feature(nll)]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(prelude_import)]
 #![feature(repr_simd, platform_intrinsics)]
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index f5ff92e69bc..18d98efebd4 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -607,7 +607,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -639,7 +639,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -669,7 +669,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c7adad896a5..927fd2a6b0b 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -284,7 +284,7 @@
 #![feature(never_type)]
 #![feature(nll)]
 #![cfg_attr(bootstrap, feature(non_exhaustive))]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 736a363bbfc..1e77eaaae88 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -134,9 +134,6 @@ declare_features! (
     /// Allows using `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    /// Allows using `#[on_unimplemented(..)]` on traits.
-    (active, on_unimplemented, "1.0.0", Some(29628), None),
-
     /// Allows using the `box $expr` syntax.
     (active, box_syntax, "1.0.0", Some(49733), None),
 
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index eb811c3e0ff..b32a887c6b2 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -166,7 +166,7 @@ macro_rules! experimental {
 }
 
 const IMPL_DETAIL: &str = "internal implementation detail";
-const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
 
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
@@ -418,14 +418,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
         "the `linkage` attribute is experimental and not portable across platforms",
     ),
-    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Macro related:
     // ==========================================================================
 
     rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
     rustc_attr!(
         rustc_macro_transparency, Whitelisted,
         template!(NameValueStr: "transparent|semitransparent|opaque"),
@@ -436,17 +436,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Internal attributes, Diagnostics related:
     // ==========================================================================
 
-    gated!(
+    rustc_attr!(
         rustc_on_unimplemented, Whitelisted,
         template!(
             List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
             NameValueStr: "message"
         ),
-        on_unimplemented,
-        experimental!(rustc_on_unimplemented),
+        INTERNAL_UNSTABLE
     ),
     // Whitelists "identity-like" conversion methods to suggest on type mismatch.
-    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
@@ -454,7 +453,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
     rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Layout related:
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 2c29e1ebf14..c7b931a6f70 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -99,6 +99,9 @@ declare_features! (
     /// + `__register_diagnostic`
     /// +`__build_diagnostic_array`
     (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
+    /// Allows using `#[on_unimplemented(..)]` on traits.
+    /// (Moved to `rustc_attrs`.)
+    (removed, on_unimplemented, "1.40.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
index 709e9be663e..fa52ca90b10 100644
--- a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
+++ b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
@@ -5,7 +5,7 @@
 // revisions: cfail1 cfail2
 // build-pass (FIXME(62277): could be check-pass?)
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 #![deny(unused_attributes)]
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs b/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
deleted file mode 100644
index bec1531c533..00000000000
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test that `#[rustc_on_unimplemented]` is gated by `on_unimplemented` feature
-// gate.
-
-#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
-//~^ ERROR the `#[rustc_on_unimplemented]` attribute is an experimental feature
-trait Foo<Bar>
-{}
-
-fn main() {}
diff --git a/src/test/ui/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs
index 5357c3bff9a..f05436b8c04 100644
--- a/src/test/ui/on-unimplemented/bad-annotation.rs
+++ b/src/test/ui/on-unimplemented/bad-annotation.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #![allow(unused)]
 
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.rs b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
index d8717f360e9..77c0ea17269 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.rs
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
@@ -2,7 +2,7 @@
 // access to the variable, whether that mutable access be used
 // for direct assignment or for taking mutable ref. Issue #6801.
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #[rustc_on_unimplemented(
     message="the message"
diff --git a/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
new file mode 100644
index 00000000000..3cc50e3499a
--- /dev/null
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
@@ -0,0 +1,8 @@
+// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate.
+
+#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
+//~^ ERROR this is an internal attribute that will never be stable
+trait Foo<Bar>
+{}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
index 6c230f8cada..ec1eaff52bd 100644
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
@@ -1,11 +1,11 @@
-error[E0658]: the `#[rustc_on_unimplemented]` attribute is an experimental feature
-  --> $DIR/feature-gate-on-unimplemented.rs:4:1
+error[E0658]: this is an internal attribute that will never be stable
+  --> $DIR/feature-gate-on-unimplemented.rs:3:1
    |
 LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29628
-   = help: add `#![feature(on_unimplemented)]` to the crate attributes to enable
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index 0aee98b2090..b74957ebcd4 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 struct Foo<T>(T);
diff --git a/src/test/ui/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index 9e4c2f6edd7..ab3e67d01fe 100644
--- a/src/test/ui/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/ui/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs
index 109cb5ba969..556813cd479 100644
--- a/src/test/ui/on-unimplemented/on-trait.rs
+++ b/src/test/ui/on-unimplemented/on-trait.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 pub mod Bar {
   #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]