From d86516d91e643fd87eadf057096989ce454f4d81 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 25 Aug 2019 13:06:49 +0200 Subject: [PATCH 1/7] Stabilise weak_ptr_eq --- src/liballoc/rc.rs | 4 +--- src/liballoc/sync.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 2b222caf13f3d..1752c1342c856 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1843,7 +1843,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::rc::Rc; /// /// let first_rc = Rc::new(5); @@ -1861,7 +1860,6 @@ impl Weak { /// Comparing `Weak::new`. /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::rc::{Rc, Weak}; /// /// let first = Weak::new(); @@ -1873,7 +1871,7 @@ impl Weak { /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] - #[unstable(feature = "weak_ptr_eq", issue = "55981")] + #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { self.ptr.as_ptr() == other.ptr.as_ptr() } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 9ffc1673e5ab8..e89433d67bdd6 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1562,7 +1562,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::sync::Arc; /// /// let first_rc = Arc::new(5); @@ -1580,7 +1579,6 @@ impl Weak { /// Comparing `Weak::new`. /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::sync::{Arc, Weak}; /// /// let first = Weak::new(); @@ -1592,7 +1590,7 @@ impl Weak { /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] - #[unstable(feature = "weak_ptr_eq", issue = "55981")] + #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { self.ptr.as_ptr() == other.ptr.as_ptr() } From 307804a00d191b6f15d1a1a5b98fbae5ea6593b0 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 25 Aug 2019 13:02:45 +0200 Subject: [PATCH 2/7] Update {rc, sync}::Weak::ptr_eq doc about comparing Weak::new --- src/liballoc/rc.rs | 5 +++-- src/liballoc/sync.rs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1752c1342c856..a10f7c60031e0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1832,8 +1832,9 @@ impl Weak { } } - /// Returns `true` if the two `Weak`s point to the same value (not just values - /// that compare as equal). + /// Returns `true` if the two `Weak`s point to the same value (not just + /// values that compare as equal), or if both don't point to any value + /// (because they were created with `Weak::new()`). /// /// # Notes /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index e89433d67bdd6..716d750915e12 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1550,15 +1550,15 @@ impl Weak { } } - /// Returns `true` if the two `Weak`s point to the same value (not just values - /// that compare as equal). + /// Returns `true` if the two `Weak`s point to the same value (not just + /// values that compare as equal), or if both don't point to any value + /// (because they were created with `Weak::new()`). /// /// # Notes /// /// Since this compares pointers it means that `Weak::new()` will equal each /// other, even though they don't point to any value. /// - /// /// # Examples /// /// ``` From b7f20d06ea40d13834bd04ad32d098d3626f11c7 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 8 Sep 2019 13:06:49 -0400 Subject: [PATCH 3/7] Provide a span if main function is not present in crate Unfortunately, the diagnotic machinery does not cope well with an empty span which can happen if the crate is empty, in which case we merely set a spanless note. --- src/librustc/middle/entry.rs | 74 +++++++++++-------- .../ui-fulldeps/hash-stable-is-unstable.rs | 2 + .../hash-stable-is-unstable.stderr | 9 +-- .../ui/associated-type-bounds/inside-adt.rs | 2 + .../associated-type-bounds/inside-adt.stderr | 7 +- .../cfg-attr-cfg-2.stderr | 5 +- .../cfg-in-crate-1.stderr | 4 +- .../ui/continue-after-missing-main.nll.stderr | 10 ++- .../ui/continue-after-missing-main.stderr | 10 ++- src/test/ui/elided-test.stderr | 6 +- src/test/ui/error-codes/E0138.stderr | 2 +- src/test/ui/error-codes/E0601.rs | 2 +- src/test/ui/error-codes/E0601.stderr | 4 +- src/test/ui/issues/issue-46101.rs | 2 + src/test/ui/issues/issue-46101.stderr | 9 +-- src/test/ui/issues/issue-49040.rs | 1 + src/test/ui/issues/issue-49040.stderr | 6 +- src/test/ui/issues/issue-60057.rs | 2 + src/test/ui/issues/issue-60057.stderr | 9 +-- src/test/ui/json-short.stderr | 2 +- src/test/ui/lifetime-before-type-params.rs | 2 + .../ui/lifetime-before-type-params.stderr | 7 +- src/test/ui/main-wrong-location.rs | 1 + src/test/ui/main-wrong-location.stderr | 16 +++- src/test/ui/missing/missing-main.stderr | 4 +- src/test/ui/parser-recovery-1.rs | 1 + src/test/ui/parser-recovery-1.stderr | 19 +++-- src/test/ui/parser/issue-2354.rs | 5 +- src/test/ui/parser/issue-2354.stderr | 20 ++++- src/test/ui/parser/lex-bad-char-literals-2.rs | 2 + .../ui/parser/lex-bad-char-literals-2.stderr | 7 +- .../parser/unclosed-delimiter-in-dep.stderr | 2 +- src/test/ui/parser/unclosed_delim_mod.rs | 2 + src/test/ui/parser/unclosed_delim_mod.stderr | 9 +-- .../ui/resolve/visibility-indeterminate.rs | 2 + .../resolve/visibility-indeterminate.stderr | 7 +- .../ui/tool-attributes/diagnostic_item.rs | 1 + .../ui/tool-attributes/diagnostic_item.stderr | 9 +-- .../ui/type-alias-impl-trait/issue-60564.rs | 2 + .../type-alias-impl-trait/issue-60564.stderr | 7 +- src/test/ui/type/ascription/issue-34255-1.rs | 1 + .../ui/type/ascription/issue-34255-1.stderr | 8 +- 42 files changed, 176 insertions(+), 126 deletions(-) diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 93bb301f0951a..ba27d332e43f7 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -16,16 +16,16 @@ struct EntryContext<'a, 'tcx> { map: &'a hir_map::Map<'tcx>, - /// The top-level function called 'main'. + /// The top-level function called `main`. main_fn: Option<(HirId, Span)>, - /// The function that has attribute named 'main'. + /// The function that has attribute named `main`. attr_main_fn: Option<(HirId, Span)>, /// The function that has the attribute 'start' on it. start_fn: Option<(HirId, Span)>, - /// The functions that one might think are 'main' but aren't, e.g. + /// The functions that one might think are `main` but aren't, e.g. /// main functions not defined at the top level. For diagnostics. non_main_fns: Vec<(HirId, Span)> , } @@ -88,7 +88,7 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType { EntryPointType::MainAttr } else if item.ident.name == sym::main { if at_root { - // This is a top-level function so can be 'main'. + // This is a top-level function so can be `main`. EntryPointType::MainNamed } else { EntryPointType::OtherMain @@ -109,7 +109,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { ctxt.main_fn = Some((item.hir_id, item.span)); } else { span_err!(ctxt.session, item.span, E0136, - "multiple 'main' functions"); + "multiple `main` functions"); } }, EntryPointType::OtherMain => { @@ -130,7 +130,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { if ctxt.start_fn.is_none() { ctxt.start_fn = Some((item.hir_id, item.span)); } else { - struct_span_err!(ctxt.session, item.span, E0138, "multiple 'start' functions") + struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions") .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here") .span_label(item.span, "multiple `start` functions") .emit(); @@ -148,34 +148,48 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De } else if let Some((hir_id, _)) = visitor.main_fn { Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main)) } else { - // There is no main function. - let mut err = struct_err!(tcx.sess, E0601, - "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE)); - if !visitor.non_main_fns.is_empty() { - // There were some functions named 'main' though. Try to give the user a hint. - err.note("the main function must be defined at the crate level \ - but you have one or more functions named 'main' that are not \ - defined at the crate level. Either move the definition or \ - attach the `#[main]` attribute to override this behavior."); - for &(_, span) in &visitor.non_main_fns { - err.span_note(span, "here is a function named 'main'"); - } - err.emit(); - } else { - if let Some(ref filename) = tcx.sess.local_crate_source_file { - err.note(&format!("consider adding a `main` function to `{}`", filename.display())); - } - if tcx.sess.teach(&err.get_code().unwrap()) { - err.note("If you don't know the basics of Rust, you can go look to the Rust Book \ - to get started: https://doc.rust-lang.org/book/"); - } - err.emit(); - } - + no_main_err(tcx, visitor); None } } +fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { + // There is no main function. + let mut err = struct_err!(tcx.sess, E0601, + "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE)); + let filename = &tcx.sess.local_crate_source_file; + let note = if !visitor.non_main_fns.is_empty() { + for &(_, span) in &visitor.non_main_fns { + err.span_note(span, "here is a function named `main`"); + } + err.note("you have one or more functions named `main` not defined at the crate level"); + err.help("either move the `main` function definitions or attach the `#[main]` attribute \ + to one of them"); + // There were some functions named `main` though. Try to give the user a hint. + format!("the main function must be defined at the crate level{}", + filename.as_ref().map(|f| format!(" (in `{}`)", f.display())).unwrap_or_default()) + } else if let Some(filename) = filename { + format!("consider adding a `main` function to `{}`", filename.display()) + } else { + String::from("consider adding a `main` function at the crate level") + }; + let sp = tcx.hir().krate().span; + // The file may be empty, which leads to the diagnostic machinery not emitting this + // note. This is a relatively simple way to detect that case and emit a span-less + // note instead. + if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) { + err.set_span(sp); + err.span_label(sp, ¬e); + } else { + err.note(¬e); + } + if tcx.sess.teach(&err.get_code().unwrap()) { + err.note("If you don't know the basics of Rust, you can go look to the Rust Book \ + to get started: https://doc.rust-lang.org/book/"); + } + err.emit(); +} + pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> { tcx.entry_fn(LOCAL_CRATE) } diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.rs b/src/test/ui-fulldeps/hash-stable-is-unstable.rs index 9f67f642df1ce..d79ef62c31207 100644 --- a/src/test/ui-fulldeps/hash-stable-is-unstable.rs +++ b/src/test/ui-fulldeps/hash-stable-is-unstable.rs @@ -13,3 +13,5 @@ use rustc_macros::HashStable; #[derive(HashStable)] //~^ use of unstable library feature 'rustc_private' struct Test; + +fn main() {} diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr index 02056d30eae9c..e2dc0c3be725f 100644 --- a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr +++ b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `hash_stable_is_unstable` - | - = note: consider adding a `main` function to `$DIR/hash-stable-is-unstable.rs` - error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? --> $DIR/hash-stable-is-unstable.rs:3:1 | @@ -47,7 +43,6 @@ LL | #[derive(HashStable)] = note: for more information, see https://github.com/rust-lang/rust/issues/27812 = help: add `#![feature(rustc_private)]` to the crate attributes to enable -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0601, E0658. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs index 83a60825d84cd..59ce9496d28f0 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.rs +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -31,3 +31,5 @@ union U2 { f: Box> } union U3 { f: dyn Iterator } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions //~| ERROR could not find defining uses + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr index d0e0ceccd3725..9c4d03e900940 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.stderr +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -52,10 +52,6 @@ error: associated type bounds are not allowed within structs, enums, or unions LL | union U3 { f: dyn Iterator } | ^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `inside_adt` - | - = note: consider adding a `main` function to `$DIR/inside-adt.rs` - error: could not find defining uses --> $DIR/inside-adt.rs:5:29 | @@ -110,6 +106,5 @@ error: could not find defining uses LL | union U3 { f: dyn Iterator } | ^^^^^^^^^^^^^ -error: aborting due to 19 previous errors +error: aborting due to 18 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr index db3c7acff151c..e9df780def5df 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr @@ -1,6 +1,9 @@ error[E0601]: `main` function not found in crate `cfg_attr_cfg_2` + --> $DIR/cfg-attr-cfg-2.rs:8:1 | - = note: consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs` +LL | / #[cfg_attr(foo, cfg(bar))] +LL | | fn main() { } + | |_____________^ consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs` error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr b/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr index c6d42c732c934..0b5c3e0335586 100644 --- a/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr +++ b/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr @@ -1,6 +1,8 @@ error[E0601]: `main` function not found in crate `cfg_in_crate_1` + --> $DIR/cfg-in-crate-1.rs:3:1 | - = note: consider adding a `main` function to `$DIR/cfg-in-crate-1.rs` +LL | #![cfg(bar)] + | ^^^^^^^^^^^^ consider adding a `main` function to `$DIR/cfg-in-crate-1.rs` error: aborting due to previous error diff --git a/src/test/ui/continue-after-missing-main.nll.stderr b/src/test/ui/continue-after-missing-main.nll.stderr index aceabf3316479..b94c365f2539a 100644 --- a/src/test/ui/continue-after-missing-main.nll.stderr +++ b/src/test/ui/continue-after-missing-main.nll.stderr @@ -1,6 +1,14 @@ error[E0601]: `main` function not found in crate `continue_after_missing_main` + --> $DIR/continue-after-missing-main.rs:1:1 | - = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs` +LL | / #![allow(dead_code)] +LL | | +LL | | // error-pattern:`main` function not found in crate +LL | | +... | +LL | | +LL | | } + | |_^ consider adding a `main` function to `$DIR/continue-after-missing-main.rs` error: aborting due to previous error diff --git a/src/test/ui/continue-after-missing-main.stderr b/src/test/ui/continue-after-missing-main.stderr index cc5f87659079e..d764e7d860af6 100644 --- a/src/test/ui/continue-after-missing-main.stderr +++ b/src/test/ui/continue-after-missing-main.stderr @@ -1,6 +1,14 @@ error[E0601]: `main` function not found in crate `continue_after_missing_main` + --> $DIR/continue-after-missing-main.rs:1:1 | - = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs` +LL | / #![allow(dead_code)] +LL | | +LL | | // error-pattern:`main` function not found in crate +LL | | +... | +LL | | +LL | | } + | |_^ consider adding a `main` function to `$DIR/continue-after-missing-main.rs` error[E0623]: lifetime mismatch --> $DIR/continue-after-missing-main.rs:30:56 diff --git a/src/test/ui/elided-test.stderr b/src/test/ui/elided-test.stderr index d22eee4e8bde7..175bd033067bc 100644 --- a/src/test/ui/elided-test.stderr +++ b/src/test/ui/elided-test.stderr @@ -1,6 +1,10 @@ error[E0601]: `main` function not found in crate `elided_test` + --> $DIR/elided-test.rs:5:1 | - = note: consider adding a `main` function to `$DIR/elided-test.rs` +LL | / #[test] +LL | | fn main() { +LL | | } + | |_^ consider adding a `main` function to `$DIR/elided-test.rs` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0138.stderr b/src/test/ui/error-codes/E0138.stderr index 745dccfb17571..445053a4a89e3 100644 --- a/src/test/ui/error-codes/E0138.stderr +++ b/src/test/ui/error-codes/E0138.stderr @@ -1,4 +1,4 @@ -error[E0138]: multiple 'start' functions +error[E0138]: multiple `start` functions --> $DIR/E0138.rs:7:1 | LL | fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } diff --git a/src/test/ui/error-codes/E0601.rs b/src/test/ui/error-codes/E0601.rs index 47feb7f836722..4380ddeac0aac 100644 --- a/src/test/ui/error-codes/E0601.rs +++ b/src/test/ui/error-codes/E0601.rs @@ -1 +1 @@ -// Test for main function not found. +//~ ERROR `main` function not found diff --git a/src/test/ui/error-codes/E0601.stderr b/src/test/ui/error-codes/E0601.stderr index cbc20db35da77..a687f575615d7 100644 --- a/src/test/ui/error-codes/E0601.stderr +++ b/src/test/ui/error-codes/E0601.stderr @@ -1,6 +1,8 @@ error[E0601]: `main` function not found in crate `E0601` + --> $DIR/E0601.rs:1:37 | - = note: consider adding a `main` function to `$DIR/E0601.rs` +LL | + | ^ consider adding a `main` function to `$DIR/E0601.rs` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-46101.rs b/src/test/ui/issues/issue-46101.rs index 2d9111e9b3a98..8b1343b1326b4 100644 --- a/src/test/ui/issues/issue-46101.rs +++ b/src/test/ui/issues/issue-46101.rs @@ -2,3 +2,5 @@ trait Foo {} #[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro struct S; + +fn main() {} diff --git a/src/test/ui/issues/issue-46101.stderr b/src/test/ui/issues/issue-46101.stderr index 772d4bfeb30a7..9c88d3b87c907 100644 --- a/src/test/ui/issues/issue-46101.stderr +++ b/src/test/ui/issues/issue-46101.stderr @@ -4,11 +4,6 @@ error[E0433]: failed to resolve: partially resolved path in a derive macro LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ partially resolved path in a derive macro -error[E0601]: `main` function not found in crate `issue_46101` - | - = note: consider adding a `main` function to `$DIR/issue-46101.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0433, E0601. -For more information about an error, try `rustc --explain E0433`. +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/issues/issue-49040.rs b/src/test/ui/issues/issue-49040.rs index a5f05d2824eb8..b7a541dd6642a 100644 --- a/src/test/ui/issues/issue-49040.rs +++ b/src/test/ui/issues/issue-49040.rs @@ -1,2 +1,3 @@ #![allow(unused_variables)]; //~ ERROR expected item, found `;` +//~^ ERROR `main` function fn foo() {} diff --git a/src/test/ui/issues/issue-49040.stderr b/src/test/ui/issues/issue-49040.stderr index de78b8d3c14af..4134d6aa54468 100644 --- a/src/test/ui/issues/issue-49040.stderr +++ b/src/test/ui/issues/issue-49040.stderr @@ -5,8 +5,12 @@ LL | #![allow(unused_variables)]; | ^ help: remove this semicolon error[E0601]: `main` function not found in crate `issue_49040` + --> $DIR/issue-49040.rs:1:1 | - = note: consider adding a `main` function to `$DIR/issue-49040.rs` +LL | / #![allow(unused_variables)]; +LL | | +LL | | fn foo() {} + | |__^ consider adding a `main` function to `$DIR/issue-49040.rs` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-60057.rs b/src/test/ui/issues/issue-60057.rs index 3027d01c5325b..b52343adaee71 100644 --- a/src/test/ui/issues/issue-60057.rs +++ b/src/test/ui/issues/issue-60057.rs @@ -15,3 +15,5 @@ impl A { } } } + +fn main() {} diff --git a/src/test/ui/issues/issue-60057.stderr b/src/test/ui/issues/issue-60057.stderr index 6b967204ce6fb..4d915fcd9fe3d 100644 --- a/src/test/ui/issues/issue-60057.stderr +++ b/src/test/ui/issues/issue-60057.stderr @@ -10,11 +10,6 @@ error[E0425]: cannot find value `banana` in this scope LL | banana: banana | ^^^^^^ help: you might have meant to use the available field: `self.banana` -error[E0601]: `main` function not found in crate `issue_60057` - | - = note: consider adding a `main` function to `$DIR/issue-60057.rs` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0425, E0601. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr index dffbdb7e4802d..86cb2f0a3a813 100644 --- a/src/test/ui/json-short.stderr +++ b/src/test/ui/json-short.stderr @@ -11,7 +11,7 @@ fn main() { If you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/ -"},"level":"error","spans":[],"children":[{"message":"consider adding a `main` function to `$DIR/json-short.rs`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"error[E0601]: `main` function not found in crate `json_short` +"},"level":"error","spans":[{"file_name":"$DIR/json-short.rs","byte_start":76,"byte_end":76,"line_start":2,"line_end":2,"column_start":63,"column_end":63,"is_primary":true,"text":[{"text":"// compile-flags: --json=diagnostic-short --error-format=json","highlight_start":63,"highlight_end":63}],"label":"consider adding a `main` function to `$DIR/json-short.rs`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-short.rs:2:63: error[E0601]: `main` function not found in crate `json_short` "} {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error "} diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs index 9b905d4883a16..5a71d6efeda62 100644 --- a/src/test/ui/lifetime-before-type-params.rs +++ b/src/test/ui/lifetime-before-type-params.rs @@ -7,3 +7,5 @@ fn third() {} //~^ ERROR lifetime parameters must be declared prior to type parameters fn fourth<'a, T, 'b, U, 'c, V>() {} //~^ ERROR lifetime parameters must be declared prior to type parameters + +fn main() {} diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr index ffc6784bafed8..76d7d0f024d65 100644 --- a/src/test/ui/lifetime-before-type-params.stderr +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -22,10 +22,5 @@ error: lifetime parameters must be declared prior to type parameters LL | fn fourth<'a, T, 'b, U, 'c, V>() {} | --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>` -error[E0601]: `main` function not found in crate `lifetime_before_type_params` - | - = note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/main-wrong-location.rs b/src/test/ui/main-wrong-location.rs index d7ed5128195e9..f75d08813cdcd 100644 --- a/src/test/ui/main-wrong-location.rs +++ b/src/test/ui/main-wrong-location.rs @@ -1,4 +1,5 @@ mod m { +//~^ ERROR `main` function not found // An inferred main entry point (that doesn't use #[main]) // must appear at the top of the crate fn main() { } diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr index b30931f2f2301..e301c2ff09ad7 100644 --- a/src/test/ui/main-wrong-location.stderr +++ b/src/test/ui/main-wrong-location.stderr @@ -1,11 +1,21 @@ error[E0601]: `main` function not found in crate `main_wrong_location` + --> $DIR/main-wrong-location.rs:1:1 | - = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior. -note: here is a function named 'main' - --> $DIR/main-wrong-location.rs:4:5 +LL | / mod m { +LL | | +LL | | // An inferred main entry point (that doesn't use #[main]) +LL | | // must appear at the top of the crate +LL | | fn main() { } +LL | | } + | |_^ the main function must be defined at the crate level (in `$DIR/main-wrong-location.rs`) + | +note: here is a function named `main` + --> $DIR/main-wrong-location.rs:5:5 | LL | fn main() { } | ^^^^^^^^^^^^^ + = note: you have one or more functions named `main` not defined at the crate level + = help: either move the `main` function definitions or attach the `#[main]` attribute to one of them error: aborting due to previous error diff --git a/src/test/ui/missing/missing-main.stderr b/src/test/ui/missing/missing-main.stderr index 34b03ada3d295..6a35f5117efd6 100644 --- a/src/test/ui/missing/missing-main.stderr +++ b/src/test/ui/missing/missing-main.stderr @@ -1,6 +1,8 @@ error[E0601]: `main` function not found in crate `missing_main` + --> $DIR/missing-main.rs:2:1 | - = note: consider adding a `main` function to `$DIR/missing-main.rs` +LL | fn mian() { } + | ^^^^^^^^^^^^^ consider adding a `main` function to `$DIR/missing-main.rs` error: aborting due to previous error diff --git a/src/test/ui/parser-recovery-1.rs b/src/test/ui/parser-recovery-1.rs index 21d36048e6703..8126525c34f95 100644 --- a/src/test/ui/parser-recovery-1.rs +++ b/src/test/ui/parser-recovery-1.rs @@ -3,6 +3,7 @@ // Test that we can recover from missing braces in the parser. trait Foo { +//~^ ERROR `main` function not found fn bar() { let x = foo(); //~^ ERROR cannot find function `foo` in this scope diff --git a/src/test/ui/parser-recovery-1.stderr b/src/test/ui/parser-recovery-1.stderr index c29f42759178e..ffe2b3322fc81 100644 --- a/src/test/ui/parser-recovery-1.stderr +++ b/src/test/ui/parser-recovery-1.stderr @@ -1,8 +1,9 @@ error: this file contains an un-closed delimiter - --> $DIR/parser-recovery-1.rs:15:55 + --> $DIR/parser-recovery-1.rs:16:55 | LL | trait Foo { | - un-closed delimiter +LL | LL | fn bar() { | - this delimiter might not be properly closed... ... @@ -13,26 +14,34 @@ LL | } | ^ error: unexpected token: `;` - --> $DIR/parser-recovery-1.rs:12:15 + --> $DIR/parser-recovery-1.rs:13:15 | LL | let x = y.; | ^ error[E0425]: cannot find function `foo` in this scope - --> $DIR/parser-recovery-1.rs:7:17 + --> $DIR/parser-recovery-1.rs:8:17 | LL | let x = foo(); | ^^^ not found in this scope error[E0425]: cannot find value `y` in this scope - --> $DIR/parser-recovery-1.rs:12:13 + --> $DIR/parser-recovery-1.rs:13:13 | LL | let x = y.; | ^ not found in this scope error[E0601]: `main` function not found in crate `parser_recovery_1` + --> $DIR/parser-recovery-1.rs:5:1 | - = note: consider adding a `main` function to `$DIR/parser-recovery-1.rs` +LL | / trait Foo { +LL | | +LL | | fn bar() { +LL | | let x = foo(); +... | +LL | | +LL | | } + | |______________________________________________________^ consider adding a `main` function to `$DIR/parser-recovery-1.rs` error: aborting due to 5 previous errors diff --git a/src/test/ui/parser/issue-2354.rs b/src/test/ui/parser/issue-2354.rs index 565f84822f7d6..a14eb6e32fc91 100644 --- a/src/test/ui/parser/issue-2354.rs +++ b/src/test/ui/parser/issue-2354.rs @@ -1,4 +1,7 @@ fn foo() { //~ NOTE un-closed delimiter +//~^ ERROR `main` function not found +//~^^ NOTE main function must be defined +//~^^^ NOTE you have one or more functions match Some(10) { //~^ NOTE this delimiter might not be properly closed... Some(y) => { panic!(); } @@ -11,5 +14,5 @@ fn bar() { while (i < 1000) {} } -fn main() {} //~ NOTE here is a function named 'main' +fn main() {} //~ NOTE here is a function named `main` //~ ERROR this file contains an un-closed delimiter diff --git a/src/test/ui/parser/issue-2354.stderr b/src/test/ui/parser/issue-2354.stderr index 7098da738b8df..038e3dcfa40a9 100644 --- a/src/test/ui/parser/issue-2354.stderr +++ b/src/test/ui/parser/issue-2354.stderr @@ -1,8 +1,9 @@ error: this file contains an un-closed delimiter - --> $DIR/issue-2354.rs:15:66 + --> $DIR/issue-2354.rs:18:66 | LL | fn foo() { | - un-closed delimiter +... LL | match Some(10) { | - this delimiter might not be properly closed... ... @@ -13,13 +14,24 @@ LL | | ^ error[E0601]: `main` function not found in crate `issue_2354` + --> $DIR/issue-2354.rs:1:1 + | +LL | / fn foo() { +LL | | +LL | | +LL | | +... | +LL | | fn main() {} +LL | | + | |_________________________________________________________________^ the main function must be defined at the crate level (in `$DIR/issue-2354.rs`) | - = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior. -note: here is a function named 'main' - --> $DIR/issue-2354.rs:14:1 +note: here is a function named `main` + --> $DIR/issue-2354.rs:17:1 | LL | fn main() {} | ^^^^^^^^^^^^ + = note: you have one or more functions named `main` not defined at the crate level + = help: either move the `main` function definitions or attach the `#[main]` attribute to one of them error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-2.rs b/src/test/ui/parser/lex-bad-char-literals-2.rs index 1e180f87fc186..d35dafd9a3443 100644 --- a/src/test/ui/parser/lex-bad-char-literals-2.rs +++ b/src/test/ui/parser/lex-bad-char-literals-2.rs @@ -2,3 +2,5 @@ static c: char = 'nope' //~ ERROR: character literal may only contain one codepoint ; + +fn main() {} diff --git a/src/test/ui/parser/lex-bad-char-literals-2.stderr b/src/test/ui/parser/lex-bad-char-literals-2.stderr index b0a4ed02434b4..5653d4ea672af 100644 --- a/src/test/ui/parser/lex-bad-char-literals-2.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-2.stderr @@ -8,10 +8,5 @@ help: if you meant to write a `str` literal, use double quotes LL | "nope" | ^^^^^^ -error[E0601]: `main` function not found in crate `lex_bad_char_literals_2` - | - = note: consider adding a `main` function to `$DIR/lex-bad-char-literals-2.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr index 633c63bea9105..818f61b4d2229 100644 --- a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr +++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr @@ -1,5 +1,5 @@ error: incorrect close delimiter: `}` - --> $DIR/unclosed_delim_mod.rs:5:1 + --> $DIR/unclosed_delim_mod.rs:7:1 | LL | pub fn new() -> Result { | - close delimiter possibly meant for this diff --git a/src/test/ui/parser/unclosed_delim_mod.rs b/src/test/ui/parser/unclosed_delim_mod.rs index b1664f49dc591..486e23312819d 100644 --- a/src/test/ui/parser/unclosed_delim_mod.rs +++ b/src/test/ui/parser/unclosed_delim_mod.rs @@ -1,3 +1,5 @@ +fn main() {} + pub struct Value {} pub fn new() -> Result { Ok(Value { diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr index cc04eb531cbea..fe2d968af0f32 100644 --- a/src/test/ui/parser/unclosed_delim_mod.stderr +++ b/src/test/ui/parser/unclosed_delim_mod.stderr @@ -1,5 +1,5 @@ error: incorrect close delimiter: `}` - --> $DIR/unclosed_delim_mod.rs:5:1 + --> $DIR/unclosed_delim_mod.rs:7:1 | LL | pub fn new() -> Result { | - close delimiter possibly meant for this @@ -9,10 +9,5 @@ LL | } LL | } | ^ incorrect close delimiter -error[E0601]: `main` function not found in crate `unclosed_delim_mod` - | - = note: consider adding a `main` function to `$DIR/unclosed_delim_mod.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/resolve/visibility-indeterminate.rs b/src/test/ui/resolve/visibility-indeterminate.rs index 595eaf440c9f4..198ea752881f1 100644 --- a/src/test/ui/resolve/visibility-indeterminate.rs +++ b/src/test/ui/resolve/visibility-indeterminate.rs @@ -3,3 +3,5 @@ foo!(); //~ ERROR cannot find macro `foo!` in this scope pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility + +fn main() {} diff --git a/src/test/ui/resolve/visibility-indeterminate.stderr b/src/test/ui/resolve/visibility-indeterminate.stderr index a259c8090b35d..17927a5967dcb 100644 --- a/src/test/ui/resolve/visibility-indeterminate.stderr +++ b/src/test/ui/resolve/visibility-indeterminate.stderr @@ -10,10 +10,5 @@ error: cannot find macro `foo!` in this scope LL | foo!(); | ^^^ -error[E0601]: `main` function not found in crate `visibility_indeterminate` - | - = note: consider adding a `main` function to `$DIR/visibility-indeterminate.rs` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/tool-attributes/diagnostic_item.rs b/src/test/ui/tool-attributes/diagnostic_item.rs index 1d35422ed6241..26a52ce60cfd8 100644 --- a/src/test/ui/tool-attributes/diagnostic_item.rs +++ b/src/test/ui/tool-attributes/diagnostic_item.rs @@ -1,2 +1,3 @@ #[rustc_diagnostic_item = "foomp"] //~ ERROR compiler internal support for linting struct Foomp; +fn main() {} diff --git a/src/test/ui/tool-attributes/diagnostic_item.stderr b/src/test/ui/tool-attributes/diagnostic_item.stderr index deff4da6b8052..5432f8dea8606 100644 --- a/src/test/ui/tool-attributes/diagnostic_item.stderr +++ b/src/test/ui/tool-attributes/diagnostic_item.stderr @@ -7,11 +7,6 @@ LL | #[rustc_diagnostic_item = "foomp"] = 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[E0601]: `main` function not found in crate `diagnostic_item` - | - = note: consider adding a `main` function to `$DIR/diagnostic_item.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0601, E0658. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 91c4576597ea4..9e96b1cf7b05f 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -24,3 +24,5 @@ where .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) } } + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index ebb13fca1da92..b838c06cadee3 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `issue_60564` - | - = note: consider adding a `main` function to `$DIR/issue-60564.rs` - error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/issue-60564.rs:20:49 | @@ -20,6 +16,5 @@ error: could not find defining uses LL | type IterBitsIter = impl std::iter::Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs index c11a248d3c7d1..c21d9f3d97cbb 100644 --- a/src/test/ui/type/ascription/issue-34255-1.rs +++ b/src/test/ui/type/ascription/issue-34255-1.rs @@ -13,3 +13,4 @@ impl Reactor { } // This case isn't currently being handled gracefully, including for completeness. +fn main() {} diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr index 531455b82b424..195b393b2f609 100644 --- a/src/test/ui/type/ascription/issue-34255-1.stderr +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -14,17 +14,13 @@ LL | input_cells: Vec::new() = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error[E0601]: `main` function not found in crate `issue_34255_1` - | - = note: consider adding a `main` function to `$DIR/issue-34255-1.rs` - error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/issue-34255-1.rs:7:22 | LL | input_cells: Vec::new() | ^^^^^^^^^^ expected 1 type argument -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0425, E0601. +Some errors have detailed explanations: E0107, E0425. For more information about an error, try `rustc --explain E0107`. From 7b3adc289eb84f21199d1f2aeac9d88779b7369b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 12 Sep 2019 10:46:49 -0400 Subject: [PATCH 4/7] Ban non-extern rust intrinsics Intrinsics can only be defined by the compiler. --- src/librustc_typeck/check/mod.rs | 20 +- .../incremental/hashes/function_interfaces.rs | 12 -- src/test/incremental/hashes/trait_defs.rs | 5 +- src/test/ui/feature-gates/feature-gate-abi.rs | 10 +- .../ui/feature-gates/feature-gate-abi.stderr | 187 ++++++++++-------- .../feature-gates/feature-gate-intrinsics.rs | 1 + .../feature-gate-intrinsics.stderr | 8 +- src/test/ui/intrinsics-always-extern.rs | 16 ++ src/test/ui/intrinsics-always-extern.stderr | 24 +++ 9 files changed, 186 insertions(+), 97 deletions(-) create mode 100644 src/test/ui/intrinsics-always-extern.rs create mode 100644 src/test/ui/intrinsics-always-extern.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 02e7d97ccdf7b..ae7ab0a771754 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1088,6 +1088,8 @@ fn check_fn<'a, 'tcx>( let span = body.value.span; + fn_maybe_err(fcx.tcx, span, fn_sig.abi); + if body.generator_kind.is_some() && can_be_generator.is_some() { let yield_ty = fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, @@ -1439,6 +1441,14 @@ fn check_opaque_for_cycles<'tcx>( } } +// Forbid defining intrinsics in Rust code, +// as they must always be defined by the compiler. +fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) { + if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi { + tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block"); + } +} + pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) { debug!( "check_item_type(it.hir_id={}, it.name={})", @@ -1475,9 +1485,17 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) { check_on_unimplemented(tcx, trait_def_id, it); } } - hir::ItemKind::Trait(..) => { + hir::ItemKind::Trait(_, _, _, _, ref items) => { let def_id = tcx.hir().local_def_id(it.hir_id); check_on_unimplemented(tcx, def_id, it); + + for item in items.iter() { + let item = tcx.hir().trait_item(item.id); + if let hir::TraitItemKind::Method(sig, _) = &item.node { + let abi = sig.header.abi; + fn_maybe_err(tcx, item.ident.span, abi); + } + } } hir::ItemKind::Struct(..) => { check_struct(tcx, it.hir_id, it.span); diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 4515e36166eb8..9cc2d3bcf6045 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -11,7 +11,6 @@ #![allow(warnings)] -#![feature(intrinsics)] #![feature(linkage)] #![feature(rustc_attrs)] #![crate_type = "rlib"] @@ -99,17 +98,6 @@ pub fn make_extern() {} pub extern "C" fn make_extern() {} -// Extern C Extern Rust-Intrinsic ---------------------------------------------- - -#[cfg(cfail1)] -pub extern "C" fn make_intrinsic() {} - -#[cfg(not(cfail1))] -#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, typeck_tables_of, fn_sig")] -#[rustc_clean(cfg = "cfail3")] -pub extern "rust-intrinsic" fn make_intrinsic() {} - - // Type Parameter -------------------------------------------------------------- #[cfg(cfail1)] diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 81ff99533fc91..3006cdccfbb55 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -18,7 +18,6 @@ #![feature(rustc_attrs)] #![crate_type="rlib"] #![feature(associated_type_defaults)] -#![feature(intrinsics)] // Change trait visibility @@ -318,7 +317,7 @@ trait TraitAddExternModifier { -// Change extern "C" to extern "rust-intrinsic" +// Change extern "C" to extern "stdcall" #[cfg(cfail1)] trait TraitChangeExternCToRustIntrinsic { extern "C" fn method(); @@ -330,7 +329,7 @@ trait TraitChangeExternCToRustIntrinsic { trait TraitChangeExternCToRustIntrinsic { #[rustc_dirty(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] - extern "rust-intrinsic" fn method(); + extern "stdcall" fn method(); } diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs index 41c9f79bfe3ed..61da38eea74b3 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.rs +++ b/src/test/ui/feature-gates/feature-gate-abi.rs @@ -10,7 +10,9 @@ // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change +//~^ ERROR intrinsic must be in extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental +//~^ ERROR intrinsic must be in extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -22,7 +24,9 @@ extern "amdgpu-kernel" fn f9() {} //~ ERROR amdgpu-kernel ABI is experimental an // Methods in trait definition trait Tr { extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change + //~^ ERROR intrinsic must be in extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental + //~^ ERROR intrinsic must be in extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental @@ -31,8 +35,6 @@ trait Tr { extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change extern "amdgpu-kernel" fn m9(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change - extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change - extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -47,7 +49,9 @@ struct S; // Methods in trait impl impl Tr for S { extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change + //~^ ERROR intrinsic must be in extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental + //~^ ERROR intrinsic must be in extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -60,7 +64,9 @@ impl Tr for S { // Methods in inherent impl impl S { extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change + //~^ ERROR intrinsic must be in extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental + //~^ ERROR intrinsic must be in extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr index 88e0b8667be54..afda76dc2b0aa 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi.stderr @@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:13:1 + --> $DIR/feature-gate-abi.rs:14:1 | LL | extern "platform-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:14:1 + --> $DIR/feature-gate-abi.rs:16:1 | LL | extern "vectorcall" fn f3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | extern "vectorcall" fn f3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:15:1 + --> $DIR/feature-gate-abi.rs:17:1 | LL | extern "rust-call" fn f4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | extern "rust-call" fn f4() {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:16:1 + --> $DIR/feature-gate-abi.rs:18:1 | LL | extern "msp430-interrupt" fn f5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | extern "msp430-interrupt" fn f5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:17:1 + --> $DIR/feature-gate-abi.rs:19:1 | LL | extern "ptx-kernel" fn f6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | extern "ptx-kernel" fn f6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:18:1 + --> $DIR/feature-gate-abi.rs:20:1 | LL | extern "x86-interrupt" fn f7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | extern "x86-interrupt" fn f7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:19:1 + --> $DIR/feature-gate-abi.rs:21:1 | LL | extern "thiscall" fn f8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | extern "thiscall" fn f8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:20:1 + --> $DIR/feature-gate-abi.rs:22:1 | LL | extern "amdgpu-kernel" fn f9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | extern "amdgpu-kernel" fn f9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:24:5 + --> $DIR/feature-gate-abi.rs:26:5 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "rust-intrinsic" fn m1(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:25:5 + --> $DIR/feature-gate-abi.rs:28:5 | LL | extern "platform-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | extern "platform-intrinsic" fn m2(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:26:5 + --> $DIR/feature-gate-abi.rs:30:5 | LL | extern "vectorcall" fn m3(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL | extern "vectorcall" fn m3(); = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:27:5 + --> $DIR/feature-gate-abi.rs:31:5 | LL | extern "rust-call" fn m4(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | extern "rust-call" fn m4(); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:28:5 + --> $DIR/feature-gate-abi.rs:32:5 | LL | extern "msp430-interrupt" fn m5(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL | extern "msp430-interrupt" fn m5(); = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:29:5 + --> $DIR/feature-gate-abi.rs:33:5 | LL | extern "ptx-kernel" fn m6(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | extern "ptx-kernel" fn m6(); = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:30:5 + --> $DIR/feature-gate-abi.rs:34:5 | LL | extern "x86-interrupt" fn m7(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,7 +138,7 @@ LL | extern "x86-interrupt" fn m7(); = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:31:5 + --> $DIR/feature-gate-abi.rs:35:5 | LL | extern "thiscall" fn m8(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,7 +146,7 @@ LL | extern "thiscall" fn m8(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:32:5 + --> $DIR/feature-gate-abi.rs:36:5 | LL | extern "amdgpu-kernel" fn m9(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,25 +154,8 @@ LL | extern "amdgpu-kernel" fn m9(); = note: for more information, see https://github.com/rust-lang/rust/issues/51575 = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable -error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:34:5 - | -LL | extern "rust-intrinsic" fn dm1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(intrinsics)]` to the crate attributes to enable - -error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:35:5 - | -LL | extern "platform-intrinsic" fn dm2() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable - error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:36:5 + --> $DIR/feature-gate-abi.rs:38:5 | LL | extern "vectorcall" fn dm3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -180,7 +163,7 @@ LL | extern "vectorcall" fn dm3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:37:5 + --> $DIR/feature-gate-abi.rs:39:5 | LL | extern "rust-call" fn dm4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +172,7 @@ LL | extern "rust-call" fn dm4() {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:38:5 + --> $DIR/feature-gate-abi.rs:40:5 | LL | extern "msp430-interrupt" fn dm5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +181,7 @@ LL | extern "msp430-interrupt" fn dm5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:39:5 + --> $DIR/feature-gate-abi.rs:41:5 | LL | extern "ptx-kernel" fn dm6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +190,7 @@ LL | extern "ptx-kernel" fn dm6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:40:5 + --> $DIR/feature-gate-abi.rs:42:5 | LL | extern "x86-interrupt" fn dm7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -216,7 +199,7 @@ LL | extern "x86-interrupt" fn dm7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:41:5 + --> $DIR/feature-gate-abi.rs:43:5 | LL | extern "thiscall" fn dm8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -224,7 +207,7 @@ LL | extern "thiscall" fn dm8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:42:5 + --> $DIR/feature-gate-abi.rs:44:5 | LL | extern "amdgpu-kernel" fn dm9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +216,7 @@ LL | extern "amdgpu-kernel" fn dm9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:49:5 + --> $DIR/feature-gate-abi.rs:51:5 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +224,7 @@ LL | extern "rust-intrinsic" fn m1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:50:5 + --> $DIR/feature-gate-abi.rs:53:5 | LL | extern "platform-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -250,7 +233,7 @@ LL | extern "platform-intrinsic" fn m2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:51:5 + --> $DIR/feature-gate-abi.rs:55:5 | LL | extern "vectorcall" fn m3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -258,7 +241,7 @@ LL | extern "vectorcall" fn m3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:52:5 + --> $DIR/feature-gate-abi.rs:56:5 | LL | extern "rust-call" fn m4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -267,7 +250,7 @@ LL | extern "rust-call" fn m4() {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:53:5 + --> $DIR/feature-gate-abi.rs:57:5 | LL | extern "msp430-interrupt" fn m5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +259,7 @@ LL | extern "msp430-interrupt" fn m5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:54:5 + --> $DIR/feature-gate-abi.rs:58:5 | LL | extern "ptx-kernel" fn m6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -285,7 +268,7 @@ LL | extern "ptx-kernel" fn m6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:55:5 + --> $DIR/feature-gate-abi.rs:59:5 | LL | extern "x86-interrupt" fn m7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -294,7 +277,7 @@ LL | extern "x86-interrupt" fn m7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:56:5 + --> $DIR/feature-gate-abi.rs:60:5 | LL | extern "thiscall" fn m8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +285,7 @@ LL | extern "thiscall" fn m8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:57:5 + --> $DIR/feature-gate-abi.rs:61:5 | LL | extern "amdgpu-kernel" fn m9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -311,7 +294,7 @@ LL | extern "amdgpu-kernel" fn m9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:62:5 + --> $DIR/feature-gate-abi.rs:66:5 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -319,7 +302,7 @@ LL | extern "rust-intrinsic" fn im1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:63:5 + --> $DIR/feature-gate-abi.rs:68:5 | LL | extern "platform-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -328,7 +311,7 @@ LL | extern "platform-intrinsic" fn im2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:64:5 + --> $DIR/feature-gate-abi.rs:70:5 | LL | extern "vectorcall" fn im3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +319,7 @@ LL | extern "vectorcall" fn im3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:65:5 + --> $DIR/feature-gate-abi.rs:71:5 | LL | extern "rust-call" fn im4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -345,7 +328,7 @@ LL | extern "rust-call" fn im4() {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:66:5 + --> $DIR/feature-gate-abi.rs:72:5 | LL | extern "msp430-interrupt" fn im5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -354,7 +337,7 @@ LL | extern "msp430-interrupt" fn im5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:67:5 + --> $DIR/feature-gate-abi.rs:73:5 | LL | extern "ptx-kernel" fn im6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -363,7 +346,7 @@ LL | extern "ptx-kernel" fn im6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:68:5 + --> $DIR/feature-gate-abi.rs:74:5 | LL | extern "x86-interrupt" fn im7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +355,7 @@ LL | extern "x86-interrupt" fn im7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:69:5 + --> $DIR/feature-gate-abi.rs:75:5 | LL | extern "thiscall" fn im8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -380,7 +363,7 @@ LL | extern "thiscall" fn im8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:70:5 + --> $DIR/feature-gate-abi.rs:76:5 | LL | extern "amdgpu-kernel" fn im9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -389,7 +372,7 @@ LL | extern "amdgpu-kernel" fn im9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:74:11 + --> $DIR/feature-gate-abi.rs:80:11 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -397,7 +380,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:75:11 + --> $DIR/feature-gate-abi.rs:81:11 | LL | type A2 = extern "platform-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -406,7 +389,7 @@ LL | type A2 = extern "platform-intrinsic" fn(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:76:11 + --> $DIR/feature-gate-abi.rs:82:11 | LL | type A3 = extern "vectorcall" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -414,7 +397,7 @@ LL | type A3 = extern "vectorcall" fn(); = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:77:11 + --> $DIR/feature-gate-abi.rs:83:11 | LL | type A4 = extern "rust-call" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -423,7 +406,7 @@ LL | type A4 = extern "rust-call" fn(); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:78:11 + --> $DIR/feature-gate-abi.rs:84:11 | LL | type A5 = extern "msp430-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -432,7 +415,7 @@ LL | type A5 = extern "msp430-interrupt" fn(); = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:79:11 + --> $DIR/feature-gate-abi.rs:85:11 | LL | type A6 = extern "ptx-kernel" fn (); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -441,7 +424,7 @@ LL | type A6 = extern "ptx-kernel" fn (); = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:80:11 + --> $DIR/feature-gate-abi.rs:86:11 | LL | type A7 = extern "x86-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -450,7 +433,7 @@ LL | type A7 = extern "x86-interrupt" fn(); = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:81:11 + --> $DIR/feature-gate-abi.rs:87:11 | LL | type A8 = extern "thiscall" fn(); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -458,7 +441,7 @@ LL | type A8 = extern "thiscall" fn(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:82:11 + --> $DIR/feature-gate-abi.rs:88:11 | LL | type A9 = extern "amdgpu-kernel" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -467,7 +450,7 @@ LL | type A9 = extern "amdgpu-kernel" fn(); = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:85:1 + --> $DIR/feature-gate-abi.rs:91:1 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -475,7 +458,7 @@ LL | extern "rust-intrinsic" {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:86:1 + --> $DIR/feature-gate-abi.rs:92:1 | LL | extern "platform-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -484,7 +467,7 @@ LL | extern "platform-intrinsic" {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:87:1 + --> $DIR/feature-gate-abi.rs:93:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -492,7 +475,7 @@ LL | extern "vectorcall" {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:88:1 + --> $DIR/feature-gate-abi.rs:94:1 | LL | extern "rust-call" {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -501,7 +484,7 @@ LL | extern "rust-call" {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:89:1 + --> $DIR/feature-gate-abi.rs:95:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -510,7 +493,7 @@ LL | extern "msp430-interrupt" {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:90:1 + --> $DIR/feature-gate-abi.rs:96:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -519,7 +502,7 @@ LL | extern "ptx-kernel" {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:91:1 + --> $DIR/feature-gate-abi.rs:97:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -528,7 +511,7 @@ LL | extern "x86-interrupt" {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:92:1 + --> $DIR/feature-gate-abi.rs:98:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ @@ -536,7 +519,7 @@ LL | extern "thiscall" {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:93:1 + --> $DIR/feature-gate-abi.rs:99:1 | LL | extern "amdgpu-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -544,6 +527,54 @@ LL | extern "amdgpu-kernel" {} = note: for more information, see https://github.com/rust-lang/rust/issues/51575 = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable -error: aborting due to 63 previous errors +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:26:32 + | +LL | extern "rust-intrinsic" fn m1(); + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:28:36 + | +LL | extern "platform-intrinsic" fn m2(); + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:12:33 + | +LL | extern "rust-intrinsic" fn f1() {} + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:14:37 + | +LL | extern "platform-intrinsic" fn f2() {} + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:51:37 + | +LL | extern "rust-intrinsic" fn m1() {} + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:53:41 + | +LL | extern "platform-intrinsic" fn m2() {} + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:66:38 + | +LL | extern "rust-intrinsic" fn im1() {} + | ^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-abi.rs:68:42 + | +LL | extern "platform-intrinsic" fn im2() {} + | ^^ + +error: aborting due to 69 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.rs b/src/test/ui/feature-gates/feature-gate-intrinsics.rs index d1da94338283b..e0dc3cc579d79 100644 --- a/src/test/ui/feature-gates/feature-gate-intrinsics.rs +++ b/src/test/ui/feature-gates/feature-gate-intrinsics.rs @@ -3,5 +3,6 @@ extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change } extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change +//~^ ERROR intrinsic must be in fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr index 09843f05af1b9..101a10e8df71f 100644 --- a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr @@ -22,7 +22,13 @@ error[E0093]: unrecognized intrinsic function: `bar` LL | fn bar(); | ^^^^^^^^^ unrecognized intrinsic -error: aborting due to 3 previous errors +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/feature-gate-intrinsics.rs:5:34 + | +LL | extern "rust-intrinsic" fn baz() {} + | ^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0093, E0658. For more information about an error, try `rustc --explain E0093`. diff --git a/src/test/ui/intrinsics-always-extern.rs b/src/test/ui/intrinsics-always-extern.rs new file mode 100644 index 0000000000000..22951147d7d87 --- /dev/null +++ b/src/test/ui/intrinsics-always-extern.rs @@ -0,0 +1,16 @@ +#![feature(intrinsics)] + +trait Foo { + extern "rust-intrinsic" fn foo(&self); //~ ERROR intrinsic must +} + +impl Foo for () { + extern "rust-intrinsic" fn foo(&self) { //~ ERROR intrinsic must + } +} + +extern "rust-intrinsic" fn hello() {//~ ERROR intrinsic must +} + +fn main() { +} diff --git a/src/test/ui/intrinsics-always-extern.stderr b/src/test/ui/intrinsics-always-extern.stderr new file mode 100644 index 0000000000000..24b6da16096e6 --- /dev/null +++ b/src/test/ui/intrinsics-always-extern.stderr @@ -0,0 +1,24 @@ +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/intrinsics-always-extern.rs:4:32 + | +LL | extern "rust-intrinsic" fn foo(&self); + | ^^^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/intrinsics-always-extern.rs:8:43 + | +LL | extern "rust-intrinsic" fn foo(&self) { + | ___________________________________________^ +LL | | } + | |_____^ + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/intrinsics-always-extern.rs:12:36 + | +LL | extern "rust-intrinsic" fn hello() { + | ____________________________________^ +LL | | } + | |_^ + +error: aborting due to 3 previous errors + From 966d96c9d2f16fd66eefda2eac25126a353bbb3a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 14 Sep 2019 19:36:41 +0300 Subject: [PATCH 5/7] feature_gate: Remove dead code from attribute checking Same checks are performed during name resolution, and all attributes go through name resolution now --- src/librustc_interface/passes.rs | 11 ++----- src/libsyntax/feature_gate/check.rs | 50 +++++------------------------ 2 files changed, 10 insertions(+), 51 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 3cfae1686dfdf..e8e8da6733471 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -41,7 +41,6 @@ use syntax::mut_visit::MutVisitor; use syntax::parse::{self, PResult}; use syntax::util::node_count::NodeCounter; use syntax::symbol::Symbol; -use syntax::feature_gate::AttributeType; use syntax_pos::FileName; use syntax_ext; @@ -219,7 +218,6 @@ impl BoxedResolver { pub struct PluginInfo { syntax_exts: Vec, - attributes: Vec<(Symbol, AttributeType)>, } pub fn register_plugins<'a>( @@ -312,12 +310,9 @@ pub fn register_plugins<'a>( } *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; - *sess.plugin_attributes.borrow_mut() = attributes.clone(); + *sess.plugin_attributes.borrow_mut() = attributes; - Ok((krate, PluginInfo { - syntax_exts, - attributes, - })) + Ok((krate, PluginInfo { syntax_exts })) } fn configure_and_expand_inner<'a>( @@ -329,7 +324,6 @@ fn configure_and_expand_inner<'a>( crate_loader: &'a mut CrateLoader<'a>, plugin_info: PluginInfo, ) -> Result<(ast::Crate, Resolver<'a>)> { - let attributes = plugin_info.attributes; time(sess, "pre ast expansion lint checks", || { lint::check_ast_crate( sess, @@ -522,7 +516,6 @@ fn configure_and_expand_inner<'a>( &krate, &sess.parse_sess, &sess.features_untracked(), - &attributes, sess.opts.unstable_features, ); }); diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 5711b269ff092..ddf847ca3a34c 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -1,7 +1,7 @@ use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState}; use super::accepted::ACCEPTED_FEATURES; use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES}; -use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; +use super::builtin_attrs::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use crate::ast::{ self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, @@ -33,9 +33,8 @@ pub enum Stability { } struct Context<'a> { - features: &'a Features, parse_sess: &'a ParseSess, - plugin_attributes: &'a [(Symbol, AttributeType)], + features: &'a Features, } macro_rules! gate_feature_fn { @@ -67,7 +66,6 @@ impl<'a> Context<'a> { &self, attr: &ast::Attribute, attr_info: Option<&BuiltinAttribute>, - is_macro: bool ) { debug!("check_attribute(attr = {:?})", attr); if let Some(&(name, ty, _template, ref gateage)) = attr_info { @@ -87,42 +85,15 @@ impl<'a> Context<'a> { } } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); - return; - } else { - for segment in &attr.path.segments { - if segment.ident.as_str().starts_with("rustc") { - let msg = "attributes starting with `rustc` are \ - reserved for use by the `rustc` compiler"; - gate_feature!(self, rustc_attrs, segment.ident.span, msg); - } - } - } - for &(n, ty) in self.plugin_attributes { - if attr.path == n { - // Plugins can't gate attributes, so we don't check for it - // unlike the code above; we only use this loop to - // short-circuit to avoid the checks below. - debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty); - return; - } - } - if !is_macro && !attr::is_known(attr) { - // Only run the custom attribute lint during regular feature gate - // checking. Macro gating runs before the plugin attributes are - // registered, so we skip this in that case. - let msg = format!("the attribute `{}` is currently unknown to the compiler and \ - may have meaning added to it in the future", attr.path); - gate_feature!(self, custom_attribute, attr.span, &msg); } } } pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { - let cx = Context { features, parse_sess, plugin_attributes: &[] }; + let cx = Context { parse_sess, features }; cx.check_attribute( attr, attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)), - true ); } @@ -321,7 +292,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { }); // Check for gated attributes. - self.context.check_attribute(attr, attr_info, false); + self.context.check_attribute(attr, attr_info); if attr.check_name(sym::doc) { if let Some(content) = attr.meta_item_list() { @@ -872,21 +843,16 @@ fn active_features_up_to(edition: Edition) -> impl Iterator { gate_all!($gate, $gate, $msg); }; ($spans:ident, $gate:ident, $msg:literal) => { - for span in &*sess.gated_spans.$spans.borrow() { + for span in &*parse_sess.gated_spans.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); } } From a01ba39b4b47e8dd397ccb5b6c0363ee168107b2 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 14 Sep 2019 21:29:59 +0300 Subject: [PATCH 6/7] feature_gate: Merge various attribute gating functions --- src/libsyntax/ext/expand.rs | 15 +-- src/libsyntax/feature_gate/builtin_attrs.rs | 1 + src/libsyntax/feature_gate/check.rs | 122 ++++++------------ src/libsyntax/feature_gate/mod.rs | 3 +- .../feature-gates/feature-gate-doc_alias.rs | 2 +- .../feature-gate-doc_alias.stderr | 2 +- .../ui/feature-gates/feature-gate-doc_cfg.rs | 2 +- .../feature-gates/feature-gate-doc_cfg.stderr | 2 +- .../feature-gates/feature-gate-doc_keyword.rs | 2 +- .../feature-gate-doc_keyword.stderr | 2 +- .../feature-gate-external_doc.rs | 2 +- .../feature-gate-external_doc.stderr | 2 +- 12 files changed, 54 insertions(+), 103 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 87e2d721f89a0..b80c530731dfc 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -26,7 +26,7 @@ use syntax_pos::{Span, DUMMY_SP, FileName}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use std::io::ErrorKind; -use std::{iter, mem}; +use std::{iter, mem, slice}; use std::ops::DerefMut; use std::rc::Rc; use std::path::PathBuf; @@ -1019,7 +1019,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn check_attributes(&mut self, attrs: &[ast::Attribute]) { let features = self.cx.ecfg.features.unwrap(); for attr in attrs.iter() { - self.check_attribute_inner(attr, features); + feature_gate::check_attribute(attr, self.cx.parse_sess, features); // macros are expanded before any lint passes so this warning has to be hardcoded if attr.path == sym::derive { @@ -1029,15 +1029,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } } } - - fn check_attribute(&mut self, at: &ast::Attribute) { - let features = self.cx.ecfg.features.unwrap(); - self.check_attribute_inner(at, features); - } - - fn check_attribute_inner(&mut self, at: &ast::Attribute, features: &Features) { - feature_gate::check_attribute(at, self.cx.parse_sess, features); - } } impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { @@ -1445,7 +1436,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { if let Some(file) = it.value_str() { let err_count = self.cx.parse_sess.span_diagnostic.err_count(); - self.check_attribute(&at); + self.check_attributes(slice::from_ref(at)); if self.cx.parse_sess.span_diagnostic.err_count() > err_count { // avoid loading the file if they haven't enabled the feature return noop_visit_attribute(at, self); diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs index 763c3ffd782df..b6e13200f32af 100644 --- a/src/libsyntax/feature_gate/builtin_attrs.rs +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -79,6 +79,7 @@ pub enum AttributeType { CrateLevel, } +#[derive(Clone, Copy)] pub enum AttributeGate { /// Is gated by a given feature gate, reason /// and function to check if enabled diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index ddf847ca3a34c..3a9dae5a8b217 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -1,7 +1,7 @@ use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState}; use super::accepted::ACCEPTED_FEATURES; use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES}; -use super::builtin_attrs::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; +use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use crate::ast::{ self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, @@ -61,40 +61,46 @@ macro_rules! gate_feature { }; } -impl<'a> Context<'a> { - fn check_attribute( - &self, - attr: &ast::Attribute, - attr_info: Option<&BuiltinAttribute>, - ) { - debug!("check_attribute(attr = {:?})", attr); - if let Some(&(name, ty, _template, ref gateage)) = attr_info { - if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage { - if !attr.span.allows_unstable(name) { - gate_feature_fn!( - self, has_feature, attr.span, name, desc, GateStrength::Hard - ); - } - } else if name == sym::doc { - if let Some(content) = attr.meta_item_list() { - if content.iter().any(|c| c.check_name(sym::include)) { - gate_feature!(self, external_doc, attr.span, - "`#[doc(include = \"...\")]` is experimental" - ); - } - } +crate fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { + let cx = &Context { parse_sess, features }; + let attr_info = + attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + // Check feature gates for built-in attributes. + if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { + gate_feature_fn!(cx, has_feature, attr.span, name, descr, GateStrength::Hard); + } + // Check input tokens for built-in and key-value attributes. + match attr_info { + // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. + Some((name, _, template, _)) if name != sym::rustc_dummy => + check_builtin_attribute(parse_sess, attr, name, template), + _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { + if token == token::Eq { + // All key-value attributes are restricted to meta-item syntax. + attr.parse_meta(parse_sess).map_err(|mut err| err.emit()).ok(); } - debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); } } -} - -pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { - let cx = Context { parse_sess, features }; - cx.check_attribute( - attr, - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)), - ); + // Check unstable flavors of the `#[doc]` attribute. + if attr.check_name(sym::doc) { + for nested_meta in attr.meta_item_list().unwrap_or_default() { + macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => { + $(if nested_meta.check_name(sym::$name) { + let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental"); + gate_feature!(cx, $feature, attr.span, msg); + })* + }} + + gate_doc!( + include => external_doc + cfg => doc_cfg + masked => doc_masked + spotlight => doc_spotlight + alias => doc_alias + keyword => doc_keyword + ); + } + } } fn find_lang_feature_issue(feature: Symbol) -> Option { @@ -210,7 +216,6 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str = struct PostExpansionVisitor<'a> { context: &'a Context<'a>, - builtin_attributes: &'static FxHashMap, } macro_rules! gate_feature_post { @@ -287,50 +292,7 @@ impl<'a> PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { - let attr_info = attr.ident().and_then(|ident| { - self.builtin_attributes.get(&ident.name).map(|a| *a) - }); - - // Check for gated attributes. - self.context.check_attribute(attr, attr_info); - - if attr.check_name(sym::doc) { - if let Some(content) = attr.meta_item_list() { - if content.len() == 1 && content[0].check_name(sym::cfg) { - gate_feature_post!(&self, doc_cfg, attr.span, - "`#[doc(cfg(...))]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::masked)) { - gate_feature_post!(&self, doc_masked, attr.span, - "`#[doc(masked)]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::spotlight)) { - gate_feature_post!(&self, doc_spotlight, attr.span, - "`#[doc(spotlight)]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::alias)) { - gate_feature_post!(&self, doc_alias, attr.span, - "`#[doc(alias = \"...\")]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::keyword)) { - gate_feature_post!(&self, doc_keyword, attr.span, - "`#[doc(keyword = \"...\")]` is experimental" - ); - } - } - } - - match attr_info { - // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some(&(name, _, template, _)) if name != sym::rustc_dummy => - check_builtin_attribute(self.context.parse_sess, attr, name, template), - _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { - if token == token::Eq { - // All key-value attributes are restricted to meta-item syntax. - attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok(); - } - } - } + check_attribute(attr, self.context.parse_sess, self.context.features); } fn visit_name(&mut self, sp: Span, name: ast::Name) { @@ -864,11 +826,7 @@ pub fn check_crate(krate: &ast::Crate, gate_all!(yields, generators, "yield syntax is experimental"); gate_all!(or_patterns, "or-patterns syntax is experimental"); - let visitor = &mut PostExpansionVisitor { - context: &ctx, - builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP, - }; - visit::walk_crate(visitor, krate); + visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate); } #[derive(Clone, Copy, Hash)] diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs index 1e41667ea411e..ca13ab3620508 100644 --- a/src/libsyntax/feature_gate/mod.rs +++ b/src/libsyntax/feature_gate/mod.rs @@ -58,7 +58,8 @@ pub use builtin_attrs::{ deprecated_attributes, is_builtin_attr, is_builtin_attr_name, }; pub use check::{ - check_attribute, check_crate, get_features, feature_err, emit_feature_err, + check_crate, get_features, feature_err, emit_feature_err, Stability, GateIssue, UnstableFeatures, EXPLAIN_STMT_ATTR_SYNTAX, EXPLAIN_UNSIZED_TUPLE_COERCION, }; +crate use check::check_attribute; diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.rs b/src/test/ui/feature-gates/feature-gate-doc_alias.rs index adb6fc217a329..c95722102d9b6 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_alias.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_alias.rs @@ -1,4 +1,4 @@ -#[doc(alias = "foo")] //~ ERROR: `#[doc(alias = "...")]` is experimental +#[doc(alias = "foo")] //~ ERROR: `#[doc(alias)]` is experimental pub struct Foo; fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr index dddaa45de8ff8..540b1f5ccbe43 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[doc(alias = "...")]` is experimental +error[E0658]: `#[doc(alias)]` is experimental --> $DIR/feature-gate-doc_alias.rs:1:1 | LL | #[doc(alias = "foo")] diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs index bb3846e7f6b55..b12b8a1057182 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs @@ -1,2 +1,2 @@ -#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg(...))]` is experimental +#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg)]` is experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr index 7b0a231df4c3e..eaa908d0037ae 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[doc(cfg(...))]` is experimental +error[E0658]: `#[doc(cfg)]` is experimental --> $DIR/feature-gate-doc_cfg.rs:1:1 | LL | #[doc(cfg(unix))] diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs index 6cdcfa67c3a9b..4bb9a40deb0dd 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs @@ -1,4 +1,4 @@ -#[doc(keyword = "match")] //~ ERROR: `#[doc(keyword = "...")]` is experimental +#[doc(keyword = "match")] //~ ERROR: `#[doc(keyword)]` is experimental /// wonderful mod foo{} diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr index abde0bea9b230..15a41d9ffa4ea 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[doc(keyword = "...")]` is experimental +error[E0658]: `#[doc(keyword)]` is experimental --> $DIR/feature-gate-doc_keyword.rs:1:1 | LL | #[doc(keyword = "match")] diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.rs b/src/test/ui/feature-gates/feature-gate-external_doc.rs index dec3fa185791c..9d68d3ec4f52a 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.rs +++ b/src/test/ui/feature-gates/feature-gate-external_doc.rs @@ -1,2 +1,2 @@ -#[doc(include="asdf.md")] //~ ERROR: `#[doc(include = "...")]` is experimental +#[doc(include="asdf.md")] //~ ERROR: `#[doc(include)]` is experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.stderr b/src/test/ui/feature-gates/feature-gate-external_doc.stderr index a5a874374d1eb..683c0ad217426 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.stderr +++ b/src/test/ui/feature-gates/feature-gate-external_doc.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[doc(include = "...")]` is experimental +error[E0658]: `#[doc(include)]` is experimental --> $DIR/feature-gate-external_doc.rs:1:1 | LL | #[doc(include="asdf.md")] From cb771fdd6c927a4308440cad1607570140f058d6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 14 Sep 2019 21:54:16 +0300 Subject: [PATCH 7/7] feature_gate: Eliminate `check::Context` Use `PostExpansionVisitor` directly instead --- src/libsyntax/feature_gate/check.rs | 110 +++++++++++++--------------- 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 3a9dae5a8b217..b4491a87f0600 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -32,15 +32,10 @@ pub enum Stability { Deprecated(&'static str, Option<&'static str>), } -struct Context<'a> { - parse_sess: &'a ParseSess, - features: &'a Features, -} - macro_rules! gate_feature_fn { ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{ let (cx, has_feature, span, - name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level); + name, explain, level) = (&*$cx, $has_feature, $span, $name, $explain, $level); let has_feature: bool = has_feature(&$cx.features); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); if !has_feature && !span.allows_unstable($name) { @@ -62,45 +57,7 @@ macro_rules! gate_feature { } crate fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { - let cx = &Context { parse_sess, features }; - let attr_info = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); - // Check feature gates for built-in attributes. - if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { - gate_feature_fn!(cx, has_feature, attr.span, name, descr, GateStrength::Hard); - } - // Check input tokens for built-in and key-value attributes. - match attr_info { - // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some((name, _, template, _)) if name != sym::rustc_dummy => - check_builtin_attribute(parse_sess, attr, name, template), - _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { - if token == token::Eq { - // All key-value attributes are restricted to meta-item syntax. - attr.parse_meta(parse_sess).map_err(|mut err| err.emit()).ok(); - } - } - } - // Check unstable flavors of the `#[doc]` attribute. - if attr.check_name(sym::doc) { - for nested_meta in attr.meta_item_list().unwrap_or_default() { - macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => { - $(if nested_meta.check_name(sym::$name) { - let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental"); - gate_feature!(cx, $feature, attr.span, msg); - })* - }} - - gate_doc!( - include => external_doc - cfg => doc_cfg - masked => doc_masked - spotlight => doc_spotlight - alias => doc_alias - keyword => doc_keyword - ); - } - } + PostExpansionVisitor { parse_sess, features }.visit_attribute(attr) } fn find_lang_feature_issue(feature: Symbol) -> Option { @@ -215,20 +172,21 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str = "unsized tuple coercion is not stable enough for use and is subject to change"; struct PostExpansionVisitor<'a> { - context: &'a Context<'a>, + parse_sess: &'a ParseSess, + features: &'a Features, } macro_rules! gate_feature_post { ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{ let (cx, span) = ($cx, $span); if !span.allows_unstable(sym::$feature) { - gate_feature!(cx.context, $feature, span, $explain) + gate_feature!(cx, $feature, span, $explain) } }}; ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{ let (cx, span) = ($cx, $span); if !span.allows_unstable(sym::$feature) { - gate_feature!(cx.context, $feature, span, $explain, $level) + gate_feature!(cx, $feature, span, $explain, $level) } }} } @@ -292,7 +250,44 @@ impl<'a> PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { - check_attribute(attr, self.context.parse_sess, self.context.features); + let attr_info = + attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + // Check feature gates for built-in attributes. + if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { + gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard); + } + // Check input tokens for built-in and key-value attributes. + match attr_info { + // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. + Some((name, _, template, _)) if name != sym::rustc_dummy => + check_builtin_attribute(self.parse_sess, attr, name, template), + _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { + if token == token::Eq { + // All key-value attributes are restricted to meta-item syntax. + attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok(); + } + } + } + // Check unstable flavors of the `#[doc]` attribute. + if attr.check_name(sym::doc) { + for nested_meta in attr.meta_item_list().unwrap_or_default() { + macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => { + $(if nested_meta.check_name(sym::$name) { + let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental"); + gate_feature!(self, $feature, attr.span, msg); + })* + }} + + gate_doc!( + include => external_doc + cfg => doc_cfg + masked => doc_masked + spotlight => doc_spotlight + alias => doc_alias + keyword => doc_keyword + ); + } + } } fn visit_name(&mut self, sp: Span, name: ast::Name) { @@ -300,7 +295,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!( &self, non_ascii_idents, - self.context.parse_sess.source_map().def_span(sp), + self.parse_sess.source_map().def_span(sp), "non-ascii idents are not fully supported" ); } @@ -356,12 +351,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - let has_feature = self.context.features.arbitrary_enum_discriminant; + let has_feature = self.features.arbitrary_enum_discriminant; if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) { - Parser::maybe_report_invalid_custom_discriminants( - self.context.parse_sess, - &variants, - ); + Parser::maybe_report_invalid_custom_discriminants(self.parse_sess, &variants); } } @@ -471,7 +463,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ExprKind::Type(..) => { // To avoid noise about type ascription in common syntax errors, only emit if it // is the *only* error. - if self.context.parse_sess.span_diagnostic.err_count() == 0 { + if self.parse_sess.span_diagnostic.err_count() == 0 { gate_feature_post!(&self, type_ascription, e.span, "type ascription is experimental"); } @@ -809,13 +801,13 @@ pub fn check_crate(krate: &ast::Crate, features: &Features, unstable: UnstableFeatures) { maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable); - let ctx = Context { parse_sess, features }; + let mut visitor = PostExpansionVisitor { parse_sess, features }; macro_rules! gate_all { ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); }; ($spans:ident, $gate:ident, $msg:literal) => { for span in &*parse_sess.gated_spans.$spans.borrow() { - gate_feature!(&ctx, $gate, *span, $msg); + gate_feature!(&visitor, $gate, *span, $msg); } } } @@ -826,7 +818,7 @@ pub fn check_crate(krate: &ast::Crate, gate_all!(yields, generators, "yield syntax is experimental"); gate_all!(or_patterns, "or-patterns syntax is experimental"); - visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate); + visit::walk_crate(&mut visitor, krate); } #[derive(Clone, Copy, Hash)]