Skip to content

Commit

Permalink
Auto merge of #50030 - flip1995:rfc2103, r=petrochenkov
Browse files Browse the repository at this point in the history
Implement tool_attributes feature (RFC 2103)

cc #44690

This is currently just a rebased and compiling (hopefully) version of #47773.

Let's see if travis likes this. I will add the implementation for `tool_lints` this week.
  • Loading branch information
bors committed May 3, 2018
2 parents 698b956 + 84f4508 commit d68b0ec
Show file tree
Hide file tree
Showing 35 changed files with 391 additions and 302 deletions.
26 changes: 26 additions & 0 deletions src/doc/unstable-book/src/language-features/tool-attributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# `tool_attributes`

The tracking issue for this feature is: [#44690]

[#44690]: https://github.com/rust-lang/rust/issues/44690

------------------------

Tool attributes let you use scoped attributes to control the behavior
of certain tools.

Currently tool names which can be appear in scoped attributes are restricted to
`clippy` and `rustfmt`.

## An example

```rust
#![feature(tool_attributes)]

#[rustfmt::skip]
fn foo() { println!("hello, world"); }

fn main() {
foo();
}
```
7 changes: 2 additions & 5 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
// ```
let hints: Vec<_> = item.attrs
.iter()
.filter(|attr| match attr.name() {
Some(name) => name == "repr",
None => false,
})
.filter(|attr| attr.name() == "repr")
.filter_map(|attr| attr.meta_item_list())
.flat_map(|hints| hints)
.collect();
Expand Down Expand Up @@ -311,7 +308,7 @@ 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 {
if attr.name() == "used" && target != Target::Static {
self.tcx.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");
}
Expand Down
21 changes: 14 additions & 7 deletions src/librustc/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
.iter()
.filter(|attr| {
!attr.is_sugared_doc &&
attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
!attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name())
})
.collect();

Expand All @@ -211,12 +210,23 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
}
}

impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.segments.len().hash_stable(hcx, hasher);
for segment in &self.segments {
segment.ident.name.hash_stable(hcx, hasher);
}
}
}

impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
// Make sure that these have been filtered out.
debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
debug_assert!(!hcx.is_ignored_attr(self.name()));
debug_assert!(!self.is_sugared_doc);

let ast::Attribute {
Expand All @@ -229,10 +239,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
} = *self;

style.hash_stable(hcx, hasher);
path.segments.len().hash_stable(hcx, hasher);
for segment in &path.segments {
segment.ident.name.hash_stable(hcx, hasher);
}
path.hash_stable(hcx, hasher);
for tt in tokens.trees() {
tt.hash_stable(hcx, hasher);
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/lint/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl<'a> LintLevelsBuilder<'a> {
"malformed lint attribute");
};
for attr in attrs {
let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
let level = match Level::from_str(&attr.name().as_str()) {
None => continue,
Some(lvl) => lvl,
};
Expand All @@ -221,7 +221,7 @@ impl<'a> LintLevelsBuilder<'a> {
continue
}
};
let name = word.ident.name;
let name = word.name();
match store.check_lint_name(&name.as_str()) {
CheckLintNameResult::Ok(ids) => {
let src = LintSource::Node(name, li.span);
Expand Down Expand Up @@ -260,7 +260,7 @@ impl<'a> LintLevelsBuilder<'a> {
Some(li.span.into()),
&msg);
if name.as_str().chars().any(|c| c.is_uppercase()) {
let name_lower = name.as_str().to_lowercase();
let name_lower = name.as_str().to_lowercase().to_string();
if let CheckLintNameResult::NoLint =
store.check_lint_name(&name_lower) {
db.emit();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
} else {
// Emit errors for non-staged-api crates.
for attr in attrs {
let tag = unwrap_or!(attr.name(), continue);
let tag = attr.name();
if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
attr::mark_used(attr);
self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> ast::CrateConfig {
early_error(ErrorOutputType::default(), &msg)
}

(meta_item.ident.name, meta_item.value_str())
(meta_item.name(), meta_item.value_str())
})
.collect::<ast::CrateConfig>()
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/on_unimplemented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
for command in self.subcommands.iter().chain(Some(self)).rev() {
if let Some(ref condition) = command.condition {
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
options.contains(&(c.ident.name.as_str().to_string(),
options.contains(&(c.name().as_str().to_string(),
match c.value_str().map(|s| s.as_str().to_string()) {
Some(s) => Some(s),
None => None
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ impl RustcDefaultCalls {
let mut cfgs = Vec::new();
for &(name, ref value) in sess.parse_sess.config.iter() {
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
ident: ast::Ident::with_empty_ctxt(name),
ident: ast::Path::from_ident(name.to_ident()),
node: ast::MetaItemKind::Word,
span: DUMMY_SP,
});
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_incremental/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
for list_item in attr.meta_item_list().unwrap_or_default() {
match list_item.word() {
Some(word) if value.is_none() =>
value = Some(word.ident.name),
value = Some(word.name()),
_ =>
// FIXME better-encapsulate meta_item (don't directly access `node`)
span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item.node),
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,9 +675,8 @@ impl LintPass for DeprecatedAttr {

impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
let name = unwrap_or!(attr.name(), return);
for &&(n, _, ref g) in &self.depr_attrs {
if name == n {
if attr.name() == n {
if let &AttributeGate::Gated(Stability::Deprecated(link),
ref name,
ref reason,
Expand Down
1 change: 0 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ impl LintPass for UnusedAttributes {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
debug!("checking attribute: {:?}", attr);
let name = unwrap_or!(attr.name(), return);

// Note that check_name() marks the attribute as used if it matches.
for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
match ty {
Expand All @@ -213,6 +211,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
}
}

let name = attr.name();
if !attr::is_used(attr) {
debug!("Emitting warning for: {:?}", attr);
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ impl<'a> Resolver<'a> {
match attr.meta_item_list() {
Some(names) => for attr in names {
if let Some(word) = attr.word() {
imports.imports.push((word.ident.name, attr.span()));
imports.imports.push((word.name(), attr.span()));
} else {
span_err!(self.session, attr.span(), E0466, "bad macro import");
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<'a> base::Resolver for Resolver<'a> {
fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_derive: bool)
-> Option<ast::Attribute> {
for i in 0..attrs.len() {
let name = unwrap_or!(attrs[i].name(), continue);
let name = attrs[i].name();

if self.session.plugin_attributes.borrow().iter()
.any(|&(ref attr_nm, _)| name == &**attr_nm) {
Expand All @@ -231,7 +231,7 @@ impl<'a> base::Resolver for Resolver<'a> {

// Check for legacy derives
for i in 0..attrs.len() {
let name = unwrap_or!(attrs[i].name(), continue);
let name = attrs[i].name();

if name == "derive" {
let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
Expand Down
Loading

0 comments on commit d68b0ec

Please sign in to comment.