Skip to content

Commit eee84fe

Browse files
committed
move struct_lint_level to levels.rs
1 parent f577b44 commit eee84fe

File tree

2 files changed

+161
-165
lines changed

2 files changed

+161
-165
lines changed

src/librustc/lint/levels.rs

+160-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use std::cmp;
22

33
use crate::ich::StableHashingContext;
4-
use crate::lint;
54
use crate::lint::context::{CheckLintNameResult, LintStore};
65
use rustc_data_structures::fx::FxHashMap;
76
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8-
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
7+
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
98
use rustc_hir::HirId;
109
use rustc_session::lint::{builtin, Level, Lint, LintId};
11-
use rustc_session::Session;
12-
use rustc_span::source_map::MultiSpan;
10+
use rustc_session::{DiagnosticMessageId, Session};
11+
use rustc_span::hygiene::MacroKind;
12+
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
1313
use rustc_span::symbol::{sym, Symbol};
1414
use rustc_span::Span;
1515
use syntax::ast;
@@ -326,7 +326,7 @@ impl<'a> LintLevelsBuilder<'a> {
326326
Also `cfg_attr(cargo-clippy)` won't be necessary anymore",
327327
name
328328
);
329-
lint::struct_lint_level(
329+
struct_lint_level(
330330
self.sess,
331331
lint,
332332
lvl,
@@ -366,7 +366,7 @@ impl<'a> LintLevelsBuilder<'a> {
366366
let lint = builtin::RENAMED_AND_REMOVED_LINTS;
367367
let (level, src) =
368368
self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess);
369-
let mut err = lint::struct_lint_level(
369+
let mut err = struct_lint_level(
370370
self.sess,
371371
lint,
372372
level,
@@ -389,7 +389,7 @@ impl<'a> LintLevelsBuilder<'a> {
389389
let (level, src) =
390390
self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess);
391391
let msg = format!("unknown lint: `{}`", name);
392-
let mut db = lint::struct_lint_level(
392+
let mut db = struct_lint_level(
393393
self.sess,
394394
lint,
395395
level,
@@ -480,7 +480,7 @@ impl<'a> LintLevelsBuilder<'a> {
480480
msg: &str,
481481
) -> DiagnosticBuilder<'a> {
482482
let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess);
483-
lint::struct_lint_level(self.sess, lint, level, src, span, msg)
483+
struct_lint_level(self.sess, lint, level, src, span, msg)
484484
}
485485

486486
/// Registers the ID provided with the current set of lints stored in
@@ -553,3 +553,155 @@ impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
553553
})
554554
}
555555
}
556+
557+
pub fn struct_lint_level<'a>(
558+
sess: &'a Session,
559+
lint: &'static Lint,
560+
level: Level,
561+
src: LintSource,
562+
span: Option<MultiSpan>,
563+
msg: &str,
564+
) -> DiagnosticBuilder<'a> {
565+
let mut err = match (level, span) {
566+
(Level::Allow, _) => return sess.diagnostic().struct_dummy(),
567+
(Level::Warn, Some(span)) => sess.struct_span_warn(span, msg),
568+
(Level::Warn, None) => sess.struct_warn(msg),
569+
(Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => sess.struct_span_err(span, msg),
570+
(Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(msg),
571+
};
572+
573+
// Check for future incompatibility lints and issue a stronger warning.
574+
let lint_id = LintId::of(lint);
575+
let future_incompatible = lint.future_incompatible;
576+
577+
// If this code originates in a foreign macro, aka something that this crate
578+
// did not itself author, then it's likely that there's nothing this crate
579+
// can do about it. We probably want to skip the lint entirely.
580+
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
581+
// Any suggestions made here are likely to be incorrect, so anything we
582+
// emit shouldn't be automatically fixed by rustfix.
583+
err.allow_suggestions(false);
584+
585+
// If this is a future incompatible lint it'll become a hard error, so
586+
// we have to emit *something*. Also allow lints to whitelist themselves
587+
// on a case-by-case basis for emission in a foreign macro.
588+
if future_incompatible.is_none() && !lint.report_in_external_macro {
589+
err.cancel();
590+
// Don't continue further, since we don't want to have
591+
// `diag_span_note_once` called for a diagnostic that isn't emitted.
592+
return err;
593+
}
594+
}
595+
596+
let name = lint.name_lower();
597+
match src {
598+
LintSource::Default => {
599+
sess.diag_note_once(
600+
&mut err,
601+
DiagnosticMessageId::from(lint),
602+
&format!("`#[{}({})]` on by default", level.as_str(), name),
603+
);
604+
}
605+
LintSource::CommandLine(lint_flag_val) => {
606+
let flag = match level {
607+
Level::Warn => "-W",
608+
Level::Deny => "-D",
609+
Level::Forbid => "-F",
610+
Level::Allow => panic!(),
611+
};
612+
let hyphen_case_lint_name = name.replace("_", "-");
613+
if lint_flag_val.as_str() == name {
614+
sess.diag_note_once(
615+
&mut err,
616+
DiagnosticMessageId::from(lint),
617+
&format!(
618+
"requested on the command line with `{} {}`",
619+
flag, hyphen_case_lint_name
620+
),
621+
);
622+
} else {
623+
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
624+
sess.diag_note_once(
625+
&mut err,
626+
DiagnosticMessageId::from(lint),
627+
&format!(
628+
"`{} {}` implied by `{} {}`",
629+
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
630+
),
631+
);
632+
}
633+
}
634+
LintSource::Node(lint_attr_name, src, reason) => {
635+
if let Some(rationale) = reason {
636+
err.note(&rationale.as_str());
637+
}
638+
sess.diag_span_note_once(
639+
&mut err,
640+
DiagnosticMessageId::from(lint),
641+
src,
642+
"lint level defined here",
643+
);
644+
if lint_attr_name.as_str() != name {
645+
let level_str = level.as_str();
646+
sess.diag_note_once(
647+
&mut err,
648+
DiagnosticMessageId::from(lint),
649+
&format!(
650+
"`#[{}({})]` implied by `#[{}({})]`",
651+
level_str, name, level_str, lint_attr_name
652+
),
653+
);
654+
}
655+
}
656+
}
657+
658+
err.code(DiagnosticId::Lint(name));
659+
660+
if let Some(future_incompatible) = future_incompatible {
661+
const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \
662+
it will become a hard error";
663+
664+
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
665+
"once this method is added to the standard library, \
666+
the ambiguity may cause an error or change in behavior!"
667+
.to_owned()
668+
} else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) {
669+
"this borrowing pattern was not meant to be accepted, \
670+
and may become a hard error in the future"
671+
.to_owned()
672+
} else if let Some(edition) = future_incompatible.edition {
673+
format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
674+
} else {
675+
format!("{} in a future release!", STANDARD_MESSAGE)
676+
};
677+
let citation = format!("for more information, see {}", future_incompatible.reference);
678+
err.warn(&explanation);
679+
err.note(&citation);
680+
}
681+
682+
return err;
683+
}
684+
685+
/// Returns whether `span` originates in a foreign crate's external macro.
686+
///
687+
/// This is used to test whether a lint should not even begin to figure out whether it should
688+
/// be reported on the current node.
689+
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
690+
let expn_data = span.ctxt().outer_expn_data();
691+
match expn_data.kind {
692+
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
693+
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
694+
ExpnKind::Macro(MacroKind::Bang, _) => {
695+
if expn_data.def_site.is_dummy() {
696+
// Dummy span for the `def_site` means it's an external macro.
697+
return true;
698+
}
699+
match sess.source_map().span_to_snippet(expn_data.def_site) {
700+
Ok(code) => !code.starts_with("macro_rules"),
701+
// No snippet means external macro or compiler-builtin expansion.
702+
Err(_) => true,
703+
}
704+
}
705+
ExpnKind::Macro(..) => true, // definitely a plugin
706+
}
707+
}

src/librustc/lint/mod.rs

+1-157
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,8 @@ pub use self::Level::*;
2323

2424
use crate::ty::TyCtxt;
2525
use rustc_data_structures::sync;
26-
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
2726
use rustc_hir as hir;
2827
use rustc_session::lint::builtin::HardwiredLints;
29-
use rustc_session::{DiagnosticMessageId, Session};
30-
use rustc_span::hygiene::MacroKind;
31-
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
3228
use rustc_span::Span;
3329
use syntax::ast;
3430

@@ -318,161 +314,9 @@ mod context;
318314
pub mod internal;
319315
mod levels;
320316

321-
pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder};
322-
323-
pub fn struct_lint_level<'a>(
324-
sess: &'a Session,
325-
lint: &'static Lint,
326-
level: Level,
327-
src: LintSource,
328-
span: Option<MultiSpan>,
329-
msg: &str,
330-
) -> DiagnosticBuilder<'a> {
331-
let mut err = match (level, span) {
332-
(Level::Allow, _) => return sess.diagnostic().struct_dummy(),
333-
(Level::Warn, Some(span)) => sess.struct_span_warn(span, msg),
334-
(Level::Warn, None) => sess.struct_warn(msg),
335-
(Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => sess.struct_span_err(span, msg),
336-
(Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(msg),
337-
};
338-
339-
// Check for future incompatibility lints and issue a stronger warning.
340-
let lint_id = LintId::of(lint);
341-
let future_incompatible = lint.future_incompatible;
342-
343-
// If this code originates in a foreign macro, aka something that this crate
344-
// did not itself author, then it's likely that there's nothing this crate
345-
// can do about it. We probably want to skip the lint entirely.
346-
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
347-
// Any suggestions made here are likely to be incorrect, so anything we
348-
// emit shouldn't be automatically fixed by rustfix.
349-
err.allow_suggestions(false);
350-
351-
// If this is a future incompatible lint it'll become a hard error, so
352-
// we have to emit *something*. Also allow lints to whitelist themselves
353-
// on a case-by-case basis for emission in a foreign macro.
354-
if future_incompatible.is_none() && !lint.report_in_external_macro {
355-
err.cancel();
356-
// Don't continue further, since we don't want to have
357-
// `diag_span_note_once` called for a diagnostic that isn't emitted.
358-
return err;
359-
}
360-
}
361-
362-
let name = lint.name_lower();
363-
match src {
364-
LintSource::Default => {
365-
sess.diag_note_once(
366-
&mut err,
367-
DiagnosticMessageId::from(lint),
368-
&format!("`#[{}({})]` on by default", level.as_str(), name),
369-
);
370-
}
371-
LintSource::CommandLine(lint_flag_val) => {
372-
let flag = match level {
373-
Level::Warn => "-W",
374-
Level::Deny => "-D",
375-
Level::Forbid => "-F",
376-
Level::Allow => panic!(),
377-
};
378-
let hyphen_case_lint_name = name.replace("_", "-");
379-
if lint_flag_val.as_str() == name {
380-
sess.diag_note_once(
381-
&mut err,
382-
DiagnosticMessageId::from(lint),
383-
&format!(
384-
"requested on the command line with `{} {}`",
385-
flag, hyphen_case_lint_name
386-
),
387-
);
388-
} else {
389-
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
390-
sess.diag_note_once(
391-
&mut err,
392-
DiagnosticMessageId::from(lint),
393-
&format!(
394-
"`{} {}` implied by `{} {}`",
395-
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
396-
),
397-
);
398-
}
399-
}
400-
LintSource::Node(lint_attr_name, src, reason) => {
401-
if let Some(rationale) = reason {
402-
err.note(&rationale.as_str());
403-
}
404-
sess.diag_span_note_once(
405-
&mut err,
406-
DiagnosticMessageId::from(lint),
407-
src,
408-
"lint level defined here",
409-
);
410-
if lint_attr_name.as_str() != name {
411-
let level_str = level.as_str();
412-
sess.diag_note_once(
413-
&mut err,
414-
DiagnosticMessageId::from(lint),
415-
&format!(
416-
"`#[{}({})]` implied by `#[{}({})]`",
417-
level_str, name, level_str, lint_attr_name
418-
),
419-
);
420-
}
421-
}
422-
}
423-
424-
err.code(DiagnosticId::Lint(name));
425-
426-
if let Some(future_incompatible) = future_incompatible {
427-
const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \
428-
it will become a hard error";
429-
430-
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
431-
"once this method is added to the standard library, \
432-
the ambiguity may cause an error or change in behavior!"
433-
.to_owned()
434-
} else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) {
435-
"this borrowing pattern was not meant to be accepted, \
436-
and may become a hard error in the future"
437-
.to_owned()
438-
} else if let Some(edition) = future_incompatible.edition {
439-
format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
440-
} else {
441-
format!("{} in a future release!", STANDARD_MESSAGE)
442-
};
443-
let citation = format!("for more information, see {}", future_incompatible.reference);
444-
err.warn(&explanation);
445-
err.note(&citation);
446-
}
447-
448-
return err;
449-
}
317+
pub use self::levels::{struct_lint_level, LintLevelMap, LintLevelSets, LintLevelsBuilder};
450318

451319
pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
452320
let attrs = tcx.hir().attrs(id);
453321
attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some())
454322
}
455-
456-
/// Returns whether `span` originates in a foreign crate's external macro.
457-
///
458-
/// This is used to test whether a lint should not even begin to figure out whether it should
459-
/// be reported on the current node.
460-
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
461-
let expn_data = span.ctxt().outer_expn_data();
462-
match expn_data.kind {
463-
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
464-
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
465-
ExpnKind::Macro(MacroKind::Bang, _) => {
466-
if expn_data.def_site.is_dummy() {
467-
// Dummy span for the `def_site` means it's an external macro.
468-
return true;
469-
}
470-
match sess.source_map().span_to_snippet(expn_data.def_site) {
471-
Ok(code) => !code.starts_with("macro_rules"),
472-
// No snippet means external macro or compiler-builtin expansion.
473-
Err(_) => true,
474-
}
475-
}
476-
ExpnKind::Macro(..) => true, // definitely a plugin
477-
}
478-
}

0 commit comments

Comments
 (0)