mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 10:18:25 +00:00
Support lints in early attribute parsing
This commit is contained in:
parent
3bf6144461
commit
4b35cde904
@ -3791,7 +3791,6 @@ dependencies = [
|
||||
"rustc_error_messages",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_hashes",
|
||||
"rustc_hir_id",
|
||||
"rustc_index",
|
||||
"rustc_lexer",
|
||||
"rustc_lint_defs",
|
||||
|
@ -50,6 +50,27 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
target_span: Span,
|
||||
target_node_id: NodeId,
|
||||
features: Option<&'sess Features>,
|
||||
) -> Option<Attribute> {
|
||||
Self::parse_limited_should_emit(
|
||||
sess,
|
||||
attrs,
|
||||
sym,
|
||||
target_span,
|
||||
target_node_id,
|
||||
features,
|
||||
ShouldEmit::Nothing,
|
||||
)
|
||||
}
|
||||
|
||||
/// Usually you want `parse_limited`, which defaults to no errors.
|
||||
pub fn parse_limited_should_emit(
|
||||
sess: &'sess Session,
|
||||
attrs: &[ast::Attribute],
|
||||
sym: Symbol,
|
||||
target_span: Span,
|
||||
target_node_id: NodeId,
|
||||
features: Option<&'sess Features>,
|
||||
should_emit: ShouldEmit,
|
||||
) -> Option<Attribute> {
|
||||
let mut parsed = Self::parse_limited_all(
|
||||
sess,
|
||||
@ -59,7 +80,7 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
target_span,
|
||||
target_node_id,
|
||||
features,
|
||||
ShouldEmit::Nothing,
|
||||
should_emit,
|
||||
);
|
||||
assert!(parsed.len() <= 1);
|
||||
parsed.pop()
|
||||
@ -84,9 +105,8 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
target,
|
||||
OmitDoc::Skip,
|
||||
std::convert::identity,
|
||||
|_lint| {
|
||||
// FIXME: Can't emit lints here for now
|
||||
// This branch can be hit when an attribute produces a warning during early parsing (such as attributes on macro calls)
|
||||
|lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -121,8 +141,8 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
cx: &mut parser,
|
||||
target_span,
|
||||
target_id: target_node_id,
|
||||
emit_lint: &mut |_lint| {
|
||||
panic!("can't emit lints here for now (nothing uses this atm)");
|
||||
emit_lint: &mut |lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
},
|
||||
},
|
||||
attr_span: attr.span,
|
||||
|
@ -1,13 +1,13 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_errors::{DiagArgValue, LintEmitter};
|
||||
use rustc_hir::Target;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_hir::{HirId, Target};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::session_diagnostics;
|
||||
|
||||
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emitter: L) {
|
||||
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emitter: L) {
|
||||
let AttributeLint { id, span, kind } = lint;
|
||||
|
||||
match kind {
|
||||
@ -51,7 +51,7 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::InvalidTargetLint {
|
||||
name,
|
||||
name: name.clone(),
|
||||
target: target.plural_name(),
|
||||
applied: DiagArgValue::StrListSepByAnd(
|
||||
applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
|
||||
|
@ -484,9 +484,9 @@ pub(crate) struct EmptyAttributeList {
|
||||
#[diag(attr_parsing_invalid_target_lint)]
|
||||
#[warning]
|
||||
#[help]
|
||||
pub(crate) struct InvalidTargetLint<'a> {
|
||||
pub name: &'a AttrPath,
|
||||
pub target: &'a str,
|
||||
pub(crate) struct InvalidTargetLint {
|
||||
pub name: AttrPath,
|
||||
pub target: &'static str,
|
||||
pub applied: DiagArgValue,
|
||||
pub only: &'static str,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
|
@ -14,7 +14,6 @@ rustc_error_codes = { path = "../rustc_error_codes" }
|
||||
rustc_error_messages = { path = "../rustc_error_messages" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_hashes = { path = "../rustc_hashes" }
|
||||
rustc_hir_id = { path = "../rustc_hir_id" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
|
@ -61,7 +61,6 @@ pub use rustc_error_messages::{
|
||||
fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display,
|
||||
};
|
||||
use rustc_hashes::Hash128;
|
||||
use rustc_hir_id::HirId;
|
||||
pub use rustc_lint_defs::{Applicability, listify, pluralize};
|
||||
use rustc_lint_defs::{Lint, LintExpectationId};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
@ -110,13 +109,14 @@ rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
|
||||
/// Used to avoid depending on `rustc_middle` in `rustc_attr_parsing`.
|
||||
/// Always the `TyCtxt`.
|
||||
pub trait LintEmitter: Copy {
|
||||
type Id: Copy;
|
||||
#[track_caller]
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
hir_id: Self::Id,
|
||||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()> + DynSend + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1421,6 +1421,8 @@ pub struct TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> LintEmitter for TyCtxt<'tcx> {
|
||||
type Id = HirId;
|
||||
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
|
@ -7,6 +7,7 @@ use std::sync::atomic::AtomicBool;
|
||||
use std::{env, fmt, io};
|
||||
|
||||
use rand::{RngCore, rng};
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
|
||||
use rustc_data_structures::flock;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
@ -22,7 +23,7 @@ use rustc_errors::timings::TimingSectionHandler;
|
||||
use rustc_errors::translation::Translator;
|
||||
use rustc_errors::{
|
||||
Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort,
|
||||
TerminalUrl, fallback_fluent_bundle,
|
||||
LintEmitter, TerminalUrl, fallback_fluent_bundle,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
pub use rustc_span::def_id::StableCrateId;
|
||||
@ -223,6 +224,20 @@ pub struct Session {
|
||||
pub invocation_temp: Option<String>,
|
||||
}
|
||||
|
||||
impl LintEmitter for &'_ Session {
|
||||
type Id = NodeId;
|
||||
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static rustc_lint_defs::Lint,
|
||||
node_id: Self::Id,
|
||||
span: impl Into<rustc_errors::MultiSpan>,
|
||||
decorator: impl for<'a> rustc_errors::LintDiagnostic<'a, ()> + DynSend + 'static,
|
||||
) {
|
||||
self.psess.buffer_lint(lint, span, node_id, decorator);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum CodegenUnits {
|
||||
/// Specified by the user. In this case we try fairly hard to produce the
|
||||
|
@ -66,6 +66,8 @@ extern "Rust" {
|
||||
}
|
||||
|
||||
//~ ERROR unused attribute
|
||||
//~^ ERROR `#[must_use]` attribute cannot be used on macro calls
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
global_asm!("");
|
||||
|
||||
//~ ERROR attribute cannot be used on
|
||||
|
@ -66,6 +66,8 @@ extern "Rust" {
|
||||
}
|
||||
|
||||
#[must_use] //~ ERROR unused attribute
|
||||
//~^ ERROR `#[must_use]` attribute cannot be used on macro calls
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
global_asm!("");
|
||||
|
||||
#[must_use] //~ ERROR attribute cannot be used on
|
||||
|
@ -1,3 +1,17 @@
|
||||
error: `#[must_use]` attribute cannot be used on macro calls
|
||||
--> $DIR/unused_attributes-must_use.rs:68:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused_attributes-must_use.rs:4:9
|
||||
|
|
||||
LL | #![deny(unused_attributes, unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused attribute `must_use`
|
||||
--> $DIR/unused_attributes-must_use.rs:68:1
|
||||
|
|
||||
@ -5,15 +19,10 @@ LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
|
||||
--> $DIR/unused_attributes-must_use.rs:69:1
|
||||
--> $DIR/unused_attributes-must_use.rs:71:1
|
||||
|
|
||||
LL | global_asm!("");
|
||||
| ^^^^^^^^^^
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused_attributes-must_use.rs:4:9
|
||||
|
|
||||
LL | #![deny(unused_attributes, unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on extern crates
|
||||
--> $DIR/unused_attributes-must_use.rs:7:1
|
||||
@ -88,7 +97,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on type aliases
|
||||
--> $DIR/unused_attributes-must_use.rs:71:1
|
||||
--> $DIR/unused_attributes-must_use.rs:73:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -97,7 +106,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on function params
|
||||
--> $DIR/unused_attributes-must_use.rs:75:8
|
||||
--> $DIR/unused_attributes-must_use.rs:77:8
|
||||
|
|
||||
LL | fn qux<#[must_use] T>(_: T) {}
|
||||
| ^^^^^^^^^^^
|
||||
@ -106,7 +115,7 @@ LL | fn qux<#[must_use] T>(_: T) {}
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on associated consts
|
||||
--> $DIR/unused_attributes-must_use.rs:80:5
|
||||
--> $DIR/unused_attributes-must_use.rs:82:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -115,7 +124,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on associated types
|
||||
--> $DIR/unused_attributes-must_use.rs:83:5
|
||||
--> $DIR/unused_attributes-must_use.rs:85:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -124,7 +133,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on trait impl blocks
|
||||
--> $DIR/unused_attributes-must_use.rs:93:1
|
||||
--> $DIR/unused_attributes-must_use.rs:95:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -133,7 +142,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on trait methods in impl blocks
|
||||
--> $DIR/unused_attributes-must_use.rs:98:5
|
||||
--> $DIR/unused_attributes-must_use.rs:100:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -142,7 +151,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to data types, functions, unions, required trait methods, provided trait methods, inherent methods, foreign functions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on trait aliases
|
||||
--> $DIR/unused_attributes-must_use.rs:105:1
|
||||
--> $DIR/unused_attributes-must_use.rs:107:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -151,7 +160,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on macro defs
|
||||
--> $DIR/unused_attributes-must_use.rs:109:1
|
||||
--> $DIR/unused_attributes-must_use.rs:111:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -160,7 +169,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on statements
|
||||
--> $DIR/unused_attributes-must_use.rs:118:5
|
||||
--> $DIR/unused_attributes-must_use.rs:120:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -169,7 +178,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on closures
|
||||
--> $DIR/unused_attributes-must_use.rs:123:13
|
||||
--> $DIR/unused_attributes-must_use.rs:125:13
|
||||
|
|
||||
LL | let x = #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -178,7 +187,7 @@ LL | let x = #[must_use]
|
||||
= help: `#[must_use]` can be applied to methods, data types, functions, unions, foreign functions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on match arms
|
||||
--> $DIR/unused_attributes-must_use.rs:146:9
|
||||
--> $DIR/unused_attributes-must_use.rs:148:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
@ -187,7 +196,7 @@ LL | #[must_use]
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on struct fields
|
||||
--> $DIR/unused_attributes-must_use.rs:155:28
|
||||
--> $DIR/unused_attributes-must_use.rs:157:28
|
||||
|
|
||||
LL | let s = PatternField { #[must_use] foo: 123 };
|
||||
| ^^^^^^^^^^^
|
||||
@ -196,7 +205,7 @@ LL | let s = PatternField { #[must_use] foo: 123 };
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: `#[must_use]` attribute cannot be used on pattern fields
|
||||
--> $DIR/unused_attributes-must_use.rs:157:24
|
||||
--> $DIR/unused_attributes-must_use.rs:159:24
|
||||
|
|
||||
LL | let PatternField { #[must_use] foo } = s;
|
||||
| ^^^^^^^^^^^
|
||||
@ -205,7 +214,7 @@ LL | let PatternField { #[must_use] foo } = s;
|
||||
= help: `#[must_use]` can be applied to functions, data types, unions, and traits
|
||||
|
||||
error: unused `X` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:128:5
|
||||
--> $DIR/unused_attributes-must_use.rs:130:5
|
||||
|
|
||||
LL | X;
|
||||
| ^
|
||||
@ -221,7 +230,7 @@ LL | let _ = X;
|
||||
| +++++++
|
||||
|
||||
error: unused `Y` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:129:5
|
||||
--> $DIR/unused_attributes-must_use.rs:131:5
|
||||
|
|
||||
LL | Y::Z;
|
||||
| ^^^^
|
||||
@ -232,7 +241,7 @@ LL | let _ = Y::Z;
|
||||
| +++++++
|
||||
|
||||
error: unused `U` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:130:5
|
||||
--> $DIR/unused_attributes-must_use.rs:132:5
|
||||
|
|
||||
LL | U { unit: () };
|
||||
| ^^^^^^^^^^^^^^
|
||||
@ -243,7 +252,7 @@ LL | let _ = U { unit: () };
|
||||
| +++++++
|
||||
|
||||
error: unused return value of `U::method` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:131:5
|
||||
--> $DIR/unused_attributes-must_use.rs:133:5
|
||||
|
|
||||
LL | U::method();
|
||||
| ^^^^^^^^^^^
|
||||
@ -254,7 +263,7 @@ LL | let _ = U::method();
|
||||
| +++++++
|
||||
|
||||
error: unused return value of `foo` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:132:5
|
||||
--> $DIR/unused_attributes-must_use.rs:134:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^
|
||||
@ -265,7 +274,7 @@ LL | let _ = foo();
|
||||
| +++++++
|
||||
|
||||
error: unused return value of `foreign_foo` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:135:9
|
||||
--> $DIR/unused_attributes-must_use.rs:137:9
|
||||
|
|
||||
LL | foreign_foo();
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -276,7 +285,7 @@ LL | let _ = foreign_foo();
|
||||
| +++++++
|
||||
|
||||
error: unused return value of `Use::get_four` that must be used
|
||||
--> $DIR/unused_attributes-must_use.rs:143:5
|
||||
--> $DIR/unused_attributes-must_use.rs:145:5
|
||||
|
|
||||
LL | ().get_four();
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -286,5 +295,5 @@ help: use `let _ = ...` to ignore the resulting value
|
||||
LL | let _ = ().get_four();
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 29 previous errors
|
||||
error: aborting due to 30 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user