From 0fd8cb45b4f19b433aea080c5e0f296954db8ded Mon Sep 17 00:00:00 2001 From: Havvy Date: Wed, 30 May 2018 00:37:32 -0700 Subject: [PATCH 01/34] Update outdated comment for split_auto_traits private fn --- src/librustc_typeck/astconv.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 68587fb8b3c1e..bce331862e1f4 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1318,7 +1318,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } -/// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the +/// Divides a list of general trait bounds into two groups: auto traits (e.g. Sync and Send) and the /// remaining general trait bounds. fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_bounds: &'b [hir::PolyTraitRef]) From 11c283cdfc536c2d0c984bea47c7ab246d4ed5d3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 21 Apr 2018 17:18:38 +0300 Subject: [PATCH 02/34] Prohibit duplicate `macro_export`s --- src/librustc/lint/builtin.rs | 13 ++++++++++++ src/librustc_lint/lib.rs | 5 +++++ src/librustc_resolve/resolve_imports.rs | 16 ++++++++++++--- src/test/run-pass/auxiliary/issue_38715.rs | 2 ++ src/test/run-pass/auxiliary/two_macros_2.rs | 13 ++++++++++++ src/test/run-pass/mod_dir_path.rs | 4 ++-- src/test/ui/issue-38715.rs | 16 +++++++++++++++ src/test/ui/issue-38715.stderr | 22 +++++++++++++++++++++ 8 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/auxiliary/two_macros_2.rs create mode 100644 src/test/ui/issue-38715.rs create mode 100644 src/test/ui/issue-38715.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de583e81ca831..d0cf30b6e069d 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -17,6 +17,7 @@ use errors::{Applicability, DiagnosticBuilder}; use lint::{LintPass, LateLintPass, LintArray}; use session::Session; +use syntax::ast; use syntax::codemap::Span; declare_lint! { @@ -285,6 +286,12 @@ declare_lint! { "warns about duplicate associated type bindings in generics" } +declare_lint! { + pub DUPLICATE_MACRO_EXPORTS, + Deny, + "detects duplicate macro exports" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -337,6 +344,7 @@ impl LintPass for HardwiredLints { ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISIONS, DUPLICATE_ASSOCIATED_TYPE_BINDINGS, + DUPLICATE_MACRO_EXPORTS, ) } } @@ -348,6 +356,7 @@ pub enum BuiltinLintDiagnostics { Normal, BareTraitObject(Span, /* is_global */ bool), AbsPathWithModule(Span), + DuplicatedMacroExports(ast::Ident, Span, Span), } impl BuiltinLintDiagnostics { @@ -380,6 +389,10 @@ impl BuiltinLintDiagnostics { }; db.span_suggestion_with_applicability(span, "use `crate`", sugg, app); } + BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => { + db.span_label(later_span, format!("`{}` already exported", ident)); + db.span_note(earlier_span, "previous macro export is now shadowed"); + } } } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c5994d0536ee0..6905b7beeef47 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -212,6 +212,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #35203 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(DUPLICATE_MACRO_EXPORTS), + reference: "issue #35896 ", + edition: Some(Edition::Edition2018), + }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 34f84597adfc5..df96f5982cbfc 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -18,13 +18,14 @@ use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc::ty; -use rustc::lint::builtin::PUB_USE_OF_PRIVATE_EXTERN_CRATE; +use rustc::lint::builtin::BuiltinLintDiagnostics; +use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use syntax::ast::{Ident, Name, NodeId}; +use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::hygiene::Mark; use syntax::symbol::keywords; @@ -974,7 +975,16 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if module as *const _ == self.graph_root as *const _ { let macro_exports = mem::replace(&mut self.macro_exports, Vec::new()); for export in macro_exports.into_iter().rev() { - if exported_macro_names.insert(export.ident.modern(), export.span).is_none() { + if let Some(later_span) = exported_macro_names.insert(export.ident.modern(), + export.span) { + self.session.buffer_lint_with_diagnostic( + DUPLICATE_MACRO_EXPORTS, + CRATE_NODE_ID, + later_span, + &format!("a macro named `{}` has already been exported", export.ident), + BuiltinLintDiagnostics::DuplicatedMacroExports( + export.ident, export.span, later_span)); + } else { reexports.push(export); } } diff --git a/src/test/run-pass/auxiliary/issue_38715.rs b/src/test/run-pass/auxiliary/issue_38715.rs index cad3996eadbfb..cf4fee0e515c9 100644 --- a/src/test/run-pass/auxiliary/issue_38715.rs +++ b/src/test/run-pass/auxiliary/issue_38715.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(duplicate_macro_exports)] + #[macro_export] macro_rules! foo { ($i:ident) => {} } diff --git a/src/test/run-pass/auxiliary/two_macros_2.rs b/src/test/run-pass/auxiliary/two_macros_2.rs new file mode 100644 index 0000000000000..b16cd3a421095 --- /dev/null +++ b/src/test/run-pass/auxiliary/two_macros_2.rs @@ -0,0 +1,13 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } + +macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } diff --git a/src/test/run-pass/mod_dir_path.rs b/src/test/run-pass/mod_dir_path.rs index e2f33963c4bad..fc91ea870d51a 100644 --- a/src/test/run-pass/mod_dir_path.rs +++ b/src/test/run-pass/mod_dir_path.rs @@ -20,12 +20,12 @@ pub fn main() { #[path = "auxiliary"] mod foo { - mod two_macros; + mod two_macros_2; } #[path = "auxiliary"] mod bar { - macro_rules! m { () => { mod two_macros; } } + macro_rules! m { () => { mod two_macros_2; } } m!(); } } diff --git a/src/test/ui/issue-38715.rs b/src/test/ui/issue-38715.rs new file mode 100644 index 0000000000000..552653c21bad6 --- /dev/null +++ b/src/test/ui/issue-38715.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_export] +macro_rules! foo { ($i:ident) => {} } + +#[macro_export] +macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported + //~| WARN this was previously accepted diff --git a/src/test/ui/issue-38715.stderr b/src/test/ui/issue-38715.stderr new file mode 100644 index 0000000000000..a0dbcbd18c673 --- /dev/null +++ b/src/test/ui/issue-38715.stderr @@ -0,0 +1,22 @@ +error: a macro named `foo` has already been exported + --> $DIR/issue-38715.rs:15:1 + | +LL | macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` already exported + | + = note: #[deny(duplicate_macro_exports)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #35896 +note: previous macro export is now shadowed + --> $DIR/issue-38715.rs:12:1 + | +LL | macro_rules! foo { ($i:ident) => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0601]: `main` function not found in crate `issue_38715` + | + = note: consider adding a `main` function to `$DIR/issue-38715.rs` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0601`. From c1df62a760734748ce6f928d330dd7909c26557c Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 1 Jun 2018 10:05:46 -0400 Subject: [PATCH 03/34] Add closing bracket expectation to sequences, modified appropriate test cases. --- src/libsyntax/parse/parser.rs | 9 +++++++-- src/test/ui/resolve/token-error-correct-3.stderr | 4 ++-- src/test/ui/similar-tokens.stderr | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7b91c49170068..022de0fe4097c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -651,7 +651,7 @@ impl<'a> Parser<'a> { Err(err) } } else { - self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[]) + self.expect_one_of(slice::from_ref(t), &[]) } } @@ -1107,7 +1107,12 @@ impl<'a> Parser<'a> { { let mut first: bool = true; let mut v = vec![]; - while !kets.contains(&&self.token) { + while !kets.iter().any(|k| { + match expect { + TokenExpectType::Expect => self.check(k), + TokenExpectType::NoExpect => self.token == **k, + } + }) { match self.token { token::CloseDelim(..) | token::Eof => break, _ => {} diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 284acd20ba5e7..24186d94acce9 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -10,11 +10,11 @@ note: unclosed delimiter LL | callback(path.as_ref(); //~ ERROR expected one of | ^ -error: expected one of `,`, `.`, `?`, or an operator, found `;` +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` --> $DIR/token-error-correct-3.rs:24:35 | LL | callback(path.as_ref(); //~ ERROR expected one of - | ^ expected one of `,`, `.`, `?`, or an operator here + | ^ expected one of `)`, `,`, `.`, `?`, or an operator here error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` --> $DIR/token-error-correct-3.rs:30:9 diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr index fe157b99e65da..e43750b982a35 100644 --- a/src/test/ui/similar-tokens.stderr +++ b/src/test/ui/similar-tokens.stderr @@ -1,8 +1,8 @@ error: expected one of `,`, `::`, or `as`, found `.` --> $DIR/similar-tokens.rs:17:10 | -LL | use x::{A. B}; //~ ERROR expected one of `,`, `::`, or `as`, found `.` - | ^ expected one of `,`, `::`, or `as` here +LL | use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.` + | ^ expected one of `,`, `::`, `as`, or `}` here error: aborting due to previous error From a771580f675eec95d551f6c2971ccc13ce9c2298 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 1 Jun 2018 10:08:56 -0400 Subject: [PATCH 04/34] Modified another test case to expect a closing delimiter. --- src/test/ui/token/issue-10636-2.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index 56a30423171da..6c0053f2f8597 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -10,11 +10,11 @@ note: unclosed delimiter LL | option.map(|some| 42; | ^ -error: expected one of `,`, `.`, `?`, or an operator, found `;` +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` --> $DIR/issue-10636-2.rs:15:25 | LL | option.map(|some| 42; - | ^ expected one of `,`, `.`, `?`, or an operator here + | ^ expected one of `)`, `,`, `.`, `?`, or an operator here error: expected expression, found `)` --> $DIR/issue-10636-2.rs:18:1 From bfdd90c72267feef4aac9e16267475e9f5980401 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 1 Jun 2018 15:51:00 -0400 Subject: [PATCH 05/34] Modified test case again. --- src/test/ui/similar-tokens.rs | 2 +- src/test/ui/similar-tokens.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/similar-tokens.rs index eb7eab9e42dd7..350a2262391b5 100644 --- a/src/test/ui/similar-tokens.rs +++ b/src/test/ui/similar-tokens.rs @@ -14,6 +14,6 @@ mod x { } // `.` is similar to `,` so list parsing should continue to closing `}` -use x::{A. B}; //~ ERROR expected one of `,`, `::`, or `as`, found `.` +use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.` fn main() {} diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr index e43750b982a35..90acc56cbc999 100644 --- a/src/test/ui/similar-tokens.stderr +++ b/src/test/ui/similar-tokens.stderr @@ -1,4 +1,4 @@ -error: expected one of `,`, `::`, or `as`, found `.` +error: expected one of `,`, `::`, `as`, or `}`, found `.` --> $DIR/similar-tokens.rs:17:10 | LL | use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.` From 86ff9fa9c95b618605fad27bd752486c6259187b Mon Sep 17 00:00:00 2001 From: Havvy Date: Fri, 1 Jun 2018 08:52:07 -0700 Subject: [PATCH 06/34] Dedup auto traits in trait objects --- src/librustc_typeck/astconv.rs | 9 +++- src/test/run-pass/trait-object-auto-dedup.rs | 53 +++++++++++++++++++ .../ui/trait-object-auto-dedup-in-impl.rs | 29 ++++++++++ .../ui/trait-object-auto-dedup-in-impl.stderr | 12 +++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/trait-object-auto-dedup.rs create mode 100644 src/test/ui/trait-object-auto-dedup-in-impl.rs create mode 100644 src/test/ui/trait-object-auto-dedup-in-impl.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index bce331862e1f4..68553ece3a750 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -30,6 +30,7 @@ use util::common::ErrorReported; use util::nodemap::{FxHashSet, FxHashMap}; use errors::FatalError; +use std::cmp::Ordering; use std::iter; use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; @@ -706,10 +707,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { .emit(); } + // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`. + let mut auto_traits = + auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait).collect::>(); + auto_traits.sort_by(|a, b| a.cmp(tcx, b)); + auto_traits.dedup_by(|a, b| (&*a).cmp(tcx, b) == Ordering::Equal); + // skip_binder is okay, because the predicates are re-bound. let mut v = iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder())) - .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait)) + .chain(auto_traits.into_iter()) .chain(existential_projections .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder()))) .collect::>(); diff --git a/src/test/run-pass/trait-object-auto-dedup.rs b/src/test/run-pass/trait-object-auto-dedup.rs new file mode 100644 index 0000000000000..9f5845f6d77b0 --- /dev/null +++ b/src/test/run-pass/trait-object-auto-dedup.rs @@ -0,0 +1,53 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that duplicate auto trait bounds in trait objects don't create new types. +#[allow(unused_assignments)] + +use std::marker::Send as SendAlias; + +// A dummy trait for the non-auto trait. +trait Trait {} + +// A dummy struct to implement Trait, Send, and . +struct Struct; + +impl Trait for Struct {} + +// These three functions should be equivalent. +fn takes_dyn_trait_send(_: Box) {} +fn takes_dyn_trait_send_send(_: Box) {} +fn takes_dyn_trait_send_sendalias(_: Box) {} + +impl dyn Trait + Send + Send { + fn do_nothing(&self) {} +} + +fn main() { + // 1. Moving into a variable with more Sends and back. + let mut dyn_trait_send = Box::new(Struct) as Box; + let dyn_trait_send_send: Box = dyn_trait_send; + dyn_trait_send = dyn_trait_send_send; + + // 2. Calling methods with different number of Sends. + let dyn_trait_send = Box::new(Struct) as Box; + takes_dyn_trait_send_send(dyn_trait_send); + + let dyn_trait_send_send = Box::new(Struct) as Box; + takes_dyn_trait_send(dyn_trait_send_send); + + // 3. Aliases to the trait are transparent. + let dyn_trait_send = Box::new(Struct) as Box; + takes_dyn_trait_send_sendalias(dyn_trait_send); + + // 4. Calling an impl that duplicates an auto trait. + let dyn_trait_send = Box::new(Struct) as Box; + dyn_trait_send.do_nothing(); +} diff --git a/src/test/ui/trait-object-auto-dedup-in-impl.rs b/src/test/ui/trait-object-auto-dedup-in-impl.rs new file mode 100644 index 0000000000000..d3e4627a4c9b8 --- /dev/null +++ b/src/test/ui/trait-object-auto-dedup-in-impl.rs @@ -0,0 +1,29 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Checks to make sure that `dyn Trait + Send` and `dyn Trait + Send + Send` are the same type. +// Issue: #47010 + +struct Struct; +impl Trait for Struct {} +trait Trait {} + +type Send1 = Trait + Send; +type Send2 = Trait + Send + Send; + +fn main () {} + +impl Trait + Send { + fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test` +} + +impl Trait + Send + Send { + fn test(&self) { println!("two"); } +} diff --git a/src/test/ui/trait-object-auto-dedup-in-impl.stderr b/src/test/ui/trait-object-auto-dedup-in-impl.stderr new file mode 100644 index 0000000000000..9abd81cdcfa23 --- /dev/null +++ b/src/test/ui/trait-object-auto-dedup-in-impl.stderr @@ -0,0 +1,12 @@ +error[E0592]: duplicate definitions with name `test` + --> $DIR/trait-object-auto-dedup-in-impl.rs:24:5 + | +LL | fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `test` +... +LL | fn test(&self) { println!("two"); } + | ----------------------------------- other definition for `test` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. From b78457f0fbe15c21dc28efaef8146a0ff9d58059 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Sat, 2 Jun 2018 17:27:37 +0530 Subject: [PATCH 07/34] Stabilize unit tests with non-`()` return type --- src/libsyntax/feature_gate.rs | 6 +-- src/libsyntax/test.rs | 38 ++++--------------- .../feature-gate-termination_trait_test.rs | 22 ----------- .../termination-trait-in-test-should-panic.rs | 1 - .../termination-trait-in-test.rs | 1 - .../termination-trait-test-wrong-type.rs | 2 - 6 files changed, 10 insertions(+), 60 deletions(-) delete mode 100644 src/test/compile-fail/feature-gate-termination_trait_test.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9b84713b0f90f..ecda2b077e1f9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -398,9 +398,6 @@ declare_features! ( // `foo.rs` as an alternative to `foo/mod.rs` (active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)), - // Termination trait in tests (RFC 1937) - (active, termination_trait_test, "1.24.0", Some(48854), Some(Edition::Edition2018)), - // `extern` in paths (active, extern_in_paths, "1.23.0", Some(44660), None), @@ -475,6 +472,9 @@ declare_features! ( // 'a: { break 'a; } (active, label_break_value, "1.28.0", Some(48594), None), + + // Termination trait in tests (RFC 1937) + (accepted, termination_trait_test, "1.28.0", Some(48854), Some(Edition::Edition2018)), ); declare_features! ( diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index e63a3d47a828f..5506f408cd269 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -351,15 +351,15 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { return No(BadTestSignature::NoArgumentsAllowed); } - match (has_output, cx.features.termination_trait_test, has_should_panic_attr) { - (true, true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs), - (true, true, false) => if generics.is_parameterized() { + match (has_output, has_should_panic_attr) { + (true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs), + (true, false) => if generics.is_parameterized() { No(BadTestSignature::WrongTypeSignature) } else { Yes }, - (true, false, _) => No(BadTestSignature::WrongTypeSignature), - (false, _, _) => Yes + (true, _) => No(BadTestSignature::WrongTypeSignature), + (false, _) => Yes } } _ => No(BadTestSignature::NotEvenAFunction), @@ -398,28 +398,9 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { fn has_bench_signature(cx: &TestCtxt, i: &ast::Item) -> bool { match i.node { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { - let input_cnt = decl.inputs.len(); - - // If the termination trait is active, the compiler will check that the output - // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait_test { - true - } else { - let no_output = match decl.output { - ast::FunctionRetTy::Default(..) => true, - ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, - _ => false - }; - let tparm_cnt = generics.params.iter() - .filter(|param| param.is_type_param()) - .count(); - - no_output && tparm_cnt == 0 - }; - // NB: inadequate check, but we're running // well before resolve, can't get too deep. - input_cnt == 1 && output_matches + decl.inputs.len() == 1 } _ => false } @@ -430,13 +411,8 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { if has_bench_attr && !has_bench_signature { let diag = cx.span_diagnostic; - if cx.features.termination_trait_test { - diag.span_err(i.span, "functions used as benches must have signature \ + diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> impl Termination`"); - } else { - diag.span_err(i.span, "functions used as benches must have signature \ - `fn(&mut Bencher) -> ()`"); - } } has_bench_attr && has_bench_signature diff --git a/src/test/compile-fail/feature-gate-termination_trait_test.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs deleted file mode 100644 index 4af7e94671627..0000000000000 --- a/src/test/compile-fail/feature-gate-termination_trait_test.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags: --test - -fn main() {} - -#[cfg(test)] -mod tests { - #[test] - fn it_works() -> Result<(), ()> { - //~^ ERROR functions used as tests must have signature fn() -> () - Ok(()) - } -} diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs index 73a0150c0bb3f..a0b2784214ae9 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs @@ -10,7 +10,6 @@ // compile-flags: --test -#![feature(termination_trait_test)] #![feature(test)] extern crate test; diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs index 2cb4552a4b29e..0561b12221d1a 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -11,7 +11,6 @@ // compile-flags: --test // run-pass -#![feature(termination_trait_test)] #![feature(test)] extern crate test; diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs index 1c00edee770f2..6153d840c8a7d 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs @@ -10,8 +10,6 @@ // compile-flags: --test -#![feature(termination_trait_test)] - use std::num::ParseIntError; #[test] From bc7416213c20e165ebe723c4328667e8008c0794 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Sat, 2 Jun 2018 17:58:06 +0530 Subject: [PATCH 08/34] fixed feature gate to right place --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ecda2b077e1f9..9adfb61d92d32 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -473,8 +473,6 @@ declare_features! ( // 'a: { break 'a; } (active, label_break_value, "1.28.0", Some(48594), None), - // Termination trait in tests (RFC 1937) - (accepted, termination_trait_test, "1.28.0", Some(48854), Some(Edition::Edition2018)), ); declare_features! ( @@ -609,6 +607,8 @@ declare_features! ( (accepted, fn_must_use, "1.27.0", Some(43302), None), // Allows use of the :lifetime macro fragment specifier (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), + // Termination trait in tests (RFC 1937) + (accepted, termination_trait_test, "1.27.0", Some(48854), Some(Edition::Edition2018)), ); // If you change this, please modify src/doc/unstable-book as well. You must From 377cf44b4e52f5bf0f50b0c344bda71d810f0b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 4 Jun 2018 18:47:47 -0700 Subject: [PATCH 09/34] Suggest braces when a struct literal needs them When writing a struct literal in an expression that expects a block to be started afterwards (like an `if` statement), do not suggest using the same struct literal: ``` did you mean `S { /* fields * /}`? ``` Instead, suggest surrounding the expression with parentheses: ``` did you mean `(S { /* fields * /})`? ``` --- src/librustc_resolve/lib.rs | 34 ++++++++++++++++++++-- src/test/ui/error-codes/E0423.rs | 19 ++++++++++++ src/test/ui/error-codes/E0423.stderr | 43 ++++++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 453627f3c36b9..7bb7f2fffbc69 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2934,8 +2934,38 @@ impl<'a> Resolver<'a> { here due to private fields")); } } else { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); + // HACK(estebank): find a better way to figure out that this was a + // parser issue where a struct literal is being used on an expression + // where a brace being opened means a block is being started. Look + // ahead for the next text to see if `span` is followed by a `{`. + let cm = this.session.codemap(); + let mut sp = span; + loop { + sp = cm.next_point(sp); + match cm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet.chars().any(|c| { !c.is_whitespace() }) { + break; + } + } + _ => break, + } + } + let followed_by_brace = match cm.span_to_snippet(sp) { + Ok(ref snippet) if snippet == "{" => true, + _ => false, + }; + if let (PathSource::Expr(None), true) = (source, followed_by_brace) { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", path_str), + ); + } else { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", path_str), + ); + } } return (err, candidates); } diff --git a/src/test/ui/error-codes/E0423.rs b/src/test/ui/error-codes/E0423.rs index f5fea77cf9639..7d71499d3186b 100644 --- a/src/test/ui/error-codes/E0423.rs +++ b/src/test/ui/error-codes/E0423.rs @@ -13,3 +13,22 @@ fn main () { let f = Foo(); //~ ERROR E0423 } + +fn bar() { + struct S { x: i32, y: i32 } + #[derive(PartialEq)] + struct T {} + + if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } + //~^ ERROR E0423 + //~| expected type, found `1` + if T {} == T {} { println!("Ok"); } + //~^ ERROR E0423 + //~| ERROR expected expression, found `==` +} + +fn foo() { + for _ in std::ops::Range { start: 0, end: 10 } {} + //~^ ERROR E0423 + //~| ERROR expected type, found `0` +} diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index ef24295332d51..477c698ac9af1 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -1,9 +1,48 @@ +error: expected type, found `1` + --> $DIR/E0423.rs:22:39 + | +LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } + | ^ expecting a type here because of type ascription + +error: expected expression, found `==` + --> $DIR/E0423.rs:25:13 + | +LL | if T {} == T {} { println!("Ok"); } + | ^^ expected expression + +error: expected type, found `0` + --> $DIR/E0423.rs:31:39 + | +LL | for _ in std::ops::Range { start: 0, end: 10 } {} + | ^ expecting a type here because of type ascription + error[E0423]: expected function, found struct `Foo` --> $DIR/E0423.rs:14:13 | LL | let f = Foo(); //~ ERROR E0423 - | ^^^ did you mean `Foo { /* fields */ }`? + | ^^^ + | | + | did you mean `foo`? + | did you mean `Foo { /* fields */ }`? + +error[E0423]: expected value, found struct `S` + --> $DIR/E0423.rs:22:32 + | +LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } + | ^ did you mean `(S { /* fields */ })`? + +error[E0423]: expected value, found struct `T` + --> $DIR/E0423.rs:25:8 + | +LL | if T {} == T {} { println!("Ok"); } + | ^ did you mean `(T { /* fields */ })`? + +error[E0423]: expected value, found struct `std::ops::Range` + --> $DIR/E0423.rs:31:14 + | +LL | for _ in std::ops::Range { start: 0, end: 10 } {} + | ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`? -error: aborting due to previous error +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0423`. From 14e4a4224542a56bfa47fabefecde8fd818dba6c Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 4 Jun 2018 22:35:39 -0400 Subject: [PATCH 10/34] Changed a few tests, and changed the folder of a few of them. --- src/test/compile-fail/issue-39616.rs | 2 +- .../privacy/restricted => ui}/tuple-struct-fields/test.rs | 2 +- .../privacy/restricted => ui}/tuple-struct-fields/test2.rs | 2 +- .../privacy/restricted => ui}/tuple-struct-fields/test3.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/test/{compile-fail/privacy/restricted => ui}/tuple-struct-fields/test.rs (92%) rename src/test/{compile-fail/privacy/restricted => ui}/tuple-struct-fields/test2.rs (92%) rename src/test/{compile-fail/privacy/restricted => ui}/tuple-struct-fields/test3.rs (92%) diff --git a/src/test/compile-fail/issue-39616.rs b/src/test/compile-fail/issue-39616.rs index d601249c036b1..e5d0cbe34f32e 100644 --- a/src/test/compile-fail/issue-39616.rs +++ b/src/test/compile-fail/issue-39616.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo(a: [0; 1]) {} //~ ERROR expected type, found `0` -//~| ERROR expected one of `->`, `where`, or `{`, found `]` +//~| ERROR expected one of `)`, `->`, `where`, or `{`, found `]` // FIXME(jseyfried): avoid emitting the second error (preexisting) fn main() {} diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs b/src/test/ui/tuple-struct-fields/test.rs similarity index 92% rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs rename to src/test/ui/tuple-struct-fields/test.rs index d4ea76d6c2655..22d54a3834073 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs +++ b/src/test/ui/tuple-struct-fields/test.rs @@ -12,6 +12,6 @@ mod foo { type T = (); struct S1(pub(in foo) (), pub(T), pub(crate) (), pub(((), T))); struct S2(pub((foo)) ()); - //~^ ERROR expected `,`, found `(` + //~^ ERROR expected one of `)` or `,`, found `(` //~| ERROR cannot find type `foo` in this scope } diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs b/src/test/ui/tuple-struct-fields/test2.rs similarity index 92% rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs rename to src/test/ui/tuple-struct-fields/test2.rs index fed9432c6a0e9..eead027cb1351 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs +++ b/src/test/ui/tuple-struct-fields/test2.rs @@ -13,7 +13,7 @@ macro_rules! define_struct { struct S1(pub $t); struct S2(pub (in foo) ()); struct S3(pub $t ()); - //~^ ERROR expected `,`, found `(` + //~^ ERROR expected one of `)` or `,`, found `(` } } diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs b/src/test/ui/tuple-struct-fields/test3.rs similarity index 92% rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs rename to src/test/ui/tuple-struct-fields/test3.rs index dd2cb0e218422..d666c8abd3c95 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs +++ b/src/test/ui/tuple-struct-fields/test3.rs @@ -13,7 +13,7 @@ macro_rules! define_struct { struct S1(pub($t)); struct S2(pub (in foo) ()); struct S3(pub($t) ()); - //~^ ERROR expected `,`, found `(` + //~^ ERROR expected one of `)` or `,`, found `(` } } From 4cbf400366bb7d635cf4be31568b41992115220a Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Tue, 5 Jun 2018 23:28:32 +0530 Subject: [PATCH 11/34] flag changed to none --- src/libsyntax/feature_gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 17118e4dff2ee..4873062d659d9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -610,7 +610,7 @@ declare_features! ( // Allows use of the :lifetime macro fragment specifier (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), // Termination trait in tests (RFC 1937) - (accepted, termination_trait_test, "1.27.0", Some(48854), Some(Edition::Edition2018)), + (accepted, termination_trait_test, "1.27.0", Some(48854), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From e8fd74a11d66849c0b5b737d3bbe0cf121f8908e Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Tue, 5 Jun 2018 23:44:42 +0530 Subject: [PATCH 12/34] remove redundant match branch --- src/libsyntax/test.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 5506f408cd269..2d5606b2edeb9 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -358,7 +358,6 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { } else { Yes }, - (true, _) => No(BadTestSignature::WrongTypeSignature), (false, _) => Yes } } From 1048ae29a11f5e4ee188dde0d3ba39be2b05d8ed Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Wed, 6 Jun 2018 12:22:38 +0530 Subject: [PATCH 13/34] append unused variables with _ --- src/libsyntax/test.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 2d5606b2edeb9..0c7f70a578a26 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -335,7 +335,7 @@ enum BadTestSignature { fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_test_attr = attr::contains_name(&i.attrs, "test"); - fn has_test_signature(cx: &TestCtxt, i: &ast::Item) -> HasTestSignature { + fn has_test_signature(_cx: &TestCtxt, i: &ast::Item) -> HasTestSignature { let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic"); match i.node { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { @@ -394,9 +394,9 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_bench_attr = attr::contains_name(&i.attrs, "bench"); - fn has_bench_signature(cx: &TestCtxt, i: &ast::Item) -> bool { + fn has_bench_signature(_cx: &TestCtxt, i: &ast::Item) -> bool { match i.node { - ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { + ast::ItemKind::Fn(ref decl, _, _, _, _, _) => { // NB: inadequate check, but we're running // well before resolve, can't get too deep. decl.inputs.len() == 1 From 5c36e01f35c1e0290afd654367c2ba1e2353ca36 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Jun 2018 12:44:05 +1000 Subject: [PATCH 14/34] Use scope tree depths to speed up `nearest_common_ancestor`. This patch adds depth markings to all entries in the `ScopeTree`'s `parent_map`. This change increases memory usage somewhat, but permits a much faster algorithm to be used: - If one scope has a greater depth than the other, the deeper scope is moved upward until they are at equal depths. - Then we move the two scopes upward in lockstep until they match. This avoids the need to keep track of which scopes have already been seen, which was the major part of the cost of the old algorithm. It also reduces the number of child-to-parent moves (which are hash table lookups) when the scopes start at different levels, because it never goes past the nearest common ancestor the way the old algorithm did. Finally, the case where one of the scopes is the root is now handled in advance, because that is moderately common and lets us skip everything. This change speeds up runs of several rust-perf benchmarks, the best by 6%. --- src/librustc/middle/region.rs | 130 ++++++++++++++++++---------------- src/librustc_driver/test.rs | 7 +- 2 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 42a08afe305a5..0ba204dc20606 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -22,7 +22,6 @@ use ty; use std::fmt; use std::mem; -use rustc_data_structures::small_vec::SmallVec; use rustc_data_structures::sync::Lrc; use syntax::codemap; use syntax::ast; @@ -280,6 +279,8 @@ impl Scope { } } +pub type ScopeDepth = u32; + /// The region scope tree encodes information about region relationships. #[derive(Default, Debug)] pub struct ScopeTree { @@ -297,7 +298,7 @@ pub struct ScopeTree { /// conditional expression or repeating block. (Note that the /// enclosing scope id for the block associated with a closure is /// the closure itself.) - parent_map: FxHashMap, + parent_map: FxHashMap, /// `var_map` maps from a variable or binding id to the block in /// which that variable is declared. @@ -415,11 +416,12 @@ pub struct Context { /// details. root_id: Option, - /// the scope that contains any new variables declared - var_parent: Option, + /// The scope that contains any new variables declared, plus its depth in + /// the scope tree. + var_parent: Option<(Scope, ScopeDepth)>, - /// region parent of expressions etc - parent: Option, + /// Region parent of expressions, etc., plus its depth in the scope tree. + parent: Option<(Scope, ScopeDepth)>, } struct RegionResolutionVisitor<'a, 'tcx: 'a> { @@ -499,7 +501,7 @@ impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor { } impl<'tcx> ScopeTree { - pub fn record_scope_parent(&mut self, child: Scope, parent: Option) { + pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) { debug!("{:?}.parent = {:?}", child, parent); if let Some(p) = parent { @@ -515,7 +517,7 @@ impl<'tcx> ScopeTree { pub fn each_encl_scope(&self, mut e:E) where E: FnMut(Scope, Scope) { for (&child, &parent) in &self.parent_map { - e(child, parent) + e(child, parent.0) } } @@ -558,7 +560,7 @@ impl<'tcx> ScopeTree { pub fn opt_encl_scope(&self, id: Scope) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.parent_map.get(&id).cloned() + self.parent_map.get(&id).cloned().map(|(p, _)| p) } #[allow(dead_code)] // used in cfg @@ -590,7 +592,7 @@ impl<'tcx> ScopeTree { // returned. let mut id = Scope::Node(expr_id); - while let Some(&p) = self.parent_map.get(&id) { + while let Some(&(p, _)) = self.parent_map.get(&id) { match p.data() { ScopeData::Destruction(..) => { debug!("temporary_scope({:?}) = {:?} [enclosing]", @@ -658,57 +660,61 @@ impl<'tcx> ScopeTree { } } - /// Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest - /// scope which is greater than or equal to both `scope_a` and `scope_b`. - pub fn nearest_common_ancestor(&self, - scope_a: Scope, - scope_b: Scope) - -> Scope { + /// Finds the nearest common ancestor of two scopes. That is, finds the + /// smallest scope which is greater than or equal to both `scope_a` and + /// `scope_b`. + pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope { if scope_a == scope_b { return scope_a; } - // Process the lists in tandem from the innermost scope, recording the - // scopes seen so far. The first scope that comes up for a second time - // is the nearest common ancestor. - // - // Note: another way to compute the nearest common ancestor is to get - // the full scope chain for both scopes and then compare the chains to - // find the first scope in a common tail. But getting a parent scope - // requires a hash table lookup, and we often have very long scope - // chains (10s or 100s of scopes) that only differ by a few elements at - // the start. So this algorithm is faster. - - let mut ma = Some(&scope_a); - let mut mb = Some(&scope_b); - - // A HashSet is a more obvious choice for these, but SmallVec is - // faster because the set size is normally small so linear search is - // as good or better than a hash table lookup, plus the size is usually - // small enough to avoid a heap allocation. - let mut seen_a: SmallVec<[&Scope; 32]> = SmallVec::new(); - let mut seen_b: SmallVec<[&Scope; 32]> = SmallVec::new(); + let mut a = scope_a; + let mut b = scope_b; - loop { - if let Some(a) = ma { - if seen_b.iter().any(|s| *s == a) { - return *a; - } - seen_a.push(a); - ma = self.parent_map.get(&a); - } + // Get the depth of each scope's parent. If either scope has no parent, + // it must be the root, which means we can stop immediately because the + // root must be the nearest common ancestor. (In practice, this is + // moderately common.) + let (parent_a, parent_a_depth) = match self.parent_map.get(&a) { + Some(pd) => *pd, + None => return a, + }; + let (parent_b, parent_b_depth) = match self.parent_map.get(&b) { + Some(pd) => *pd, + None => return b, + }; - if let Some(b) = mb { - if seen_a.iter().any(|s| *s == b) { - return *b; - } - seen_b.push(b); - mb = self.parent_map.get(&b); + if parent_a_depth > parent_b_depth { + // `a` is lower than `b`. Move `a` up until it's at the same depth + // as `b`. The first move up is trivial because we already found + // `parent_a` above; the loop does the remaining N-1 moves. + a = parent_a; + for _ in 0..(parent_a_depth - parent_b_depth - 1) { + a = self.parent_map.get(&a).unwrap().0; } - - if ma.is_none() && mb.is_none() { - // No nearest common ancestor found. - bug!(); + } else if parent_b_depth > parent_a_depth { + // `b` is lower than `a`. + b = parent_b; + for _ in 0..(parent_b_depth - parent_a_depth - 1) { + b = self.parent_map.get(&b).unwrap().0; } + } else { + // Both scopes are at the same depth, and we know they're not equal + // because that case was tested for at the top of this function. So + // we can trivially move them both up one level now. + assert!(parent_a_depth != 0); + a = parent_a; + b = parent_b; } + + // Now both scopes are at the same level. We move upwards in lockstep + // until they match. In practice, this loop is almost always executed + // zero times because `a` is almost always a direct ancestor of `b` or + // vice versa. + while a != b { + a = self.parent_map.get(&a).unwrap().0; + b = self.parent_map.get(&b).unwrap().0; + }; + + a } /// Assuming that the provided region was defined within this `ScopeTree`, @@ -807,7 +813,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor, // // extern fn isalnum(c: c_int) -> c_int } - Some(parent_scope) => + Some((parent_scope, _)) => visitor.scope_tree.record_var_scope(var_id, parent_scope), } } @@ -1019,7 +1025,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr: // Keep traversing up while we can. match visitor.scope_tree.parent_map.get(&scope) { // Don't cross from closure bodies to their parent. - Some(&superscope) => match superscope.data() { + Some(&(superscope, _)) => match superscope.data() { ScopeData::CallSite(_) => break, _ => scope = superscope }, @@ -1036,7 +1042,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, init: Option<&'tcx hir::Expr>) { debug!("resolve_local(pat={:?}, init={:?})", pat, init); - let blk_scope = visitor.cx.var_parent; + let blk_scope = visitor.cx.var_parent.map(|(p, _)| p); // As an exception to the normal rules governing temporary // lifetimes, initializers in a let have a temporary lifetime @@ -1261,16 +1267,20 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> { /// Records the current parent (if any) as the parent of `child_scope`. - fn record_child_scope(&mut self, child_scope: Scope) { + /// Returns the depth of `child_scope`. + fn record_child_scope(&mut self, child_scope: Scope) -> ScopeDepth { let parent = self.cx.parent; self.scope_tree.record_scope_parent(child_scope, parent); + // If `child_scope` has no parent, it must be the root node, and so has + // a depth of 1. Otherwise, its depth is one more than its parent's. + parent.map_or(1, |(_p, d)| d + 1) } /// Records the current parent (if any) as the parent of `child_scope`, /// and sets `child_scope` as the new current parent. fn enter_scope(&mut self, child_scope: Scope) { - self.record_child_scope(child_scope); - self.cx.parent = Some(child_scope); + let child_depth = self.record_child_scope(child_scope); + self.cx.parent = Some((child_scope, child_depth)); } fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index b22817a066c43..206e58b3e2e27 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -191,11 +191,12 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { self.infcx.tcx } - pub fn create_region_hierarchy(&mut self, rh: &RH, parent: region::Scope) { + pub fn create_region_hierarchy(&mut self, rh: &RH, + parent: (region::Scope, region::ScopeDepth)) { let me = region::Scope::Node(rh.id); self.region_scope_tree.record_scope_parent(me, Some(parent)); for child_rh in rh.sub { - self.create_region_hierarchy(child_rh, me); + self.create_region_hierarchy(child_rh, (me, parent.1 + 1)); } } @@ -215,7 +216,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { id: hir::ItemLocalId(11), sub: &[], }], - }, dscope); + }, (dscope, 1)); } #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now From 5c7ca77b173e170f7440ba2cb5898cfc33874681 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 6 Jun 2018 13:46:51 +0200 Subject: [PATCH 15/34] Make the size of Option a documented guarantee. Closes #49137, the tracking issue for `NonZero*`, as this was the last remaining open question. Note that `ptr::NonNull` already documents a similar guarantee. --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 26dd08b10b9b8..c2da9006a8a92 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -39,10 +39,10 @@ macro_rules! nonzero_integers { $( /// An integer that is known not to equal zero. /// - /// This may enable some memory layout optimization such as: + /// This enables some memory layout optimization. + /// For example, `Option` is the same size as `u32`: /// /// ```rust - /// # #![feature(nonzero)] /// use std::mem::size_of; /// assert_eq!(size_of::>(), size_of::()); /// ``` From 8ecbd351bb80f03a76110ba9f7b9e6a68b3d2798 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Wed, 6 Jun 2018 20:51:57 +0530 Subject: [PATCH 16/34] fix stderrs --- .../termination-trait-in-test-should-panic.stderr | 2 +- .../termination-trait-test-wrong-type.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr index e3dab82df41b9..bfdcf01c325f7 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr @@ -1,5 +1,5 @@ error: functions using `#[should_panic]` must return `()` - --> $DIR/termination-trait-in-test-should-panic.rs:22:1 + --> $DIR/termination-trait-in-test-should-panic.rs:21:1 | LL | / fn not_a_num() -> Result<(), ParseIntError> { LL | | //~^ ERROR functions using `#[should_panic]` must return `()` diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr index 8efd8a216f10f..0972a0994fc0d 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr @@ -1,5 +1,5 @@ error[E0277]: `main` has invalid return type `std::result::Result` - --> $DIR/termination-trait-test-wrong-type.rs:18:1 + --> $DIR/termination-trait-test-wrong-type.rs:16:1 | LL | / fn can_parse_zero_as_f32() -> Result { //~ ERROR LL | | "0".parse() From 507dfd2148f68bc3bd6349d5e666b12e360a9d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 00:30:25 -0700 Subject: [PATCH 17/34] Use spans pointing at the inside of a rustdoc attribute --- src/librustdoc/clean/mod.rs | 46 +++++++++----- src/test/rustdoc-ui/intra-links-warning.rs | 8 ++- .../rustdoc-ui/intra-links-warning.stderr | 63 ++++++++++--------- 3 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1c1ba208678ed..8055c99ceb839 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1191,30 +1191,44 @@ fn resolution_failure( link_range: Option>, ) { let sp = span_of_attrs(attrs); - let mut diag = cx.sess() - .struct_span_warn(sp, &format!("[{}] cannot be resolved, ignoring it...", path_str)); + let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); - if let Some(link_range) = link_range { + let code_dox = sp.to_src(cx); + // The whitespace before the `///` to properly find the original span location. + let dox_leading_whitespace = code_dox.lines().nth(1) + .map(|x| x.len() - x.trim_left().len()).unwrap_or(0); + + let doc_comment_padding = 3; + let mut diag = if let Some(link_range) = link_range { // blah blah blah\nblah\nblah [blah] blah blah\nblah blah // ^ ~~~~~~ // | link_range // last_new_line_offset - let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1); - let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); - - // Print the line containing the `link_range` and manually mark it with '^'s - diag.note(&format!( - "the link appears in this line:\n\n{line}\n{indicator: $DIR/intra-links-warning.rs:13:1 +warning: `[Foo::baz]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:13:23 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +13 | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ cannot be resolved, ignoring + +warning: `[Bar::foo]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:13:35 | - = note: the link appears in this line: - - Test with [Foo::baz], [Bar::foo], ... - ^^^^^^^^ +13 | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ cannot be resolved, ignoring -warning: [Bar::foo] cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:13:1 +warning: `[Uniooon::X]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:14:15 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +14 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ cannot be resolved, ignoring + +warning: `[Qux::Z]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:14:32 | - = note: the link appears in this line: - - Test with [Foo::baz], [Bar::foo], ... - ^^^^^^^^ +14 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ cannot be resolved, ignoring -warning: [Uniooon::X] cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:13:1 +warning: `[Uniooon::X]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:16:15 | -13 | / //! Test with [Foo::baz], [Bar::foo], ... -14 | | //! -15 | | //! and [Uniooon::X]. - | |_____________________^ +16 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ cannot be resolved, ignoring + +warning: `[Qux::Z]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:16:32 + | +16 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ cannot be resolved, ignoring + +warning: `[Qux:Y]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:18:13 | - = note: the link appears in this line: - - and [Uniooon::X]. - ^^^^^^^^^^ +18 | /// [Qux:Y] + | ^^^^^ cannot be resolved, ignoring From 7d0b6b75f05a669ee8cc76e651a654296d7d166c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 09:14:09 -0700 Subject: [PATCH 18/34] When unable to sinthesize link span, fallback to previous behavior --- src/librustdoc/clean/mod.rs | 55 +++++++----- src/test/rustdoc-ui/intra-links-warning.rs | 42 ++++++++- .../rustdoc-ui/intra-links-warning.stderr | 87 ++++++++++++++++--- 3 files changed, 149 insertions(+), 35 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8055c99ceb839..226b3627e3e08 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1194,9 +1194,6 @@ fn resolution_failure( let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); let code_dox = sp.to_src(cx); - // The whitespace before the `///` to properly find the original span location. - let dox_leading_whitespace = code_dox.lines().nth(1) - .map(|x| x.len() - x.trim_left().len()).unwrap_or(0); let doc_comment_padding = 3; let mut diag = if let Some(link_range) = link_range { @@ -1205,26 +1202,44 @@ fn resolution_failure( // | link_range // last_new_line_offset - let line_offset = dox[..link_range.start].lines().count(); - let code_dox_len = if line_offset <= 1 { + let mut diag; + if dox.lines().count() == code_dox.lines().count() { + let line_offset = dox[..link_range.start].lines().count(); // The span starts in the `///`, so we don't have to account for the leading whitespace - doc_comment_padding - } else { - // The first `///` - doc_comment_padding + - // Each subsequent leading whitespace and `///` - (doc_comment_padding + dox_leading_whitespace) - // The line position inside the doc string - * (line_offset - 1) - }; + let code_dox_len = if line_offset <= 1 { + doc_comment_padding + } else { + // The first `///` + doc_comment_padding + + // Each subsequent leading whitespace and `///` + code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| { + sum + doc_comment_padding + line.len() - line.trim().len() + }) + }; - // Extract the specific span - let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32); - let hi = lo + syntax_pos::BytePos(link_range.len() as u32); - let sp = sp.with_lo(lo).with_hi(hi); + // Extract the specific span + let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32); + let hi = lo + syntax_pos::BytePos(link_range.len() as u32); + let sp = sp.with_lo(lo).with_hi(hi); - let mut diag = cx.sess().struct_span_warn(sp, &msg); - diag.span_label(sp, "cannot be resolved, ignoring"); + diag = cx.sess().struct_span_warn(sp, &msg); + diag.span_label(sp, "cannot be resolved, ignoring"); + } else { + diag = cx.sess().struct_span_warn(sp, &msg); + + let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1); + let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); + + // Print the line containing the `link_range` and manually mark it with '^'s + diag.note(&format!( + "the link appears in this line:\n\n{line}\n\ + {indicator: { + #[doc = $f] + pub fn f() {} + } +} +f!("Foo\nbar [BarF] bar\nbaz"); diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index a5a5598ed8fc8..52adba5679fe0 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -11,28 +11,28 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it... | ^^^^^^^^ cannot be resolved, ignoring warning: `[Uniooon::X]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:14:15 + --> $DIR/intra-links-warning.rs:14:13 | -14 | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ cannot be resolved, ignoring +14 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ cannot be resolved, ignoring warning: `[Qux::Z]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:14:32 + --> $DIR/intra-links-warning.rs:14:30 | -14 | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ cannot be resolved, ignoring +14 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ cannot be resolved, ignoring warning: `[Uniooon::X]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:16:15 + --> $DIR/intra-links-warning.rs:16:14 | -16 | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ cannot be resolved, ignoring +16 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ cannot be resolved, ignoring warning: `[Qux::Z]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:16:32 + --> $DIR/intra-links-warning.rs:16:31 | -16 | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ cannot be resolved, ignoring +16 | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ cannot be resolved, ignoring warning: `[Qux:Y]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:18:13 @@ -40,3 +40,66 @@ warning: `[Qux:Y]` cannot be resolved, ignoring it... 18 | /// [Qux:Y] | ^^^^^ cannot be resolved, ignoring +warning: `[BarA]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:24:10 + | +24 | /// bar [BarA] bar + | ^^^^ cannot be resolved, ignoring + +warning: `[BarB]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:28:1 + | +28 | / /** +29 | | * Foo +30 | | * bar [BarB] bar +31 | | * baz +32 | | */ + | |___^ + | + = note: the link appears in this line: + + bar [BarB] bar + ^^^^ + +warning: `[BarC]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:35:1 + | +35 | / /** Foo +36 | | +37 | | bar [BarC] bar +38 | | baz +... | +44 | | +45 | | */ + | |__^ + | + = note: the link appears in this line: + + bar [BarC] bar + ^^^^ + +warning: `[BarD]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:48:1 + | +48 | #[doc = "Foo/nbar [BarD] bar/nbaz"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + bar [BarD] bar + ^^^^ + +warning: `[BarF]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:53:9 + | +53 | #[doc = $f] + | ^^^^^^^^^^^ +... +57 | f!("Foo/nbar [BarF] bar/nbaz"); + | ------------------------------- in this macro invocation + | + = note: the link appears in this line: + + bar [BarF] bar + ^^^^ + From 36381fabaf18a6dfa0e9ee27b5045c2e8cf1c8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 10:02:09 -0700 Subject: [PATCH 19/34] Warn on `repr` without hints --- src/librustc/diagnostics.rs | 1 + src/librustc/hir/check_attr.rs | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 61f05ca347358..a526967aff0aa 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2139,6 +2139,7 @@ register_diagnostics! { E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders + E0689, // `#[repr]` must have a hint E0906, // closures cannot be static } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 591cb9d5ad6c2..1e642b98e18ce 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -154,7 +154,22 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let hints: Vec<_> = item.attrs .iter() .filter(|attr| attr.name() == "repr") - .filter_map(|attr| attr.meta_item_list()) + .filter_map(|attr| { + let list = attr.meta_item_list(); + let mut has_hints = false; + if let Some(ref list) = list { + has_hints = !list.is_empty(); + } + if !has_hints { + span_warn!( + self.tcx.sess, + item.span, + E0689, + "`repr` attribute cannot be empty", + ); + } + list + }) .flat_map(|hints| hints) .collect(); From 2c7099baeb6be82fcfec630b00d8a8175f5329f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 12:31:43 -0700 Subject: [PATCH 20/34] Expand output and suggestions, fix tests --- src/librustc/diagnostics.rs | 1 - src/librustc/hir/check_attr.rs | 59 +++- .../issue-43106-gating-of-builtin-attrs.rs | 5 + ...issue-43106-gating-of-builtin-attrs.stderr | 329 ++++++++++-------- src/test/ui/suggestions/repr.rs | 28 ++ src/test/ui/suggestions/repr.stderr | 24 ++ 6 files changed, 292 insertions(+), 154 deletions(-) create mode 100644 src/test/ui/suggestions/repr.rs create mode 100644 src/test/ui/suggestions/repr.stderr diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index a526967aff0aa..61f05ca347358 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2139,7 +2139,6 @@ register_diagnostics! { E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders - E0689, // `#[repr]` must have a hint E0906, // closures cannot be static } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 1e642b98e18ce..5c7c9a05964e0 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -14,7 +14,7 @@ //! conflicts between multiple such attributes attached to the same //! item. -use syntax_pos::Span; +use syntax_pos::{BytePos, Span}; use ty::TyCtxt; use hir; @@ -156,17 +156,54 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { .filter(|attr| attr.name() == "repr") .filter_map(|attr| { let list = attr.meta_item_list(); - let mut has_hints = false; - if let Some(ref list) = list { - has_hints = !list.is_empty(); - } + + // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or + // no hints (``#[repr]`) + let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false); if !has_hints { - span_warn!( - self.tcx.sess, - item.span, - E0689, - "`repr` attribute cannot be empty", - ); + let mut suggested = false; + let mut warn = if let Some(ref lit) = attr.value_str() { + // avoid warning about empty `repr` on `#[repr = "foo"]` + let sp = match format!("{}", lit).as_ref() { + "C" | "packed" | "rust" | "u*" | "i*" => { + let lo = attr.span.lo() + BytePos(2); + let hi = attr.span.hi() - BytePos(1); + suggested = true; + attr.span.with_lo(lo).with_hi(hi) + } + _ => attr.span, // the literal wasn't a valid `repr` arg + }; + let mut warn = self.tcx.sess.struct_span_warn( + sp, + "`repr` attribute isn't configurable with a literal", + ); + if suggested { + // if the literal could have been a valid `repr` arg, + // suggest the correct syntax + warn.span_suggestion( + sp, + "give `repr` a hint", + format!("repr({})", lit), + ); + } else { + warn.span_label(attr.span, "needs a hint"); + } + warn + } else { + let mut warn = self.tcx.sess.struct_span_warn( + attr.span, + "`repr` attribute must have a hint", + ); + warn.span_label(attr.span, "needs a hint"); + warn + }; + if !suggested { + warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \ + `#[repr(rust)]`"); + warn.note("for more information, visit \ + "); + } + warn.emit(); } list }) diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 76fb09f27bedf..4ba4464e87fa5 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -309,20 +309,25 @@ mod bench { #[repr = "3900"] //~^ WARN unused attribute +//~| WARN `repr` attribute isn't configurable with a literal mod repr { mod inner { #![repr="3900"] } //~^ WARN unused attribute + //~| WARN `repr` attribute isn't configurable with a literal #[repr = "3900"] fn f() { } //~^ WARN unused attribute + //~| WARN `repr` attribute isn't configurable with a literal struct S; #[repr = "3900"] type T = S; //~^ WARN unused attribute + //~| WARN `repr` attribute isn't configurable with a literal #[repr = "3900"] impl S { } //~^ WARN unused attribute + //~| WARN `repr` attribute isn't configurable with a literal } #[path = "3800"] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index f8e5f58ca0e89..6754e51707318 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1,11 +1,11 @@ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:498:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ @@ -186,6 +186,51 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1 + | +LL | #[repr = "3900"] + | ^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:17 + | +LL | mod inner { #![repr="3900"] } + | ^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:5 + | +LL | #[repr = "3900"] fn f() { } + | ^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 + | +LL | #[repr = "3900"] type T = S; + | ^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 + | +LL | #[repr = "3900"] impl S { } + | ^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5 | @@ -343,25 +388,25 @@ LL | #[start = "4300"] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:17 | LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:5 | LL | #[repr = "3900"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 | LL | #[repr = "3900"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 | LL | #[repr = "3900"] impl S { } | ^^^^^^^^^^^^^^^^ @@ -373,103 +418,103 @@ LL | #[repr = "3900"] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:5 | LL | #[path = "3800"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:340:5 | LL | #[path = "3800"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:5 | LL | #[path = "3800"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:346:5 | LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:17 | LL | mod inner { #![abi="3700"] } | ^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:356:5 | LL | #[abi = "3700"] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:359:5 | LL | #[abi = "3700"] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:357:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:362:5 | LL | #[abi = "3700"] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:5 | LL | #[abi = "3700"] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:1 | LL | #[abi = "3700"] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:17 | LL | mod inner { #![automatically_derived="3600"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:5 | LL | #[automatically_derived = "3600"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:5 | LL | #[automatically_derived = "3600"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:381:5 | LL | #[automatically_derived = "3600"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:5 | LL | #[automatically_derived = "3600"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:369:1 | LL | #[automatically_derived = "3600"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: function is marked #[no_mangle], but not exported - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:27 | LL | #[no_mangle = "3500"] fn f() { } | -^^^^^^^^^ @@ -479,709 +524,709 @@ LL | #[no_mangle = "3500"] fn f() { } = note: #[warn(private_no_mangle_fns)] on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:17 | LL | mod inner { #![no_link="3400"] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5 | LL | #[no_link = "3400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:406:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5 | LL | #[no_link = "3400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:409:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 | LL | #[no_link = "3400"]type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:412:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:5 | LL | #[no_link = "3400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:1 | LL | #[no_link = "3400"] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:17 | LL | mod inner { #![should_panic="3200"] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:422:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5 | LL | #[should_panic = "3200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:425:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5 | LL | #[should_panic = "3200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:428:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5 | LL | #[should_panic = "3200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:431:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:5 | LL | #[should_panic = "3200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:1 | LL | #[should_panic = "3200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:443:17 | LL | mod inner { #![ignore="3100"] } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:446:5 | LL | #[ignore = "3100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:449:5 | LL | #[ignore = "3100"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:447:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:452:5 | LL | #[ignore = "3100"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:5 | LL | #[ignore = "3100"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:440:1 | LL | #[ignore = "3100"] | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17 | LL | mod inner { #![no_implicit_prelude="3000"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5 | LL | #[no_implicit_prelude = "3000"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5 | LL | #[no_implicit_prelude = "3000"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 | LL | #[no_implicit_prelude = "3000"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5 | LL | #[no_implicit_prelude = "3000"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:1 | LL | #[no_implicit_prelude = "3000"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:481:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:490:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:504:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:507:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:510:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:17 | LL | mod inner { #![no_std="2600"] } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:17 | LL | mod inner { #![no_std="2600"] } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5 | LL | #[no_std = "2600"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5 | LL | #[no_std = "2600"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:5 | LL | #[no_std = "2600"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:5 | LL | #[no_std = "2600"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:533:5 | LL | #[no_std = "2600"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:533:5 | LL | #[no_std = "2600"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:537:5 | LL | #[no_std = "2600"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:537:5 | LL | #[no_std = "2600"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:517:1 | LL | #[no_std = "2600"] | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:517:1 | LL | #[no_std = "2600"] | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:730:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:730:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:811:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:811:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1259,7 +1304,7 @@ LL | #![proc_macro_derive = "2500"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: compilation successful - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:842:1 | LL | / fn main() { //~ ERROR compilation successful LL | | println!("Hello World"); diff --git a/src/test/ui/suggestions/repr.rs b/src/test/ui/suggestions/repr.rs new file mode 100644 index 0000000000000..312f60202c6c2 --- /dev/null +++ b/src/test/ui/suggestions/repr.rs @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +#[repr] +//^ WARN `repr` attribute must have a hint +struct _A {} + +#[repr = "B"] +//^ WARN `repr` attribute isn't configurable with a literal +struct _B {} + +#[repr = "C"] +//^ WARN `repr` attribute isn't configurable with a literal +struct _C {} + +#[repr(C)] +struct _D {} + +fn main() {} diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr new file mode 100644 index 0000000000000..6ed246d0d2c29 --- /dev/null +++ b/src/test/ui/suggestions/repr.stderr @@ -0,0 +1,24 @@ +warning: `repr` attribute must have a hint + --> $DIR/repr.rs:13:1 + | +LL | #[repr] + | ^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/repr.rs:17:1 + | +LL | #[repr = "B"] + | ^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/repr.rs:21:3 + | +LL | #[repr = "C"] + | ^^^^^^^^^^ help: give `repr` a hint: `repr(C)` + From 3580de8c6d6aa39a4b81a851deaf8bb9b6baf66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 14:11:48 -0700 Subject: [PATCH 21/34] Turn warning into lint --- src/librustc/hir/check_attr.rs | 56 +-- src/librustc/lint/builtin.rs | 6 + src/librustc_lint/builtin.rs | 69 +++ src/librustc_lint/lib.rs | 1 + .../issue-43106-gating-of-builtin-attrs.rs | 4 +- ...issue-43106-gating-of-builtin-attrs.stderr | 436 +++++++++--------- src/test/ui/suggestions/repr.stderr | 1 + 7 files changed, 305 insertions(+), 268 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 5c7c9a05964e0..591cb9d5ad6c2 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -14,7 +14,7 @@ //! conflicts between multiple such attributes attached to the same //! item. -use syntax_pos::{BytePos, Span}; +use syntax_pos::Span; use ty::TyCtxt; use hir; @@ -154,59 +154,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let hints: Vec<_> = item.attrs .iter() .filter(|attr| attr.name() == "repr") - .filter_map(|attr| { - let list = attr.meta_item_list(); - - // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or - // no hints (``#[repr]`) - let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false); - if !has_hints { - let mut suggested = false; - let mut warn = if let Some(ref lit) = attr.value_str() { - // avoid warning about empty `repr` on `#[repr = "foo"]` - let sp = match format!("{}", lit).as_ref() { - "C" | "packed" | "rust" | "u*" | "i*" => { - let lo = attr.span.lo() + BytePos(2); - let hi = attr.span.hi() - BytePos(1); - suggested = true; - attr.span.with_lo(lo).with_hi(hi) - } - _ => attr.span, // the literal wasn't a valid `repr` arg - }; - let mut warn = self.tcx.sess.struct_span_warn( - sp, - "`repr` attribute isn't configurable with a literal", - ); - if suggested { - // if the literal could have been a valid `repr` arg, - // suggest the correct syntax - warn.span_suggestion( - sp, - "give `repr` a hint", - format!("repr({})", lit), - ); - } else { - warn.span_label(attr.span, "needs a hint"); - } - warn - } else { - let mut warn = self.tcx.sess.struct_span_warn( - attr.span, - "`repr` attribute must have a hint", - ); - warn.span_label(attr.span, "needs a hint"); - warn - }; - if !suggested { - warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \ - `#[repr(rust)]`"); - warn.note("for more information, visit \ - "); - } - warn.emit(); - } - list - }) + .filter_map(|attr| attr.meta_item_list()) .flat_map(|hints| hints) .collect(); diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de583e81ca831..9fa6230670b67 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -206,6 +206,12 @@ declare_lint! { "potentially-conflicting impls were erroneously allowed" } +declare_lint! { + pub BAD_REPR, + Warn, + "detects incorrect use of `repr` attribute" +} + declare_lint! { pub DEPRECATED, Warn, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 79c7a79114761..fbd153982b7c4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -673,6 +673,75 @@ impl EarlyLintPass for AnonymousParameters { } } +/// Checks for incorrect use use of `repr` attributes. +#[derive(Clone)] +pub struct BadRepr; + +impl LintPass for BadRepr { + fn get_lints(&self) -> LintArray { + lint_array!() + } +} + +impl EarlyLintPass for BadRepr { + fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { + if attr.name() == "repr" { + let list = attr.meta_item_list(); + + // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or + // no hints (``#[repr]`) + let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false); + if !has_hints { + let mut suggested = false; + let mut warn = if let Some(ref lit) = attr.value_str() { + // avoid warning about empty `repr` on `#[repr = "foo"]` + let sp = match format!("{}", lit).as_ref() { + "C" | "packed" | "rust" | "u*" | "i*" => { + let lo = attr.span.lo() + BytePos(2); + let hi = attr.span.hi() - BytePos(1); + suggested = true; + attr.span.with_lo(lo).with_hi(hi) + } + _ => attr.span, // the literal wasn't a valid `repr` arg + }; + let mut warn = cx.struct_span_lint( + BAD_REPR, + sp, + "`repr` attribute isn't configurable with a literal", + ); + if suggested { + // if the literal could have been a valid `repr` arg, + // suggest the correct syntax + warn.span_suggestion( + sp, + "give `repr` a hint", + format!("repr({})", lit), + ); + } else { + warn.span_label(attr.span, "needs a hint"); + } + warn + } else { + let mut warn = cx.struct_span_lint( + BAD_REPR, + attr.span, + "`repr` attribute must have a hint", + ); + warn.span_label(attr.span, "needs a hint"); + warn + }; + if !suggested { + warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \ + `#[repr(rust)]`"); + warn.note("for more information, visit \ + "); + } + warn.emit(); + } + } + } +} + /// Checks for use of attributes which have been deprecated. #[derive(Clone)] pub struct DeprecatedAttr { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d6ce5b2ea57fe..e1106281f4523 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -107,6 +107,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedImportBraces, AnonymousParameters, UnusedDocComment, + BadRepr, ); add_early_builtin_with_new!(sess, diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 4ba4464e87fa5..db50b9514430c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -59,7 +59,9 @@ #![start = "x4300"] //~ WARN unused attribute // see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200" // see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100" -#![repr = "3900"] //~ WARN unused attribute +#![repr = "3900"] +//~^ WARN unused attribute +//~| WARN `repr` attribute isn't configurable with a literal #![path = "3800"] //~ WARN unused attribute #![abi = "3700"] //~ WARN unused attribute #![automatically_derived = "3600"] //~ WARN unused attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 6754e51707318..013504c554def 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1,11 +1,11 @@ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:498:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ @@ -43,169 +43,161 @@ LL | #![deny (x5100)] //~ WARN unknown lint: `x5100` | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:8 | LL | #[warn(x5400)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:25 | LL | mod inner { #![warn(x5400)] } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12 | LL | #[warn(x5400)] fn f() { } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:12 | LL | #[warn(x5400)] struct S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:12 | LL | #[warn(x5400)] type T = S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:12 | LL | #[warn(x5400)] impl S { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:9 | LL | #[allow(x5300)] | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:26 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:26 | LL | mod inner { #![allow(x5300)] } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13 | LL | #[allow(x5300)] fn f() { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:13 | LL | #[allow(x5300)] struct S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:13 | LL | #[allow(x5300)] type T = S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:13 | LL | #[allow(x5300)] impl S { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:10 | LL | #[forbid(x5200)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:27 | LL | mod inner { #![forbid(x5200)] } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14 | LL | #[forbid(x5200)] fn f() { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:14 | LL | #[forbid(x5200)] struct S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:14 | LL | #[forbid(x5200)] type T = S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:14 | LL | #[forbid(x5200)] impl S { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:8 | LL | #[deny(x5100)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:25 | LL | mod inner { #![deny(x5100)] } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:175:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12 | LL | #[deny(x5100)] fn f() { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:178:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:12 | LL | #[deny(x5100)] struct S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:181:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:12 | LL | #[deny(x5100)] type T = S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:12 | LL | #[deny(x5100)] impl S { } | ^^^^^ warning: `repr` attribute isn't configurable with a literal - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1 - | -LL | #[repr = "3900"] - | ^^^^^^^^^^^^^^^^ needs a hint - | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` - = note: for more information, visit - -warning: `repr` attribute isn't configurable with a literal - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17 | LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ needs a hint | + = note: #[warn(bad_repr)] on by default = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5 | LL | #[repr = "3900"] fn f() { } | ^^^^^^^^^^^^^^^^ needs a hint @@ -214,7 +206,7 @@ LL | #[repr = "3900"] fn f() { } = note: for more information, visit warning: `repr` attribute isn't configurable with a literal - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5 | LL | #[repr = "3900"] type T = S; | ^^^^^^^^^^^^^^^^ needs a hint @@ -223,7 +215,7 @@ LL | #[repr = "3900"] type T = S; = note: for more information, visit warning: `repr` attribute isn't configurable with a literal - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5 | LL | #[repr = "3900"] impl S { } | ^^^^^^^^^^^^^^^^ needs a hint @@ -231,8 +223,26 @@ LL | #[repr = "3900"] impl S { } = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` = note: for more information, visit +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:1 + | +LL | #[repr = "3900"] + | ^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + +warning: `repr` attribute isn't configurable with a literal + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 + | +LL | #![repr = "3900"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint + | + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = note: for more information, visit + warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5 | LL | #[macro_use] fn f() { } | ^^^^^^^^^^^^ @@ -244,277 +254,277 @@ LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:5 | LL | #[macro_use] struct S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:5 | LL | #[macro_use] type T = S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:203:5 | LL | #[macro_use] impl S { } | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:17 | LL | mod inner { #![macro_export="4800"] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:211:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5 | LL | #[macro_export = "4800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:5 | LL | #[macro_export = "4800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:5 | LL | #[macro_export = "4800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:222:5 | LL | #[macro_export = "4800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:1 | LL | #[macro_export = "4800"] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:229:17 | LL | mod inner { #![plugin_registrar="4700"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5 | LL | #[plugin_registrar = "4700"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:237:5 | LL | #[plugin_registrar = "4700"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5 | LL | #[plugin_registrar = "4700"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:1 | LL | #[plugin_registrar = "4700"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:17 | LL | mod inner { #![main="4300"] } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:5 | LL | #[main = "4400"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5 | LL | #[main = "4400"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:5 | LL | #[main = "4400"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:1 | LL | #[main = "4400"] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:17 | LL | mod inner { #![start="4300"] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5 | LL | #[start = "4300"] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5 | LL | #[start = "4300"] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:274:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5 | LL | #[start = "4300"] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:1 | LL | #[start = "4300"] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17 | LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5 | LL | #[repr = "3900"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5 | LL | #[repr = "3900"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5 | LL | #[repr = "3900"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:1 | LL | #[repr = "3900"] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:5 | LL | #[path = "3800"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:340:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:5 | LL | #[path = "3800"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5 | LL | #[path = "3800"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:346:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:5 | LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:17 | LL | mod inner { #![abi="3700"] } | ^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:356:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5 | LL | #[abi = "3700"] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:359:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5 | LL | #[abi = "3700"] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:362:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5 | LL | #[abi = "3700"] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5 | LL | #[abi = "3700"] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:1 | LL | #[abi = "3700"] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:17 | LL | mod inner { #![automatically_derived="3600"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5 | LL | #[automatically_derived = "3600"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5 | LL | #[automatically_derived = "3600"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:381:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5 | LL | #[automatically_derived = "3600"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5 | LL | #[automatically_derived = "3600"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:369:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:1 | LL | #[automatically_derived = "3600"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: function is marked #[no_mangle], but not exported - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:27 | LL | #[no_mangle = "3500"] fn f() { } | -^^^^^^^^^ @@ -524,709 +534,709 @@ LL | #[no_mangle = "3500"] fn f() { } = note: #[warn(private_no_mangle_fns)] on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:17 | LL | mod inner { #![no_link="3400"] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5 | LL | #[no_link = "3400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5 | LL | #[no_link = "3400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:5 | LL | #[no_link = "3400"]type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:5 | LL | #[no_link = "3400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:1 | LL | #[no_link = "3400"] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:17 | LL | mod inner { #![should_panic="3200"] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5 | LL | #[should_panic = "3200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5 | LL | #[should_panic = "3200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:5 | LL | #[should_panic = "3200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:5 | LL | #[should_panic = "3200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:1 | LL | #[should_panic = "3200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:443:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:17 | LL | mod inner { #![ignore="3100"] } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:446:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5 | LL | #[ignore = "3100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:449:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5 | LL | #[ignore = "3100"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:452:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5 | LL | #[ignore = "3100"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:5 | LL | #[ignore = "3100"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:440:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:1 | LL | #[ignore = "3100"] | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:17 | LL | mod inner { #![no_implicit_prelude="3000"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5 | LL | #[no_implicit_prelude = "3000"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5 | LL | #[no_implicit_prelude = "3000"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5 | LL | #[no_implicit_prelude = "3000"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5 | LL | #[no_implicit_prelude = "3000"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:1 | LL | #[no_implicit_prelude = "3000"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:481:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:490:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:504:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:507:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:509:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:510:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:515:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:17 | LL | mod inner { #![no_std="2600"] } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:17 | LL | mod inner { #![no_std="2600"] } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:5 | LL | #[no_std = "2600"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:5 | LL | #[no_std = "2600"] fn f() { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5 | LL | #[no_std = "2600"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5 | LL | #[no_std = "2600"] struct S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:533:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5 | LL | #[no_std = "2600"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:533:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5 | LL | #[no_std = "2600"] type T = S; | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:537:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:539:5 | LL | #[no_std = "2600"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:537:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:539:5 | LL | #[no_std = "2600"] impl S { } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:517:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:1 | LL | #[no_std = "2600"] | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:517:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:1 | LL | #[no_std = "2600"] | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:686:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:686:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:730:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:730:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:800:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:800:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:804:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:804:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:811:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:811:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1258,53 +1268,53 @@ LL | #![start = "x4300"] //~ WARN unused attribute warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 | -LL | #![repr = "3900"] //~ WARN unused attribute +LL | #![repr = "3900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1 | LL | #![path = "3800"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1 | LL | #![abi = "3700"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1 | LL | #![automatically_derived = "3600"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1 | LL | #![no_link = "3400"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1 | LL | #![should_panic = "3200"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1 | LL | #![ignore = "3100"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:78:1 | LL | #![proc_macro_derive = "2500"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: compilation successful - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:842:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:844:1 | LL | / fn main() { //~ ERROR compilation successful LL | | println!("Hello World"); diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr index 6ed246d0d2c29..24a22a81c4aa0 100644 --- a/src/test/ui/suggestions/repr.stderr +++ b/src/test/ui/suggestions/repr.stderr @@ -4,6 +4,7 @@ warning: `repr` attribute must have a hint LL | #[repr] | ^^^^^^^ needs a hint | + = note: #[warn(bad_repr)] on by default = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` = note: for more information, visit From 48e45eec30312e7490f3b24c7692d06f83d47d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 14:18:13 -0700 Subject: [PATCH 22/34] Add `transparent` as valid `repr` hint --- src/librustc_lint/builtin.rs | 6 +++--- .../issue-43106-gating-of-builtin-attrs.stderr | 12 ++++++------ src/test/ui/suggestions/repr.stderr | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index fbd153982b7c4..b1b1440fbd282 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -696,7 +696,7 @@ impl EarlyLintPass for BadRepr { let mut warn = if let Some(ref lit) = attr.value_str() { // avoid warning about empty `repr` on `#[repr = "foo"]` let sp = match format!("{}", lit).as_ref() { - "C" | "packed" | "rust" | "u*" | "i*" => { + "C" | "packed" | "rust" | "u*" | "i*" | "transparent" => { let lo = attr.span.lo() + BytePos(2); let hi = attr.span.hi() - BytePos(1); suggested = true; @@ -731,8 +731,8 @@ impl EarlyLintPass for BadRepr { warn }; if !suggested { - warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \ - `#[repr(rust)]`"); + warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]`, \ + `#[repr(rust)]` and `#[repr(transparent)]`"); warn.note("for more information, visit \ "); } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 013504c554def..2b6396249bb82 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -193,7 +193,7 @@ LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ needs a hint | = note: #[warn(bad_repr)] on by default - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -202,7 +202,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #[repr = "3900"] fn f() { } | ^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -211,7 +211,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #[repr = "3900"] type T = S; | ^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -220,7 +220,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #[repr = "3900"] impl S { } | ^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -229,7 +229,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #[repr = "3900"] | ^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -238,7 +238,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #![repr = "3900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: unused attribute diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr index 24a22a81c4aa0..efc7e0fd2bed5 100644 --- a/src/test/ui/suggestions/repr.stderr +++ b/src/test/ui/suggestions/repr.stderr @@ -5,7 +5,7 @@ LL | #[repr] | ^^^^^^^ needs a hint | = note: #[warn(bad_repr)] on by default - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -14,7 +14,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #[repr = "B"] | ^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal From 451eb66a53efdad9886bfb1525a217a3ca5beb1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 14:25:57 -0700 Subject: [PATCH 23/34] Expand (fix) u* and i* `repr` hints --- src/librustc_lint/builtin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index b1b1440fbd282..0987197db26c2 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -696,7 +696,9 @@ impl EarlyLintPass for BadRepr { let mut warn = if let Some(ref lit) = attr.value_str() { // avoid warning about empty `repr` on `#[repr = "foo"]` let sp = match format!("{}", lit).as_ref() { - "C" | "packed" | "rust" | "u*" | "i*" | "transparent" => { + | "C" | "packed" | "rust" | "transparent" + | "u8" | "u16" | "u32" | "u64" | "u128" + | "i8" | "i16" | "i32" | "i64" | "i128" => { let lo = attr.span.lo() + BytePos(2); let hi = attr.span.hi() - BytePos(1); suggested = true; From 9a80c2b99473d504c6e16d8fe55d3344d770320c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 14:33:07 -0700 Subject: [PATCH 24/34] Change repr documentation link --- src/librustc_lint/builtin.rs | 2 +- .../issue-43106-gating-of-builtin-attrs.stderr | 12 ++++++------ src/test/ui/suggestions/repr.stderr | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 0987197db26c2..0688e47606f72 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -736,7 +736,7 @@ impl EarlyLintPass for BadRepr { warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]`, \ `#[repr(rust)]` and `#[repr(transparent)]`"); warn.note("for more information, visit \ - "); + "); } warn.emit(); } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 2b6396249bb82..f351a9e69d011 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -194,7 +194,7 @@ LL | mod inner { #![repr="3900"] } | = note: #[warn(bad_repr)] on by default = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5 @@ -203,7 +203,7 @@ LL | #[repr = "3900"] fn f() { } | ^^^^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5 @@ -212,7 +212,7 @@ LL | #[repr = "3900"] type T = S; | ^^^^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5 @@ -221,7 +221,7 @@ LL | #[repr = "3900"] impl S { } | ^^^^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:1 @@ -230,7 +230,7 @@ LL | #[repr = "3900"] | ^^^^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 @@ -239,7 +239,7 @@ LL | #![repr = "3900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5 diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr index efc7e0fd2bed5..83f5bb48f7a08 100644 --- a/src/test/ui/suggestions/repr.stderr +++ b/src/test/ui/suggestions/repr.stderr @@ -6,7 +6,7 @@ LL | #[repr] | = note: #[warn(bad_repr)] on by default = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/repr.rs:17:1 @@ -15,7 +15,7 @@ LL | #[repr = "B"] | ^^^^^^^^^^^^^ needs a hint | = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` - = note: for more information, visit + = note: for more information, visit warning: `repr` attribute isn't configurable with a literal --> $DIR/repr.rs:21:3 From b3810f61da08bc986ffd854361e957e4b8d42560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 14:34:07 -0700 Subject: [PATCH 25/34] Add i/u size --- src/librustc_lint/builtin.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 0688e47606f72..5c05fdb5621a7 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -697,8 +697,8 @@ impl EarlyLintPass for BadRepr { // avoid warning about empty `repr` on `#[repr = "foo"]` let sp = match format!("{}", lit).as_ref() { | "C" | "packed" | "rust" | "transparent" - | "u8" | "u16" | "u32" | "u64" | "u128" - | "i8" | "i16" | "i32" | "i64" | "i128" => { + | "u8" | "u16" | "u32" | "u64" | "u128" | "usize" + | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => { let lo = attr.span.lo() + BytePos(2); let hi = attr.span.hi() - BytePos(1); suggested = true; From 3cc09c8380ed22d4aa9b3b0896b88707b4034b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 15:48:08 -0700 Subject: [PATCH 26/34] Use consistent span for repr attr suggestion --- src/librustc_lint/builtin.rs | 58 +++++++++++-------- src/test/compile-fail/issue-43988.rs | 3 +- ...issue-43106-gating-of-builtin-attrs.stderr | 4 +- src/test/ui/suggestions/repr.stderr | 4 +- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5c05fdb5621a7..d95e0d77d86d3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -687,6 +687,18 @@ impl EarlyLintPass for BadRepr { fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { if attr.name() == "repr" { let list = attr.meta_item_list(); + let outer = match attr.style { + ast::AttrStyle::Outer => true, + ast::AttrStyle::Inner => false, + }; + + let repr_str = move |lit: &str| { + if outer { + format!("#[repr({})]", lit) + } else { + format!("#![repr({})]", lit) + } + }; // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or // no hints (``#[repr]`) @@ -695,33 +707,28 @@ impl EarlyLintPass for BadRepr { let mut suggested = false; let mut warn = if let Some(ref lit) = attr.value_str() { // avoid warning about empty `repr` on `#[repr = "foo"]` - let sp = match format!("{}", lit).as_ref() { + let mut warn = cx.struct_span_lint( + BAD_REPR, + attr.span, + "`repr` attribute isn't configurable with a literal", + ); + match format!("{}", lit).as_ref() { | "C" | "packed" | "rust" | "transparent" | "u8" | "u16" | "u32" | "u64" | "u128" | "usize" | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => { - let lo = attr.span.lo() + BytePos(2); - let hi = attr.span.hi() - BytePos(1); + // if the literal could have been a valid `repr` arg, + // suggest the correct syntax + warn.span_suggestion( + attr.span, + "give `repr` a hint", + repr_str(&lit.as_str()), + ); suggested = true; - attr.span.with_lo(lo).with_hi(hi) } - _ => attr.span, // the literal wasn't a valid `repr` arg + _ => { // the literal wasn't a valid `repr` arg + warn.span_label(attr.span, "needs a hint"); + } }; - let mut warn = cx.struct_span_lint( - BAD_REPR, - sp, - "`repr` attribute isn't configurable with a literal", - ); - if suggested { - // if the literal could have been a valid `repr` arg, - // suggest the correct syntax - warn.span_suggestion( - sp, - "give `repr` a hint", - format!("repr({})", lit), - ); - } else { - warn.span_label(attr.span, "needs a hint"); - } warn } else { let mut warn = cx.struct_span_lint( @@ -733,8 +740,13 @@ impl EarlyLintPass for BadRepr { warn }; if !suggested { - warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]`, \ - `#[repr(rust)]` and `#[repr(transparent)]`"); + warn.help(&format!( + "valid hints include `{}`, `{}`, `{}` and `{}`", + repr_str("C"), + repr_str("packed"), + repr_str("rust"), + repr_str("transparent"), + )); warn.note("for more information, visit \ "); } diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs index 0dfa9f6f0d341..6361af7648258 100644 --- a/src/test/compile-fail/issue-43988.rs +++ b/src/test/compile-fail/issue-43988.rs @@ -34,6 +34,7 @@ fn main() { #[repr] let _y = "123"; //~^^ ERROR attribute should not be applied to a statement + //~| WARN `repr` attribute must have a hint fn foo() {} @@ -44,5 +45,5 @@ fn main() { let _z = #[repr] 1; //~^ ERROR attribute should not be applied to an expression - + //~| WARN `repr` attribute must have a hint } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index f351a9e69d011..3569eecd883f6 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -193,7 +193,7 @@ LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ needs a hint | = note: #[warn(bad_repr)] on by default - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` + = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -238,7 +238,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #![repr = "3900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` + = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]` = note: for more information, visit warning: unused attribute diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr index 83f5bb48f7a08..7a99d8c04488f 100644 --- a/src/test/ui/suggestions/repr.stderr +++ b/src/test/ui/suggestions/repr.stderr @@ -18,8 +18,8 @@ LL | #[repr = "B"] = note: for more information, visit warning: `repr` attribute isn't configurable with a literal - --> $DIR/repr.rs:21:3 + --> $DIR/repr.rs:21:1 | LL | #[repr = "C"] - | ^^^^^^^^^^ help: give `repr` a hint: `repr(C)` + | ^^^^^^^^^^^^^ help: give `repr` a hint: `#[repr(C)]` From 0e3f19d3f179c179ccde3a2f15e9e429483f6903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Jun 2018 17:39:58 -0700 Subject: [PATCH 27/34] Do not account for inner/outer attr --- src/librustc_lint/builtin.rs | 12 +----------- .../issue-43106-gating-of-builtin-attrs.stderr | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d95e0d77d86d3..b3b737ab28329 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -687,18 +687,8 @@ impl EarlyLintPass for BadRepr { fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { if attr.name() == "repr" { let list = attr.meta_item_list(); - let outer = match attr.style { - ast::AttrStyle::Outer => true, - ast::AttrStyle::Inner => false, - }; - let repr_str = move |lit: &str| { - if outer { - format!("#[repr({})]", lit) - } else { - format!("#![repr({})]", lit) - } - }; + let repr_str = |lit: &str| { format!("#[repr({})]", lit) }; // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or // no hints (``#[repr]`) diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 3569eecd883f6..f351a9e69d011 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -193,7 +193,7 @@ LL | mod inner { #![repr="3900"] } | ^^^^^^^^^^^^^^^ needs a hint | = note: #[warn(bad_repr)] on by default - = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: `repr` attribute isn't configurable with a literal @@ -238,7 +238,7 @@ warning: `repr` attribute isn't configurable with a literal LL | #![repr = "3900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint | - = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]` + = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]` = note: for more information, visit warning: unused attribute From eccd2ede3c1b11ddcdde7929e049c4773df690ae Mon Sep 17 00:00:00 2001 From: Havvy Date: Wed, 6 Jun 2018 22:11:37 -0700 Subject: [PATCH 28/34] Use Ord::cmp for auto traits since stable sort not needed --- src/librustc_typeck/astconv.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 68553ece3a750..da98dc5d14b46 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -30,7 +30,7 @@ use util::common::ErrorReported; use util::nodemap::{FxHashSet, FxHashMap}; use errors::FatalError; -use std::cmp::Ordering; +// use std::cmp::Ordering; use std::iter; use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; @@ -646,7 +646,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { &mut vec![]); } - let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]); + let (mut auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]); if !trait_bounds.is_empty() { let b = &trait_bounds[0]; @@ -708,15 +708,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`. - let mut auto_traits = - auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait).collect::>(); - auto_traits.sort_by(|a, b| a.cmp(tcx, b)); - auto_traits.dedup_by(|a, b| (&*a).cmp(tcx, b) == Ordering::Equal); + auto_traits.sort(); + auto_traits.dedup(); // skip_binder is okay, because the predicates are re-bound. let mut v = iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder())) - .chain(auto_traits.into_iter()) + .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait)) .chain(existential_projections .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder()))) .collect::>(); From 31bb50b6b949aa19fc6d5ed76a4d458e8a5af8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Jun 2018 09:47:09 -0700 Subject: [PATCH 29/34] Use `from_inner_byte_pos` for cleaner code --- src/librustdoc/clean/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 226b3627e3e08..e24c1a23b89b0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1218,9 +1218,10 @@ fn resolution_failure( }; // Extract the specific span - let lo = sp.lo() + syntax_pos::BytePos((link_range.start + code_dox_len) as u32); - let hi = lo + syntax_pos::BytePos(link_range.len() as u32); - let sp = sp.with_lo(lo).with_hi(hi); + let sp = sp.from_inner_byte_pos( + link_range.start + code_dox_len, + link_range.end + code_dox_len, + ); diag = cx.sess().struct_span_warn(sp, &msg); diag.span_label(sp, "cannot be resolved, ignoring"); From b0440d359b0dab992e8f01d63523799a72c81285 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Apr 2018 15:13:20 +1000 Subject: [PATCH 30/34] Avoid useless Vec clones in pending_obligations(). The only instance of `ObligationForest` in use has an obligation type of `PendingPredicateObligation`, which contains a `PredicateObligation` and a `Vec`. `FulfillmentContext::pending_obligations()` calls `ObligationForest::pending_obligations()`, which clones all the `PendingPredicateObligation`s. But the `Vec` field of those cloned obligations is never touched. This patch changes `ObligationForest::pending_obligations()` to `map_pending_obligations` -- which gives callers control about which part of the obligation to clone -- and takes advantage of the change to avoid cloning the `Vec`. The change speeds up runs of a few rustc-perf benchmarks, the best by 1%. --- src/librustc/traits/engine.rs | 4 ++-- src/librustc/traits/fulfill.rs | 4 ++-- src/librustc_data_structures/obligation_forest/mod.rs | 6 +++--- src/librustc_typeck/check/closure.rs | 2 -- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index 8eee6f35ab956..40d54885619fa 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -13,7 +13,7 @@ use ty::{self, Ty, TyCtxt}; use hir::def_id::DefId; use super::{FulfillmentContext, FulfillmentError}; -use super::{ObligationCause, PendingPredicateObligation, PredicateObligation}; +use super::{ObligationCause, PredicateObligation}; pub trait TraitEngine<'tcx>: 'tcx { fn normalize_projection_type<'a, 'gcx>( @@ -49,7 +49,7 @@ pub trait TraitEngine<'tcx>: 'tcx { infcx: &InferCtxt<'a, 'gcx, 'tcx>, ) -> Result<(), Vec>>; - fn pending_obligations(&self) -> Vec>; + fn pending_obligations(&self) -> Vec>; } impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 4447a2b6ed140..7c31d8cc06052 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -241,8 +241,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { self.select(&mut selcx) } - fn pending_obligations(&self) -> Vec> { - self.predicates.pending_obligations() + fn pending_obligations(&self) -> Vec> { + self.predicates.map_pending_obligations(|o| o.obligation.clone()) } } diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 612f44f09cf65..c3934c4e1b850 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -229,13 +229,13 @@ impl ObligationForest { } /// Returns the set of obligations that are in a pending state. - pub fn pending_obligations(&self) -> Vec - where O: Clone + pub fn map_pending_obligations(&self, f: F) -> Vec

+ where F: Fn(&O) -> P { self.nodes .iter() .filter(|n| n.state.get() == NodeState::Pending) - .map(|n| n.obligation.clone()) + .map(|n| f(&n.obligation)) .collect() } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 67245bec7fb89..439c1b3422794 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -225,7 +225,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_sig = fulfillment_cx .pending_obligations() .iter() - .map(|obligation| &obligation.obligation) .filter_map(|obligation| { debug!( "deduce_expectations_from_obligations: obligation.predicate={:?}", @@ -257,7 +256,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_kind = fulfillment_cx .pending_obligations() .iter() - .map(|obligation| &obligation.obligation) .filter_map(|obligation| { let opt_trait_ref = match obligation.predicate { ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)), From ec08622192c5c7b2378014e951a0df4dfb210b04 Mon Sep 17 00:00:00 2001 From: Kyle Simpson Date: Thu, 7 Jun 2018 16:13:25 +0100 Subject: [PATCH 31/34] compiletest: autoremove duplicate .nll.* files (#51204) UI tests in bless mode should now check to see if `.nll.*` files have a matching `.*` file. If a match is found, it will be deleted. This should be extensible to other modes (i.e., Polonius). On running with `--bless`, the two files removed in #51186 are, in turn, removed automatically. --- src/tools/compiletest/src/runtest.rs | 59 ++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index cc00f200171d8..caf73f4f68b03 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -9,7 +9,7 @@ // except according to those terms. use common::CompareMode; -use common::{expected_output_path, UI_FIXED, UI_STDERR, UI_STDOUT}; +use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; use common::{output_base_dir, output_base_name, output_testname_unique}; use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc}; use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; @@ -2609,6 +2609,9 @@ impl<'test> TestCx<'test> { errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout); errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr); + let modes_to_prune = vec![CompareMode::Nll]; + self.prune_duplicate_outputs(&modes_to_prune); + if self.config.compare_mode.is_some() { // don't test rustfix with nll right now } else if self.props.run_rustfix { @@ -2971,6 +2974,16 @@ impl<'test> TestCx<'test> { } } + fn delete_file(&self, file: &PathBuf) { + if let Err(e) = ::std::fs::remove_file(file) { + self.fatal(&format!( + "failed to delete `{}`: {}", + file.display(), + e, + )); + } + } + fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize { if actual == expected { return 0; @@ -3023,13 +3036,7 @@ impl<'test> TestCx<'test> { for output_file in &files { if actual.is_empty() { - if let Err(e) = ::std::fs::remove_file(output_file) { - self.fatal(&format!( - "failed to delete `{}`: {}", - output_file.display(), - e, - )); - } + self.delete_file(output_file); } else { match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) { Ok(()) => {} @@ -3054,6 +3061,42 @@ impl<'test> TestCx<'test> { } } + fn prune_duplicate_output(&self, mode: CompareMode, kind: &str, canon_content: &str) { + let examined_path = expected_output_path( + &self.testpaths, + self.revision, + &Some(mode), + kind, + ); + + let examined_content = self + .load_expected_output_from_path(&examined_path) + .unwrap_or_else(|_| String::new()); + + if examined_path.exists() && canon_content == &examined_content { + self.delete_file(&examined_path); + } + } + + fn prune_duplicate_outputs(&self, modes: &[CompareMode]) { + if self.config.bless { + for kind in UI_EXTENSIONS { + let canon_comparison_path = expected_output_path( + &self.testpaths, + self.revision, + &None, + kind, + ); + + if let Ok(canon) = self.load_expected_output_from_path(&canon_comparison_path) { + for mode in modes { + self.prune_duplicate_output(mode.clone(), kind, &canon); + } + } + } + } + } + fn create_stamp(&self) { let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap(); f.write_all(compute_stamp_hash(&self.config).as_bytes()) From 721f2e789ae821e85f30ac6bfad8da31b6f1c692 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 8 Jun 2018 08:29:15 -0600 Subject: [PATCH 32/34] Do not require stage 2 compiler for rustdoc --- src/bootstrap/builder.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9300b94156acb..be9c926bedf22 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -800,10 +800,7 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_ERROR_FORMAT", error_format); } if cmd != "build" && cmd != "check" && want_rustdoc { - cargo.env( - "RUSTDOC_LIBDIR", - self.rustc_libdir(self.compiler(2, self.config.build)), - ); + cargo.env("RUSTDOC_LIBDIR", self.sysroot_libdir(compiler, self.config.build)); } if mode.is_tool() { From c28145d1adbb32340897a102c43f0a8d2cb58ee2 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 8 Jun 2018 16:47:16 +0200 Subject: [PATCH 33/34] rustbuild: generate full list of dependencies for metadata Previously, we didn't send --features to our cargo metadata invocations, and thus missed some dependencies that we enable through the --features mechanism. --- src/bootstrap/lib.rs | 3 ++- src/bootstrap/metadata.rs | 54 ++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d16d7a520659b..6e77413f06188 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -280,7 +280,8 @@ pub struct Build { struct Crate { name: Interned, version: String, - deps: Vec>, + deps: HashSet>, + id: String, path: PathBuf, doc_step: String, build_step: String, diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 5f1df1d26e273..718a6da363724 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -11,6 +11,7 @@ use std::collections::HashMap; use std::process::Command; use std::path::PathBuf; +use std::collections::HashSet; use build_helper::output; use serde_json; @@ -45,12 +46,34 @@ struct ResolveNode { } pub fn build(build: &mut Build) { - build_krate(build, "src/libstd"); - build_krate(build, "src/libtest"); - build_krate(build, "src/rustc"); + let mut resolves = Vec::new(); + build_krate(&build.std_features(), build, &mut resolves, "src/libstd"); + build_krate("", build, &mut resolves, "src/libtest"); + build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc"); + + let mut id2name = HashMap::new(); + for (name, krate) in build.crates.iter() { + id2name.insert(krate.id.clone(), name.clone()); + } + + for node in resolves { + let name = match id2name.get(&node.id) { + Some(name) => name, + None => continue, + }; + + let krate = build.crates.get_mut(name).unwrap(); + for dep in node.dependencies.iter() { + let dep = match id2name.get(dep) { + Some(dep) => dep, + None => continue, + }; + krate.deps.insert(*dep); + } + } } -fn build_krate(build: &mut Build, krate: &str) { +fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec, krate: &str) { // Run `cargo metadata` to figure out what crates we're testing. // // Down below we're going to call `cargo test`, but to test the right set @@ -60,14 +83,13 @@ fn build_krate(build: &mut Build, krate: &str) { let mut cargo = Command::new(&build.initial_cargo); cargo.arg("metadata") .arg("--format-version").arg("1") + .arg("--features").arg(features) .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml")); let output = output(&mut cargo); let output: Output = serde_json::from_str(&output).unwrap(); - let mut id2name = HashMap::new(); for package in output.packages { if package.source.is_none() { let name = INTERNER.intern_string(package.name); - id2name.insert(package.id, name); let mut path = PathBuf::from(package.manifest_path); path.pop(); build.crates.insert(name, Crate { @@ -77,25 +99,11 @@ fn build_krate(build: &mut Build, krate: &str) { bench_step: format!("bench-crate-{}", name), name, version: package.version, - deps: Vec::new(), + id: package.id, + deps: HashSet::new(), path, }); } } - - for node in output.resolve.nodes { - let name = match id2name.get(&node.id) { - Some(name) => name, - None => continue, - }; - - let krate = build.crates.get_mut(name).unwrap(); - for dep in node.dependencies.iter() { - let dep = match id2name.get(dep) { - Some(dep) => dep, - None => continue, - }; - krate.deps.push(*dep); - } - } + resolves.extend(output.resolve.nodes); } From df0c6a97b4a7897931c6e4b21b9f4398272d552e Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 8 Jun 2018 17:25:53 -0400 Subject: [PATCH 34/34] Built, corrected, and run tests. Added expected stderr files. --- src/test/compile-fail/issue-39616.rs | 2 +- src/test/ui/tuple-struct-fields/test.stderr | 20 ++++++++++++++++++++ src/test/ui/tuple-struct-fields/test2.stderr | 11 +++++++++++ src/test/ui/tuple-struct-fields/test3.stderr | 11 +++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/tuple-struct-fields/test.stderr create mode 100644 src/test/ui/tuple-struct-fields/test2.stderr create mode 100644 src/test/ui/tuple-struct-fields/test3.stderr diff --git a/src/test/compile-fail/issue-39616.rs b/src/test/compile-fail/issue-39616.rs index e5d0cbe34f32e..13b4c0896e75c 100644 --- a/src/test/compile-fail/issue-39616.rs +++ b/src/test/compile-fail/issue-39616.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo(a: [0; 1]) {} //~ ERROR expected type, found `0` -//~| ERROR expected one of `)`, `->`, `where`, or `{`, found `]` +//~| ERROR expected one of `)`, `,`, `->`, `where`, or `{`, found `]` // FIXME(jseyfried): avoid emitting the second error (preexisting) fn main() {} diff --git a/src/test/ui/tuple-struct-fields/test.stderr b/src/test/ui/tuple-struct-fields/test.stderr new file mode 100644 index 0000000000000..59228ea8c14d2 --- /dev/null +++ b/src/test/ui/tuple-struct-fields/test.stderr @@ -0,0 +1,20 @@ +error: expected one of `)` or `,`, found `(` + --> $DIR/test.rs:14:26 + | +LL | struct S2(pub((foo)) ()); + | ^ expected one of `)` or `,` here + +error[E0412]: cannot find type `foo` in this scope + --> $DIR/test.rs:14:20 + | +LL | struct S2(pub((foo)) ()); + | ^^^ not found in this scope + +error[E0601]: `main` function not found in crate `test` + | + = note: consider adding a `main` function to `$DIR/test.rs` + +error: aborting due to 3 previous errors + +Some errors occurred: E0412, E0601. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/tuple-struct-fields/test2.stderr b/src/test/ui/tuple-struct-fields/test2.stderr new file mode 100644 index 0000000000000..983e74772ac69 --- /dev/null +++ b/src/test/ui/tuple-struct-fields/test2.stderr @@ -0,0 +1,11 @@ +error: expected one of `)` or `,`, found `(` + --> $DIR/test2.rs:15:26 + | +LL | struct S3(pub $t ()); + | ^ expected one of `)` or `,` here +... +LL | define_struct! { (foo) } + | ------------------------ in this macro invocation + +error: aborting due to previous error + diff --git a/src/test/ui/tuple-struct-fields/test3.stderr b/src/test/ui/tuple-struct-fields/test3.stderr new file mode 100644 index 0000000000000..6738595b99798 --- /dev/null +++ b/src/test/ui/tuple-struct-fields/test3.stderr @@ -0,0 +1,11 @@ +error: expected one of `)` or `,`, found `(` + --> $DIR/test3.rs:15:27 + | +LL | struct S3(pub($t) ()); + | ^ expected one of `)` or `,` here +... +LL | define_struct! { foo } + | ---------------------- in this macro invocation + +error: aborting due to previous error +