Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,11 +645,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return None;
}

// preemptively look for ambiguities for panic macros to ensure we don't
// speculatively resolve to a non-prelude item when an ambiguity that we'd
// downgrade is present
let is_issue_147319_hack = || ctxt.edition()
<= Edition::Edition2024
&& matches!(orig_ident.name, sym::panic)
&& (this.is_specific_builtin_macro(binding.res(), sym::std_panic) || this.is_specific_builtin_macro(binding.res(), sym::core_panic));
let finalizing = !matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. }));

// Below we report various ambiguity errors.
// We do not need to report them if we are either in speculative resolution,
// or in late resolution when everything is already imported and expanded
// and no ambiguities exist.
if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
if !finalizing && !is_issue_147319_hack() {
return Some(Ok(binding));
}

Expand Down Expand Up @@ -720,8 +729,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let is_issue_147319_hack = ctxt.edition()
<= Edition::Edition2024
&& matches!(orig_ident.name, sym::panic)
&& this.is_builtin_macro(binding.res())
&& this.is_builtin_macro(innermost_binding.res());
&& matches!(scope, Scope::StdLibPrelude)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this handles the case where we're firing on two globs where neither is from the implicit prelude import (the glob vs multiouter test) and turning it into a hard error. We probably want this to be a warning but I think the tiebreak logic as I wrote it may be broken in this case and depend on import expansion order.

&& ((this.is_specific_builtin_macro(
binding.res(),
sym::std_panic,
) && this.is_specific_builtin_macro(
innermost_binding.res(),
sym::core_panic,
)) || (this.is_specific_builtin_macro(
binding.res(),
sym::core_panic,
) && this.is_specific_builtin_macro(
innermost_binding.res(),
sym::std_panic,
)));

let warning = if is_issue_147319_hack {
Some(AmbiguityWarning::PanicImport)
Expand All @@ -740,16 +761,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
AmbiguityErrorMisc::None
}
};
this.get_mut().ambiguity_errors.push(AmbiguityError {
kind,
ident: orig_ident,
b1: innermost_binding,
b2: binding,
warning,
misc1: misc(innermost_flags),
misc2: misc(flags),
});
return Some(Ok(innermost_binding));
if finalizing {
this.get_mut().ambiguity_errors.push(AmbiguityError {
kind,
ident: orig_ident,
b1: innermost_binding,
b2: binding,
warning,
misc1: misc(innermost_flags),
misc2: misc(flags),
});
}
if is_issue_147319_hack {
return Some(Ok(binding));
} else {
return Some(Ok(innermost_binding));
}
}
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
}

fn is_specific_builtin_macro(&self, res: Res, symbol: Symbol) -> bool {
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name == Some(symbol))
}

fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
loop {
match ctxt.outer_expn_data().macro_def_id {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ edition: 2024
#![crate_type = "lib"]
mod m1 {
pub use core::prelude::v1::*;
}

mod m2 {
pub use std::prelude::v1::*;
}

#[allow(unused)]
use m2::*;
fn foo() {
use m1::*;

panic!(); //~ ERROR: `panic` is ambiguous [E0659]
}
23 changes: 23 additions & 0 deletions tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0659]: `panic` is ambiguous
--> $DIR/ambiguous-panic-glob-vs-multiouter.rs:19:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-glob-vs-multiouter.rs:14:9
|
LL | use m1::*;
| ^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
note: `panic` could also refer to the macro imported here
--> $DIR/ambiguous-panic-glob-vs-multiouter.rs:12:5
|
LL | use m2::*;
| ^^^^^
= help: use `crate::panic` to refer to this macro unambiguously

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0659`.
23 changes: 23 additions & 0 deletions tests/ui/imports/ambiguous-panic-globvsglob.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ edition: 2024
#![crate_type = "lib"]
mod m1 {
pub use core::prelude::v1::*;
}

mod m2 {
pub use std::prelude::v1::*;
}

#[allow(unused)]
fn foo() {
use m1::*;
use m2::*;

// I had hoped that this would not produce the globvsglob error because it would never be
// resolving `panic` via one of the ambiguous glob imports above but it appears to do so, not
// sure why
Comment on lines +16 to +18
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expected this to only have two candidates because both globs are in the same scope, so panic candidates should only exist in two scopes total and it should tiebreak to the prelude candidate.

panic!();
//~^ ERROR: `panic` is ambiguous [E0659]
//~| WARN: `panic` is ambiguous [ambiguous_panic_imports]
//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
}
42 changes: 42 additions & 0 deletions tests/ui/imports/ambiguous-panic-globvsglob.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
error[E0659]: `panic` is ambiguous
--> $DIR/ambiguous-panic-globvsglob.rs:19:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= note: ambiguous because of multiple glob imports of a name in the same module
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-globvsglob.rs:13:9
|
LL | use m1::*;
| ^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
note: `panic` could also refer to the macro imported here
--> $DIR/ambiguous-panic-globvsglob.rs:14:9
|
LL | use m2::*;
| ^^^^^
= help: consider adding an explicit import of `panic` to disambiguate

warning: `panic` is ambiguous
--> $DIR/ambiguous-panic-globvsglob.rs:19:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-globvsglob.rs:13:9
|
LL | use m1::*;
| ^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
note: `panic` could also refer to a macro from prelude
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
= note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0659`.
16 changes: 16 additions & 0 deletions tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ edition: 2024
#![crate_type = "lib"]
#![no_implicit_prelude]

mod m1 {
macro_rules! panic {
() => {};
}

pub(crate) use panic;
}

fn foo() {
use m1::*;
panic!(); //~ERROR: `panic` is ambiguous [E0659]
}
19 changes: 19 additions & 0 deletions tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0659]: `panic` is ambiguous
--> $DIR/ambiguous-panic-no-implicit-prelude.rs:15:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-no-implicit-prelude.rs:14:9
|
LL | use m1::*;
| ^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
note: `panic` could also refer to a macro from prelude
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0659`.
11 changes: 11 additions & 0 deletions tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ edition: 2024
//@ check-pass
#![crate_type = "lib"]

use ::core::*;

fn f() {
panic!();
//~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
}
22 changes: 22 additions & 0 deletions tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
warning: `panic` is ambiguous
--> $DIR/ambiguous-panic-non-prelude-core-glob.rs:8:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-non-prelude-core-glob.rs:5:5
|
LL | use ::core::*;
| ^^^^^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
= help: or use `crate::panic` to refer to this macro unambiguously
note: `panic` could also refer to a macro from prelude
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
= note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default

warning: 1 warning emitted

12 changes: 12 additions & 0 deletions tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ check-pass
#![crate_type = "lib"]
#![no_std]

extern crate std;
use ::std::*;

fn f() {
panic!();
//~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
}
22 changes: 22 additions & 0 deletions tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
warning: `panic` is ambiguous
--> $DIR/ambiguous-panic-non-prelude-std-glob.rs:9:5
|
LL | panic!();
| ^^^^^ ambiguous name
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-non-prelude-std-glob.rs:6:5
|
LL | use ::std::*;
| ^^^^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
= help: or use `crate::panic` to refer to this macro unambiguously
note: `panic` could also refer to a macro from prelude
--> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
= note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default

warning: 1 warning emitted

14 changes: 14 additions & 0 deletions tests/ui/imports/ambiguous-panic-pick-core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ edition: 2018
#![crate_type = "lib"]
#![no_std]

extern crate std;
use ::std::prelude::v1::*;

fn f() {
panic!(std::string::String::new());
//~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| ERROR: mismatched types [E0308]

}
39 changes: 39 additions & 0 deletions tests/ui/imports/ambiguous-panic-pick-core.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
warning: `panic` is ambiguous
--> $DIR/ambiguous-panic-pick-core.rs:9:5
|
LL | panic!(std::string::String::new());
| ^^^^^ ambiguous name
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> $DIR/ambiguous-panic-pick-core.rs:6:5
|
LL | use ::std::prelude::v1::*;
| ^^^^^^^^^^^^^^^^^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
= help: or use `crate::panic` to refer to this macro unambiguously
note: `panic` could also refer to a macro from prelude
--> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
= note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default

error[E0308]: mismatched types
--> $DIR/ambiguous-panic-pick-core.rs:9:12
|
LL | panic!(std::string::String::new());
| -------^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | |
| | expected `&str`, found `String`
| arguments to this function are incorrect
|
note: function defined here
--> $SRC_DIR/core/src/panicking.rs:LL:COL
help: consider borrowing here
|
LL | panic!(&std::string::String::new());
| +

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0308`.
12 changes: 12 additions & 0 deletions tests/ui/imports/ambiguous-panic-pick-std.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ edition: 2018
//@ check-pass
#![crate_type = "lib"]
use ::core::prelude::v1::*;

#[allow(unused)]
fn f() {
panic!(std::string::String::new());
//~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| WARN: panic message is not a string literal [non_fmt_panics]
}
Loading
Loading