Skip to content

Commit bdc4c56

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 af7ef89 commit bdc4c56

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
@@ -2863,11 +2863,11 @@ pub(crate) struct ExternCrateNotIdiomatic {
28632863
}
28642864

28652865
// FIXME: make this translatable
2866-
pub(crate) struct AmbiguousGlobImports {
2866+
pub(crate) struct AmbiguousImports {
28672867
pub ambiguity: AmbiguityErrorDiag,
28682868
}
28692869

2870-
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
2870+
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousImports {
28712871
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
28722872
diag.primary_message(self.ambiguity.msg.clone());
28732873
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)]
@@ -697,13 +697,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
697697
// Skip ambiguity errors for extern flag bindings "overridden"
698698
// by extern item bindings.
699699
// FIXME: Remove with lang team approval.
700-
let issue_145575_hack = Some(binding)
701-
== extern_prelude_flag_binding
702-
&& extern_prelude_item_binding.is_some()
703-
&& extern_prelude_item_binding != Some(innermost_binding);
700+
let is_issue_145575_hack = || {
701+
Some(binding) == extern_prelude_flag_binding
702+
&& extern_prelude_item_binding.is_some()
703+
&& extern_prelude_item_binding != Some(innermost_binding)
704+
};
705+
704706
if let Some(kind) = ambiguity_error_kind
705-
&& !issue_145575_hack
707+
&& !is_issue_145575_hack()
706708
{
709+
// Turn ambiguity errors for core vs std panic into warnings.
710+
// FIXME: Remove with lang team approval.
711+
let is_issue_147319_hack = matches!(
712+
(binding.res(), innermost_binding.res()),
713+
(
714+
Res::Def(DefKind::Macro(_), def_id_core),
715+
Res::Def(DefKind::Macro(_), def_id_std)
716+
) if this.tcx.def_path_debug_str(def_id_core)
717+
== "core[234c]::macros::panic"
718+
&& this.tcx.def_path_debug_str(def_id_std)
719+
== "std[d474]::macros::panic"
720+
);
721+
722+
let warning = if is_issue_147319_hack {
723+
Some(AmbiguityWarning::PanicImport)
724+
} else {
725+
None
726+
};
727+
707728
let misc = |f: Flags| {
708729
if f.contains(Flags::MISC_SUGGEST_CRATE) {
709730
AmbiguityErrorMisc::SuggestCrate
@@ -720,7 +741,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
720741
ident: orig_ident,
721742
b1: innermost_binding,
722743
b2: binding,
723-
warning: false,
744+
warning,
724745
misc1: misc(innermost_flags),
725746
misc2: misc(flags),
726747
});
@@ -1064,7 +1085,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10641085
ident,
10651086
b1: binding,
10661087
b2: shadowed_glob,
1067-
warning: false,
1088+
warning: None,
10681089
misc1: AmbiguityErrorMisc::None,
10691090
misc2: AmbiguityErrorMisc::None,
10701091
});

compiler/rustc_resolve/src/imports.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -957,8 +957,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
957957
ImportKind::Single { bindings, .. } => bindings[TypeNS].get().binding(),
958958
_ => None,
959959
};
960-
let ambiguity_errors_len =
961-
|errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
960+
let ambiguity_errors_len = |errors: &Vec<AmbiguityError<'_>>| {
961+
errors.iter().filter(|error| error.warning.is_none()).count()
962+
};
962963
let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
963964
let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
964965

@@ -1173,7 +1174,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11731174
});
11741175
let res = binding.res();
11751176
let has_ambiguity_error =
1176-
this.ambiguity_errors.iter().any(|error| !error.warning);
1177+
this.ambiguity_errors.iter().any(|error| error.warning.is_none());
11771178
if res == Res::Err || has_ambiguity_error {
11781179
this.dcx()
11791180
.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> {
@@ -2046,7 +2052,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20462052
b2,
20472053
misc1: AmbiguityErrorMisc::None,
20482054
misc2: AmbiguityErrorMisc::None,
2049-
warning: warn_ambiguity,
2055+
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
20502056
};
20512057
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
20522058
// 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)