mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Rollup merge of #76143 - jyn514:duplicate-builtin-macros, r=petrochenkov
Give a better error message for duplicate built-in macros Minor follow-up to https://github.com/rust-lang/rust/pull/75176 giving a better error message for duplicate builtin macros. This would have made it a little easier to debug. r? @petrochenkov
This commit is contained in:
commit
b01d0b1414
@ -454,6 +454,7 @@ E0768: include_str!("./error_codes/E0768.md"),
|
|||||||
E0769: include_str!("./error_codes/E0769.md"),
|
E0769: include_str!("./error_codes/E0769.md"),
|
||||||
E0770: include_str!("./error_codes/E0770.md"),
|
E0770: include_str!("./error_codes/E0770.md"),
|
||||||
E0771: include_str!("./error_codes/E0771.md"),
|
E0771: include_str!("./error_codes/E0771.md"),
|
||||||
|
E0773: include_str!("./error_codes/E0773.md"),
|
||||||
;
|
;
|
||||||
// E0006, // merged with E0005
|
// E0006, // merged with E0005
|
||||||
// E0008, // cannot bind by-move into a pattern guard
|
// E0008, // cannot bind by-move into a pattern guard
|
||||||
|
38
compiler/rustc_error_codes/src/error_codes/E0773.md
Normal file
38
compiler/rustc_error_codes/src/error_codes/E0773.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
A builtin-macro was defined more than once.
|
||||||
|
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
|
```compile_fail,E0773
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro test($item:item) {
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
|
||||||
|
mod inner {
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro test($item:item) {
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To fix the issue, remove the duplicate declaration:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro test($item:item) {
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In very rare edge cases, this may happen when loading `core` or `std` twice,
|
||||||
|
once with `check` metadata and once with `build` metadata.
|
||||||
|
For more information, see [#75176].
|
||||||
|
|
||||||
|
[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468
|
@ -867,6 +867,12 @@ pub struct ExternPreludeEntry<'a> {
|
|||||||
pub introduced_by_item: bool,
|
pub introduced_by_item: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for better errors for E0773
|
||||||
|
enum BuiltinMacroState {
|
||||||
|
NotYetSeen(SyntaxExtension),
|
||||||
|
AlreadySeen(Span),
|
||||||
|
}
|
||||||
|
|
||||||
/// The main resolver class.
|
/// The main resolver class.
|
||||||
///
|
///
|
||||||
/// This is the visitor that walks the whole crate.
|
/// This is the visitor that walks the whole crate.
|
||||||
@ -960,7 +966,7 @@ pub struct Resolver<'a> {
|
|||||||
|
|
||||||
crate_loader: CrateLoader<'a>,
|
crate_loader: CrateLoader<'a>,
|
||||||
macro_names: FxHashSet<Ident>,
|
macro_names: FxHashSet<Ident>,
|
||||||
builtin_macros: FxHashMap<Symbol, SyntaxExtension>,
|
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
|
||||||
registered_attrs: FxHashSet<Ident>,
|
registered_attrs: FxHashSet<Ident>,
|
||||||
registered_tools: FxHashSet<Ident>,
|
registered_tools: FxHashSet<Ident>,
|
||||||
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use crate::imports::ImportResolver;
|
use crate::imports::ImportResolver;
|
||||||
use crate::Namespace::*;
|
use crate::Namespace::*;
|
||||||
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
|
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy};
|
||||||
use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
|
use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
|
||||||
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
|
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
|
||||||
use rustc_ast::{self as ast, NodeId};
|
use rustc_ast::{self as ast, NodeId};
|
||||||
@ -11,6 +11,7 @@ use rustc_ast_lowering::ResolverAstLowering;
|
|||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_attr::StabilityLevel;
|
use rustc_attr::StabilityLevel;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
|
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
|
||||||
use rustc_expand::compile_declarative_macro;
|
use rustc_expand::compile_declarative_macro;
|
||||||
use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
|
use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
|
||||||
@ -166,7 +167,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) {
|
fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) {
|
||||||
if self.builtin_macros.insert(ident.name, ext).is_some() {
|
if self.builtin_macros.insert(ident.name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
|
||||||
self.session
|
self.session
|
||||||
.span_err(ident.span, &format!("built-in macro `{}` was already defined", ident));
|
.span_err(ident.span, &format!("built-in macro `{}` was already defined", ident));
|
||||||
}
|
}
|
||||||
@ -1076,10 +1077,23 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
if result.is_builtin {
|
if result.is_builtin {
|
||||||
// The macro was marked with `#[rustc_builtin_macro]`.
|
// The macro was marked with `#[rustc_builtin_macro]`.
|
||||||
if let Some(ext) = self.builtin_macros.remove(&item.ident.name) {
|
if let Some(builtin_macro) = self.builtin_macros.get_mut(&item.ident.name) {
|
||||||
// The macro is a built-in, replace its expander function
|
// The macro is a built-in, replace its expander function
|
||||||
// while still taking everything else from the source code.
|
// while still taking everything else from the source code.
|
||||||
result.kind = ext.kind;
|
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
|
||||||
|
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
|
||||||
|
BuiltinMacroState::NotYetSeen(ext) => result.kind = ext.kind,
|
||||||
|
BuiltinMacroState::AlreadySeen(span) => {
|
||||||
|
struct_span_err!(
|
||||||
|
self.session,
|
||||||
|
item.span,
|
||||||
|
E0773,
|
||||||
|
"attempted to define built-in macro more than once"
|
||||||
|
)
|
||||||
|
.span_note(span, "previously defined here")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
|
let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
|
||||||
self.session.span_err(item.span, &msg);
|
self.session.span_err(item.span, &msg);
|
||||||
|
17
src/test/ui/macros/duplicate-builtin.rs
Normal file
17
src/test/ui/macros/duplicate-builtin.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// compile-flags:--crate-type lib
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro test($item:item) {
|
||||||
|
//~^ NOTE previously defined
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
|
||||||
|
mod inner {
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro test($item:item) {
|
||||||
|
//~^ ERROR attempted to define built-in macro more than once [E0773]
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
}
|
21
src/test/ui/macros/duplicate-builtin.stderr
Normal file
21
src/test/ui/macros/duplicate-builtin.stderr
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
error[E0773]: attempted to define built-in macro more than once
|
||||||
|
--> $DIR/duplicate-builtin.rs:13:5
|
||||||
|
|
|
||||||
|
LL | / pub macro test($item:item) {
|
||||||
|
LL | |
|
||||||
|
LL | | /* compiler built-in */
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: previously defined here
|
||||||
|
--> $DIR/duplicate-builtin.rs:6:1
|
||||||
|
|
|
||||||
|
LL | / pub macro test($item:item) {
|
||||||
|
LL | |
|
||||||
|
LL | | /* compiler built-in */
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0773`.
|
@ -1,4 +1,4 @@
|
|||||||
// error-pattern: cannot find a built-in macro with name `line`
|
// error-pattern: attempted to define built-in macro more than once
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
|
macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
|
||||||
|
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! line { () => () }
|
macro_rules! line { () => () } //~ NOTE previously defined here
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
line!();
|
line!();
|
||||||
|
@ -4,7 +4,7 @@ error: cannot find a built-in macro with name `unknown`
|
|||||||
LL | macro_rules! unknown { () => () }
|
LL | macro_rules! unknown { () => () }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: cannot find a built-in macro with name `line`
|
error[E0773]: attempted to define built-in macro more than once
|
||||||
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | / macro_rules! line {
|
LL | / macro_rules! line {
|
||||||
@ -13,6 +13,13 @@ LL | | /* compiler built-in */
|
|||||||
LL | | };
|
LL | | };
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
||||||
|
note: previously defined here
|
||||||
|
--> $DIR/unknown-builtin.rs:9:1
|
||||||
|
|
|
||||||
|
LL | macro_rules! line { () => () }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0773`.
|
||||||
|
Loading…
Reference in New Issue
Block a user