From 256096da9ee680366b839f912e8d3ecccc0da033 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 25 Apr 2018 16:33:02 -0500 Subject: Make Vec::new const --- src/test/run-pass/vec-const-new.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/run-pass/vec-const-new.rs (limited to 'src/test') diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/vec-const-new.rs new file mode 100644 index 00000000000..02d8cfdcf98 --- /dev/null +++ b/src/test/run-pass/vec-const-new.rs @@ -0,0 +1,15 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that Vec::new() can be used for constants + +const MY_VEC: Vec = Vec::new(); + +pub fn main() {} -- cgit 1.4.1-3-g733a5 From 0212e0230a500c3b50a6830a20c12d1db3520b99 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Apr 2018 20:59:25 -0500 Subject: feature on test --- src/test/run-pass/vec-const-new.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/test') diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/vec-const-new.rs index 02d8cfdcf98..62e2a36d7cc 100644 --- a/src/test/run-pass/vec-const-new.rs +++ b/src/test/run-pass/vec-const-new.rs @@ -10,6 +10,8 @@ // Test that Vec::new() can be used for constants +#![feature(const_vec_new)] + const MY_VEC: Vec = Vec::new(); pub fn main() {} -- cgit 1.4.1-3-g733a5 From 0a6e91bdbc6368a15bd5ccc632954b8247284b6d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 30 Apr 2018 01:13:54 +0300 Subject: Add a few more tests for proc macro feature gating --- .../proc-macro/proc-macro-gates.rs | 55 +++++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'src/test') diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs index 0dc1c2ab2da..fff433b90ce 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs @@ -24,9 +24,17 @@ use foo::*; #[foo::a] //~ ERROR: paths of length greater than one fn _test() {} +fn _test_inner() { + #![a] // OK +} + #[a] //~ ERROR: custom attributes cannot be applied to modules mod _test2 {} +mod _test2_inner { + #![a] //~ ERROR: custom attributes cannot be applied to modules +} + #[a = y] //~ ERROR: must only be followed by a delimiter token fn _test3() {} @@ -36,19 +44,40 @@ fn _test4() {} #[a () = ] //~ ERROR: must only be followed by a delimiter token fn _test5() {} -fn main() { +fn attrs() { + // Statement, item + #[a] // OK + struct S; + + // Statement, macro + #[a] //~ ERROR: custom attributes cannot be applied to statements + println!(); + + // Statement, semi + #[a] //~ ERROR: custom attributes cannot be applied to statements + S; + + // Statement, local #[a] //~ ERROR: custom attributes cannot be applied to statements let _x = 2; - let _x = #[a] 2; - //~^ ERROR: custom attributes cannot be applied to expressions - - let _x: m!(u32) = 3; - //~^ ERROR: procedural macros cannot be expanded to types - if let m!(Some(_x)) = Some(3) { - //~^ ERROR: procedural macros cannot be expanded to patterns - } - let _x = m!(3); - //~^ ERROR: procedural macros cannot be expanded to expressions - m!(let _x = 3;); - //~^ ERROR: procedural macros cannot be expanded to statements + + // Expr + let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions + + // Opt expr + let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions + + // Expr macro + let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions +} + +fn main() { + let _x: m!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types + if let m!(Some(_x)) = Some(3) {} //~ ERROR: procedural macros cannot be expanded to patterns + + m!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements + m!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements + + let _x = m!(3); //~ ERROR: procedural macros cannot be expanded to expressions + let _x = [m!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions } -- cgit 1.4.1-3-g733a5 From cc53db8bf9f7583b14ae3a309fb65c3cb676bd66 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 30 Apr 2018 00:40:11 +0100 Subject: Correct unused field warning on &struct match --- src/librustc/middle/liveness.rs | 28 +++++++++++++++------- ...ssue-47390-unused-variable-in-struct-pattern.rs | 12 ++++++++++ ...-47390-unused-variable-in-struct-pattern.stderr | 14 +++++++---- 3 files changed, 41 insertions(+), 13 deletions(-) (limited to 'src/test') diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 17c114bc3b3..bf7fecb884e 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -412,18 +412,28 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) { } fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { - for pat in &arm.pats { - // for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`) + for mut pat in &arm.pats { + // For struct patterns, take note of which fields used shorthand + // (`x` rather than `x: x`). // - // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased - // out in favor of `HirId`s; however, we need to match the signature of `each_binding`, - // which uses `NodeIds`. + // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be + // phased out in favor of `HirId`s; however, we need to match the signature of + // `each_binding`, which uses `NodeIds`. let mut shorthand_field_ids = NodeSet(); - if let hir::PatKind::Struct(_, ref fields, _) = pat.node { - for field in fields { - if field.node.is_shorthand { - shorthand_field_ids.insert(field.node.pat.id); + loop { + match pat.node { + hir::PatKind::Struct(_, ref fields, _) => { + for field in fields { + if field.node.is_shorthand { + shorthand_field_ids.insert(field.node.pat.id); + } + } + break; + } + hir::PatKind::Ref(ref deref_pat, _) => { + pat = deref_pat; } + _ => break } } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 18b83370355..498e7e5e6c4 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -18,6 +18,10 @@ struct SoulHistory { endless_and_singing: bool } +enum Large { + Suit { case: () } +} + fn main() { let i_think_continually = 2; let who_from_the_womb_remembered = SoulHistory { @@ -31,4 +35,12 @@ fn main() { endless_and_singing: true } = who_from_the_womb_remembered { hours_are_suns = false; } + + let bag = &Large::Suit { + case: () + }; + + match bag { + &Large::Suit { case } => {} + }; } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index 35fe5479406..cecda22280c 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -1,5 +1,5 @@ warning: unused variable: `i_think_continually` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 | LL | let i_think_continually = 2; | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead @@ -12,13 +12,13 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) = note: #[warn(unused_variables)] implied by #[warn(unused)] warning: unused variable: `corridors_of_light` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:26 | LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:34:26 | LL | mut hours_are_suns, | ^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | mut hours_are_suns, = note: consider using `_hours_are_suns` instead warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:9 | LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ @@ -38,3 +38,9 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ = note: #[warn(unused_assignments)] implied by #[warn(unused)] +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:44:24 + | +LL | &Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + -- cgit 1.4.1-3-g733a5 From 8e8fe9042c86c53d90ce17cc0754505bf014d0ed Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 30 Apr 2018 00:51:02 +0100 Subject: Correct unused field warning on box struct match --- src/librustc/middle/liveness.rs | 5 +++-- .../issue-47390-unused-variable-in-struct-pattern.rs | 10 ++++++++-- ...ue-47390-unused-variable-in-struct-pattern.stderr | 20 +++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src/test') diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index bf7fecb884e..b32ee2f29d2 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -430,8 +430,9 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { } break; } - hir::PatKind::Ref(ref deref_pat, _) => { - pat = deref_pat; + hir::PatKind::Ref(ref inner_pat, _) | + hir::PatKind::Box(ref inner_pat) => { + pat = inner_pat; } _ => break } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 498e7e5e6c4..db3c812f259 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -10,6 +10,8 @@ // compile-pass +#![feature(box_syntax)] +#![feature(box_patterns)] #![warn(unused)] // UI tests pass `-A unused` (#43896) struct SoulHistory { @@ -36,11 +38,15 @@ fn main() { hours_are_suns = false; } - let bag = &Large::Suit { + let bag = Large::Suit { case: () }; - match bag { + match &bag { &Large::Suit { case } => {} }; + + match box bag { + box Large::Suit { case } => {} + }; } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index cecda22280c..ce064f9c93f 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -1,24 +1,24 @@ warning: unused variable: `i_think_continually` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:28:9 | LL | let i_think_continually = 2; | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead | note: lint level defined here - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ = note: #[warn(unused_variables)] implied by #[warn(unused)] warning: unused variable: `corridors_of_light` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:26 | LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:34:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:26 | LL | mut hours_are_suns, | ^^^^^^^^^^^^^^^^^^ @@ -26,21 +26,27 @@ LL | mut hours_are_suns, = note: consider using `_hours_are_suns` instead warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9 | LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ = note: #[warn(unused_assignments)] implied by #[warn(unused)] warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:44:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:24 | LL | &Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:27 + | +LL | box Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + -- cgit 1.4.1-3-g733a5 From 2eb8343af18470d3c48a50c68dbaeb1887b42c37 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 30 Apr 2018 01:27:37 +0100 Subject: Correct unused field warning on struct match container patterns --- src/librustc/middle/liveness.rs | 29 ++++++++++++----- ...ssue-47390-unused-variable-in-struct-pattern.rs | 25 +++++++++++++++ ...-47390-unused-variable-in-struct-pattern.stderr | 36 ++++++++++++++++++---- 3 files changed, 77 insertions(+), 13 deletions(-) (limited to 'src/test') diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index b32ee2f29d2..d1a46f5f155 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -111,6 +111,7 @@ use ty::{self, TyCtxt}; use lint; use util::nodemap::{NodeMap, NodeSet}; +use std::collections::VecDeque; use std::{fmt, usize}; use std::io::prelude::*; use std::io; @@ -420,21 +421,35 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { // phased out in favor of `HirId`s; however, we need to match the signature of // `each_binding`, which uses `NodeIds`. let mut shorthand_field_ids = NodeSet(); - loop { + let mut pats = VecDeque::new(); + pats.push_back(pat); + while let Some(pat) = pats.pop_front() { + use hir::PatKind::*; match pat.node { - hir::PatKind::Struct(_, ref fields, _) => { + Binding(_, _, _, ref inner_pat) => { + pats.extend(inner_pat.iter()); + } + Struct(_, ref fields, _) => { for field in fields { if field.node.is_shorthand { shorthand_field_ids.insert(field.node.pat.id); } } - break; } - hir::PatKind::Ref(ref inner_pat, _) | - hir::PatKind::Box(ref inner_pat) => { - pat = inner_pat; + Ref(ref inner_pat, _) | + Box(ref inner_pat) => { + pats.push_back(inner_pat); + } + TupleStruct(_, ref inner_pats, _) | + Tuple(ref inner_pats, _) => { + pats.extend(inner_pats.iter()); + } + Slice(ref pre_pats, ref inner_pat, ref post_pats) => { + pats.extend(pre_pats.iter()); + pats.extend(inner_pat.iter()); + pats.extend(post_pats.iter()); } - _ => break + _ => {} } } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index db3c812f259..6994a377a06 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -20,10 +20,13 @@ struct SoulHistory { endless_and_singing: bool } +#[derive(Clone, Copy)] enum Large { Suit { case: () } } +struct Tuple(Large, ()); + fn main() { let i_think_continually = 2; let who_from_the_womb_remembered = SoulHistory { @@ -42,11 +45,33 @@ fn main() { case: () }; + // Plain struct + match bag { + Large::Suit { case } => {} + }; + + // Referenced struct match &bag { &Large::Suit { case } => {} }; + // Boxed struct match box bag { box Large::Suit { case } => {} }; + + // Tuple with struct + match (bag,) { + (Large::Suit { case },) => {} + }; + + // Slice with struct + match [bag] { + [Large::Suit { case }] => {} + }; + + // Tuple struct with struct + match Tuple(bag, ()) { + Tuple(Large::Suit { case }, ()) => {} + }; } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index ce064f9c93f..7bfe2c9162e 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -1,5 +1,5 @@ warning: unused variable: `i_think_continually` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:28:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9 | LL | let i_think_continually = 2; | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead @@ -12,13 +12,13 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) = note: #[warn(unused_variables)] implied by #[warn(unused)] warning: unused variable: `corridors_of_light` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:26 | LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:39:26 | LL | mut hours_are_suns, | ^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | mut hours_are_suns, = note: consider using `_hours_are_suns` instead warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:9 | LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ @@ -39,14 +39,38 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) = note: #[warn(unused_assignments)] implied by #[warn(unused)] warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:23 + | +LL | Large::Suit { case } => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:55:24 | LL | &Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:27 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:60:27 | LL | box Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:65:24 + | +LL | (Large::Suit { case },) => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:70:24 + | +LL | [Large::Suit { case }] => {} + | ^^^^ help: try ignoring the field: `case: _` + +warning: unused variable: `case` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:75:29 + | +LL | Tuple(Large::Suit { case }, ()) => {} + | ^^^^ help: try ignoring the field: `case: _` + -- cgit 1.4.1-3-g733a5 From bd4ebf28bdf6eb898971b194f5cf773c88281251 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 30 Apr 2018 07:43:22 +0200 Subject: check that #[used] is used only on statics --- src/librustc/hir/check_attr.rs | 12 ++++++++++++ src/test/compile-fail/used.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/test/compile-fail/used.rs (limited to 'src/test') diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 19f8d15662d..cad6ff8ae9f 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -31,6 +31,7 @@ enum Target { Expression, Statement, Closure, + Static, Other, } @@ -43,6 +44,7 @@ impl Target { hir::ItemEnum(..) => Target::Enum, hir::ItemConst(..) => Target::Const, hir::ItemForeignMod(..) => Target::ForeignMod, + hir::ItemStatic(..) => Target::Static, _ => Target::Other, } } @@ -102,6 +104,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } self.check_repr(item, target); + self.check_used(item, target); } /// Check if an `#[inline]` is applied to a function or a closure. @@ -305,6 +308,15 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } } + + fn check_used(&self, item: &hir::Item, target: Target) { + for attr in &item.attrs { + if attr.name().map(|name| name == "used").unwrap_or(false) && target != Target::Static { + self.tcx.sess + .span_err(attr.span, "attribute must be applied to a `static` variable"); + } + } + } } impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> { diff --git a/src/test/compile-fail/used.rs b/src/test/compile-fail/used.rs new file mode 100644 index 00000000000..f170d9c25f5 --- /dev/null +++ b/src/test/compile-fail/used.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. + +#![feature(used)] + +#[used] +static FOO: u32 = 0; // OK + +#[used] //~ ERROR attribute must be applied to a `static` variable +fn foo() {} + +#[used] //~ ERROR attribute must be applied to a `static` variable +struct Foo {} + +#[used] //~ ERROR attribute must be applied to a `static` variable +trait Bar {} + +#[used] //~ ERROR attribute must be applied to a `static` variable +impl Bar for Foo {} + +fn main() {} -- cgit 1.4.1-3-g733a5