Skip to content

Commit

Permalink
Add cargo update suggestion for non local defs
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Feb 17, 2024
1 parent 85e3a2e commit 63469ab
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 52 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ lint_non_fmt_panic_unused =
}
.add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`
lint_non_local_definitions_deprecation = this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
lint_non_local_definitions_impl = non-local `impl` definition, they should be avoided as they go against expectation
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,8 @@ pub enum NonLocalDefinitionsDiag {
depth: u32,
body_kind_descr: &'static str,
body_name: String,
#[subdiagnostic]
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
#[suggestion(lint_const_anon, code = "_", applicability = "machine-applicable")]
const_anon: Option<Span>,
},
Expand All @@ -1313,7 +1315,21 @@ pub enum NonLocalDefinitionsDiag {
#[note(lint_non_local)]
#[note(lint_exception)]
#[note(lint_non_local_definitions_deprecation)]
MacroRules { depth: u32, body_kind_descr: &'static str, body_name: String },
MacroRules {
depth: u32,
body_kind_descr: &'static str,
body_name: String,
#[subdiagnostic]
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
},
}

#[derive(Subdiagnostic)]
#[note(lint_non_local_definitions_cargo_update)]
pub struct NonLocalDefinitionsCargoUpdateNote {
pub macro_kind: &'static str,
pub macro_name: Symbol,
pub crate_name: Symbol,
}

// pass_by_value.rs
Expand Down
25 changes: 23 additions & 2 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
use rustc_span::{def_id::DefId, sym, symbol::kw, MacroKind};
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};

use smallvec::{smallvec, SmallVec};

use crate::{lints::NonLocalDefinitionsDiag, LateContext, LateLintPass, LintContext};
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
use crate::{LateContext, LateLintPass, LintContext};

declare_lint! {
/// The `non_local_definitions` lint checks for `impl` blocks and `#[macro_export]`
Expand Down Expand Up @@ -77,6 +79,23 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
return;
}

let cargo_update = || {
let oexpn = item.span.ctxt().outer_expn_data();
if let Some(def_id) = oexpn.macro_def_id
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
&& def_id.krate != LOCAL_CRATE
&& std::env::var_os("CARGO").is_some()
{
Some(NonLocalDefinitionsCargoUpdateNote {
macro_kind: macro_kind.descr(),
macro_name,
crate_name: cx.tcx.crate_name(def_id.krate),
})
} else {
None
}
};

match item.kind {
ItemKind::Impl(impl_) => {
// The RFC states:
Expand Down Expand Up @@ -162,6 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
body_name: parent_opt_item_name
.map(|s| s.to_ident_string())
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
const_anon,
},
)
Expand All @@ -179,6 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
body_name: parent_opt_item_name
.map(|s| s.to_ident_string())
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
},
)
}
Expand Down
26 changes: 26 additions & 0 deletions tests/ui/lint/auxiliary/non_local_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#[macro_export]
macro_rules! non_local_impl {
($a:ident) => {
const _IMPL_DEBUG: () = {
impl ::std::fmt::Debug for $a {
fn fmt(&self, _: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error>
{
todo!()
}
}
};
}
}

#[macro_export]
macro_rules! non_local_macro_rules {
($a:ident) => {
const _MACRO_EXPORT: () = {
#[macro_export]
macro_rules! $a {
() => {}
}
};
}
}
12 changes: 12 additions & 0 deletions tests/ui/lint/non_local_definitions.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//@ check-pass
//@ edition:2021
//@ aux-build:non_local_macro.rs
//@ rustc-env:CARGO=/usr/bin/cargo

#![feature(inline_const)]

extern crate non_local_macro;

use std::fmt::{Debug, Display};

struct Test;
Expand Down Expand Up @@ -364,6 +368,14 @@ macro_rules! m {

m!();

struct CargoUpdate;

non_local_macro::non_local_impl!(CargoUpdate);
//~^ WARN non-local `impl` definition

non_local_macro::non_local_macro_rules!(my_macro);
//~^ WARN non-local `macro_rules!` definition

fn bitflags() {
struct Flags;

Expand Down
Loading

0 comments on commit 63469ab

Please sign in to comment.