diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 97261759aeb28..cdb665e066159 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -48,6 +48,7 @@ mod late; mod levels; mod non_ascii_idents; mod nonstandard_style; +mod nonstandard_taste; mod passes; mod redundant_semicolon; mod types; @@ -69,6 +70,7 @@ use builtin::*; use internal::*; use non_ascii_idents::*; use nonstandard_style::*; +use nonstandard_taste::*; use redundant_semicolon::*; use types::*; use unused::*; @@ -183,6 +185,7 @@ macro_rules! late_lint_mod_passes { UnreachablePub: UnreachablePub, ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, InvalidValue: InvalidValue, + PineappleOnPizza: PineappleOnPizza, ] ); }; @@ -247,6 +250,8 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { store.register_lints(&BuiltinCombinedLateLintPass::get_lints()); } + add_lint_group!("nonstandard_taste", PINEAPPLE_ON_PIZZA); + add_lint_group!( "nonstandard_style", NON_CAMEL_CASE_TYPES, diff --git a/src/librustc_lint/nonstandard_taste.rs b/src/librustc_lint/nonstandard_taste.rs new file mode 100644 index 0000000000000..49d76025f052b --- /dev/null +++ b/src/librustc_lint/nonstandard_taste.rs @@ -0,0 +1,52 @@ +use crate::{LateContext, LateLintPass, LintContext}; +use rustc_hir as hir; + +declare_lint! { + pub PINEAPPLE_ON_PIZZA, + Forbid, + "pineapple doesn't go on pizza" +} + +declare_lint_pass!(PineappleOnPizza => [PINEAPPLE_ON_PIZZA]); + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PineappleOnPizza { + fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &hir::Ty<'_>) { + if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &ty.kind { + for pizza_segment in path.segments { + if let Some(args) = pizza_segment.args { + if pizza_segment.ident.name.as_str().to_lowercase() != "pizza" { + continue; + } + for arg in args.args { + if let hir::GenericArg::Type(hir::Ty { + kind: hir::TyKind::Path(hir::QPath::Resolved(_, path)), + .. + }) = arg + { + for pineapple_segment in path.segments { + if pineapple_segment.ident.name.as_str().to_lowercase() + == "pineapple" + { + cx.struct_span_lint( + PINEAPPLE_ON_PIZZA, + pineapple_segment.ident.span, + |lint| { + let mut err = + lint.build("pineapple doesn't go on pizza"); + err.span_label( + pizza_segment.ident.span, + "this is the pizza you ruined", + ); + err.note("you're a monster"); // Yep Esteban, you are. + err.emit(); + }, + ); + } + } + } + } + } + } + } + } +} diff --git a/src/test/ui/lint/pineapple-on-pizza.rs b/src/test/ui/lint/pineapple-on-pizza.rs new file mode 100644 index 0000000000000..2d5846ceb9431 --- /dev/null +++ b/src/test/ui/lint/pineapple-on-pizza.rs @@ -0,0 +1,6 @@ +struct Pizza(T); +struct Pineapple; + +fn main() { + let _: Pizza; //~ERROR pineapple doesn't go on pizza +} diff --git a/src/test/ui/lint/pineapple-on-pizza.stderr b/src/test/ui/lint/pineapple-on-pizza.stderr new file mode 100644 index 0000000000000..f35d1e1276537 --- /dev/null +++ b/src/test/ui/lint/pineapple-on-pizza.stderr @@ -0,0 +1,13 @@ +error: pineapple doesn't go on pizza + --> $DIR/pineapple-on-pizza.rs:5:18 + | +LL | let _: Pizza; + | ----- ^^^^^^^^^ + | | + | this is the pizza you ruined + | + = note: `#[forbid(pineapple_on_pizza)]` on by default + = note: you're a monster + +error: aborting due to previous error +