Skip to content

Commit a2e4e4a

Browse files
committed
Add ambiguous_panic_imports lint
This turns the ambiguous panic import error into a warning to avoid breaking large parts of the Rust crate ecosystem.
1 parent 09a4a47 commit a2e4e4a

File tree

10 files changed

+164
-28
lines changed

10 files changed

+164
-28
lines changed

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ pub fn decorate_builtin_lint(
257257

258258
lints::ExternCrateNotIdiomatic { span: suggestion_span, code }.decorate_lint(diag);
259259
}
260-
BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => {
261-
lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag);
260+
BuiltinLintDiag::AmbiguousImports { diag: ambiguity } => {
261+
lints::AmbiguousImports { ambiguity }.decorate_lint(diag);
262262
}
263263
BuiltinLintDiag::AmbiguousGlobReexports {
264264
name,

compiler/rustc_lint/src/lints.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,11 +2870,11 @@ pub(crate) struct ExternCrateNotIdiomatic {
28702870
}
28712871

28722872
// FIXME: make this translatable
2873-
pub(crate) struct AmbiguousGlobImports {
2873+
pub(crate) struct AmbiguousImports {
28742874
pub ambiguity: AmbiguityErrorDiag,
28752875
}
28762876

2877-
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
2877+
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousImports {
28782878
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
28792879
diag.primary_message(self.ambiguity.msg.clone());
28802880
rustc_errors::report_ambiguity_error(diag, self.ambiguity);

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ declare_lint_pass! {
2121
AMBIGUOUS_ASSOCIATED_ITEMS,
2222
AMBIGUOUS_GLOB_IMPORTS,
2323
AMBIGUOUS_GLOB_REEXPORTS,
24+
AMBIGUOUS_PANIC_IMPORTS,
2425
ARITHMETIC_OVERFLOW,
2526
ASM_SUB_REGISTER,
2627
BAD_ASM_STYLE,
@@ -4438,6 +4439,43 @@ declare_lint! {
44384439
};
44394440
}
44404441

4442+
declare_lint! {
4443+
/// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
4444+
/// previously didn't do that due to `#[macro_use]` prelude macro import.
4445+
///
4446+
/// ### Example
4447+
///
4448+
/// ```rust,compile_fail
4449+
/// #![deny(ambiguous_panic_imports)]
4450+
/// #![no_std]
4451+
///
4452+
/// extern crate std;
4453+
/// use std::prelude::v1::*;
4454+
///
4455+
/// fn xx() {
4456+
/// panic!(); // resolves to core::panic
4457+
/// }
4458+
/// ```
4459+
///
4460+
/// {{produces}}
4461+
///
4462+
/// ### Explanation
4463+
///
4464+
/// Future versions of Rust will no longer accept the ambiguous resolution.
4465+
///
4466+
/// This is a [future-incompatible] lint to transition this to a hard error in the future.
4467+
///
4468+
/// [future-incompatible]: ../index.md#future-incompatible-lints
4469+
pub AMBIGUOUS_PANIC_IMPORTS,
4470+
Warn,
4471+
"detects ambiguous core and std panic imports",
4472+
@future_incompatible = FutureIncompatibleInfo {
4473+
reason: FutureIncompatibilityReason::FutureReleaseError,
4474+
reference: "issue #147319 <https://github.com/rust-lang/rust/issues/147319>",
4475+
report_in_deps: true,
4476+
};
4477+
}
4478+
44414479
declare_lint! {
44424480
/// The `refining_impl_trait_reachable` lint detects `impl Trait` return
44434481
/// types in method signatures that are refined by a publically reachable

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ pub enum BuiltinLintDiag {
682682
vis_span: Span,
683683
ident_span: Span,
684684
},
685-
AmbiguousGlobImports {
685+
AmbiguousImports {
686686
diag: AmbiguityErrorDiag,
687687
},
688688
AmbiguousGlobReexports {

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_middle::bug;
2121
use rustc_middle::ty::TyCtxt;
2222
use rustc_session::Session;
2323
use rustc_session::lint::builtin::{
24-
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS,
24+
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_PANIC_IMPORTS,
2525
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
2626
};
2727
use rustc_session::lint::{AmbiguityErrorDiag, BuiltinLintDiag};
@@ -42,9 +42,9 @@ use crate::errors::{
4242
use crate::imports::{Import, ImportKind};
4343
use crate::late::{PatternSource, Rib};
4444
use crate::{
45-
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
46-
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
47-
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
45+
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey,
46+
Finalize, ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope,
47+
Module, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
4848
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
4949
VisResolutionError, errors as errs, path_names_to_string,
5050
};
@@ -144,15 +144,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
144144

145145
for ambiguity_error in &self.ambiguity_errors {
146146
let diag = self.ambiguity_diagnostics(ambiguity_error);
147-
if ambiguity_error.warning {
147+
if let Some(ambiguity_warning) = ambiguity_error.warning {
148148
let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else {
149149
unreachable!()
150150
};
151+
152+
let lint = match ambiguity_warning {
153+
AmbiguityWarning::GlobImport => AMBIGUOUS_GLOB_IMPORTS,
154+
AmbiguityWarning::PanicImport => AMBIGUOUS_PANIC_IMPORTS,
155+
};
156+
151157
self.lint_buffer.buffer_lint(
152-
AMBIGUOUS_GLOB_IMPORTS,
158+
lint,
153159
import.root_id,
154160
ambiguity_error.ident.span,
155-
BuiltinLintDiag::AmbiguousGlobImports { diag },
161+
BuiltinLintDiag::AmbiguousImports { diag },
156162
);
157163
} else {
158164
let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", diag.msg);

compiler/rustc_resolve/src/ident.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use crate::imports::{Import, NameResolution};
1515
use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
1616
use crate::macros::{MacroRulesScope, sub_namespace_match};
1717
use crate::{
18-
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy,
19-
Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot,
20-
NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError,
21-
Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors,
18+
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver,
19+
Determinacy, Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind,
20+
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res,
21+
ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors,
2222
};
2323

2424
#[derive(Copy, Clone)]
@@ -704,13 +704,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
704704
// Skip ambiguity errors for extern flag bindings "overridden"
705705
// by extern item bindings.
706706
// FIXME: Remove with lang team approval.
707-
let issue_145575_hack = Some(binding)
708-
== extern_prelude_flag_binding
709-
&& extern_prelude_item_binding.is_some()
710-
&& extern_prelude_item_binding != Some(innermost_binding);
707+
let is_issue_145575_hack = || {
708+
Some(binding) == extern_prelude_flag_binding
709+
&& extern_prelude_item_binding.is_some()
710+
&& extern_prelude_item_binding != Some(innermost_binding)
711+
};
712+
711713
if let Some(kind) = ambiguity_error_kind
712-
&& !issue_145575_hack
714+
&& !is_issue_145575_hack()
713715
{
716+
// Turn ambiguity errors for core vs std panic into warnings.
717+
// FIXME: Remove with lang team approval.
718+
let is_issue_147319_hack = matches!(
719+
(binding.res(), innermost_binding.res()),
720+
(
721+
Res::Def(DefKind::Macro(_), def_id_core),
722+
Res::Def(DefKind::Macro(_), def_id_std)
723+
) if this.tcx.def_path_debug_str(def_id_core)
724+
== "core[234c]::macros::panic"
725+
&& this.tcx.def_path_debug_str(def_id_std)
726+
== "std[d474]::macros::panic"
727+
);
728+
729+
let warning = if is_issue_147319_hack {
730+
Some(AmbiguityWarning::PanicImport)
731+
} else {
732+
None
733+
};
734+
714735
let misc = |f: Flags| {
715736
if f.contains(Flags::MISC_SUGGEST_CRATE) {
716737
AmbiguityErrorMisc::SuggestCrate
@@ -727,7 +748,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
727748
ident: orig_ident,
728749
b1: innermost_binding,
729750
b2: binding,
730-
warning: false,
751+
warning,
731752
misc1: misc(innermost_flags),
732753
misc2: misc(flags),
733754
});
@@ -1071,7 +1092,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10711092
ident,
10721093
b1: binding,
10731094
b2: shadowed_glob,
1074-
warning: false,
1095+
warning: None,
10751096
misc1: AmbiguityErrorMisc::None,
10761097
misc2: AmbiguityErrorMisc::None,
10771098
});

compiler/rustc_resolve/src/imports.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,8 +945,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
945945
ImportKind::Single { bindings, .. } => bindings[TypeNS].get().binding(),
946946
_ => None,
947947
};
948-
let ambiguity_errors_len =
949-
|errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
948+
let ambiguity_errors_len = |errors: &Vec<AmbiguityError<'_>>| {
949+
errors.iter().filter(|error| error.warning.is_none()).count()
950+
};
950951
let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
951952
let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
952953

@@ -1161,7 +1162,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11611162
});
11621163
let res = binding.res();
11631164
let has_ambiguity_error =
1164-
this.ambiguity_errors.iter().any(|error| !error.warning);
1165+
this.ambiguity_errors.iter().any(|error| error.warning.is_none());
11651166
if res == Res::Err || has_ambiguity_error {
11661167
this.dcx()
11671168
.span_delayed_bug(import.span, "some error happened for an import");

compiler/rustc_resolve/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,14 +903,20 @@ enum AmbiguityErrorMisc {
903903
None,
904904
}
905905

906+
#[derive(Clone, Copy, PartialEq)]
907+
enum AmbiguityWarning {
908+
GlobImport,
909+
PanicImport,
910+
}
911+
906912
struct AmbiguityError<'ra> {
907913
kind: AmbiguityKind,
908914
ident: Ident,
909915
b1: NameBinding<'ra>,
910916
b2: NameBinding<'ra>,
911917
misc1: AmbiguityErrorMisc,
912918
misc2: AmbiguityErrorMisc,
913-
warning: bool,
919+
warning: Option<AmbiguityWarning>,
914920
}
915921

916922
impl<'ra> NameBindingData<'ra> {
@@ -2039,7 +2045,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20392045
b2,
20402046
misc1: AmbiguityErrorMisc::None,
20412047
misc2: AmbiguityErrorMisc::None,
2042-
warning: warn_ambiguity,
2048+
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
20432049
};
20442050
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
20452051
// avoid duplicated span information to be emit out
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![deny(ambiguous_panic_imports)]
2+
#![crate_type = "lib"]
3+
#![no_std]
4+
5+
extern crate std;
6+
use std::prelude::v1::*;
7+
8+
#[allow(unused)]
9+
fn xx() {
10+
panic!();
11+
//~^ ERROR `panic` is ambiguous
12+
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
13+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error: `panic` is ambiguous
2+
--> $DIR/ambiguous-panic.rs:10:5
3+
|
4+
LL | panic!();
5+
| ^^^^^ ambiguous name
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
9+
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
10+
note: `panic` could refer to the macro imported here
11+
--> $DIR/ambiguous-panic.rs:6:5
12+
|
13+
LL | use std::prelude::v1::*;
14+
| ^^^^^^^^^^^^^^^^^^^
15+
= help: consider adding an explicit import of `panic` to disambiguate
16+
= help: or use `crate::panic` to refer to this macro unambiguously
17+
note: `panic` could also refer to a macro from prelude
18+
--> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
19+
note: the lint level is defined here
20+
--> $DIR/ambiguous-panic.rs:1:9
21+
|
22+
LL | #![deny(ambiguous_panic_imports)]
23+
| ^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: aborting due to 1 previous error
26+
27+
Future incompatibility report: Future breakage diagnostic:
28+
error: `panic` is ambiguous
29+
--> $DIR/ambiguous-panic.rs:10:5
30+
|
31+
LL | panic!();
32+
| ^^^^^ ambiguous name
33+
|
34+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
35+
= note: for more information, see issue #147319 <https://github.com/rust-lang/rust/issues/147319>
36+
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
37+
note: `panic` could refer to the macro imported here
38+
--> $DIR/ambiguous-panic.rs:6:5
39+
|
40+
LL | use std::prelude::v1::*;
41+
| ^^^^^^^^^^^^^^^^^^^
42+
= help: consider adding an explicit import of `panic` to disambiguate
43+
= help: or use `crate::panic` to refer to this macro unambiguously
44+
note: `panic` could also refer to a macro from prelude
45+
--> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
46+
note: the lint level is defined here
47+
--> $DIR/ambiguous-panic.rs:1:9
48+
|
49+
LL | #![deny(ambiguous_panic_imports)]
50+
| ^^^^^^^^^^^^^^^^^^^^^^^
51+

0 commit comments

Comments
 (0)