Skip to content

Commit a619ad8

Browse files
address review
1 parent c925e11 commit a619ad8

File tree

5 files changed

+77
-51
lines changed

5 files changed

+77
-51
lines changed

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
151151
self.lint_shadowed_supertrait_items(pick, segment);
152152

153153
// Lint when a trait is ambiguously imported
154-
self.lint_ambiguously_imported_trait(pick, segment);
154+
self.lint_ambiguously_glob_imported_trait(pick, segment);
155155

156156
// Add any trait/regions obligations specified on the method's type parameters.
157157
// We won't add these if we encountered an illegal sized bound, so that we can use
@@ -720,7 +720,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
720720
);
721721
}
722722

723-
fn lint_ambiguously_imported_trait(
723+
fn lint_ambiguously_glob_imported_trait(
724724
&self,
725725
pick: &probe::Pick<'_>,
726726
segment: &hir::PathSegment<'tcx>,
@@ -733,7 +733,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
733733
let import_span = self.tcx.hir_span_if_local(pick.import_ids[0].to_def_id()).unwrap();
734734

735735
self.tcx.node_lint(AMBIGUOUS_TRAIT_GLOB_IMPORTS, segment.hir_id, |diag| {
736-
diag.primary_message(format!("Usage of ambiguously imported trait `{trait_name}`"))
736+
diag.primary_message(format!("Use of ambiguously glob imported trait `{trait_name}`"))
737737
.span(segment.ident.span)
738738
.span_label(import_span, format!("`{trait_name}`imported ambiguously here"))
739739
.help(format!("Import `{trait_name}` explicitly"));

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4439,8 +4439,9 @@ declare_lint! {
44394439
}
44404440

44414441
declare_lint! {
4442-
/// The `ambiguous_trait_glob_imports` lint report traits that are imported ambiguously by glob imports,
4443-
/// but this wasn't done previously due to a rustc bug.
4442+
/// The `ambiguous_trait_glob_imports` lint reports uses of traits that are
4443+
/// imported ambiguously via glob imports. Previously, this was not enforced
4444+
/// due to a bug in rustc.
44444445
///
44454446
/// ### Example
44464447
///
@@ -4471,12 +4472,25 @@ declare_lint! {
44714472
///
44724473
/// ### Explanation
44734474
///
4474-
/// Previous versions of Rust compile this wrong and actually report that `method2`
4475-
/// can't be found. Now both traits are imported but a warning is emitted that they are ambiguous.
4475+
/// When multiple traits with the same name are brought into scope through glob imports,
4476+
/// one trait becomes the "primary" one while the others are shadowed. Methods from the
4477+
/// shadowed traits (e.g. `method2`) become inaccessible, while methods from the "primary"
4478+
/// trait (e.g. `method1`) still resolve. Ideally, none of the ambiguous traits would be in scope,
4479+
/// but we have to allow this for now because of backwards compatibility.
4480+
/// This lint reports uses of these "primary" traits that are ambiguous.
44764481
///
4482+
/// This is a [future-incompatible] lint to transition this to a
4483+
/// hard error in the future.
4484+
///
4485+
/// [future-incompatible]: ../index.md#future-incompatible-lints
44774486
pub AMBIGUOUS_TRAIT_GLOB_IMPORTS,
44784487
Warn,
4479-
"detects certain glob imports that import traits ambiguously and reports them.",
4488+
"detects usages of ambiguously glob imported traits",
4489+
@future_incompatible = FutureIncompatibleInfo {
4490+
reason: FutureIncompatibilityReason::FutureReleaseError,
4491+
reference: "issue #147992 <https://github.com/rust-lang/rust/issues/147992>",
4492+
report_in_deps: false,
4493+
};
44804494
}
44814495

44824496
declare_lint! {

compiler/rustc_resolve/src/lib.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -712,29 +712,17 @@ impl<'ra> Module<'ra> {
712712
let mut traits = self.traits.borrow_mut(resolver.as_ref());
713713
if traits.is_none() {
714714
let mut collected_traits = Vec::new();
715-
self.for_each_child(resolver, |r, name, ns, mut binding| {
715+
self.for_each_child(resolver, |r, name, ns, binding| {
716716
if ns != TypeNS {
717717
return;
718718
}
719-
let lint_ambiguous = binding.is_ambiguity_recursive();
720-
loop {
721-
// Add to collected_traits if it's a trait
722-
if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() {
723-
collected_traits.push((
724-
name,
725-
binding,
726-
r.as_ref().get_module(def_id),
727-
lint_ambiguous,
728-
));
729-
}
730-
731-
// Break if no ambiguity
732-
let Some((ambiguous_binding, AmbiguityKind::GlobVsGlob)) = binding.ambiguity
733-
else {
734-
break;
735-
};
736-
737-
binding = ambiguous_binding;
719+
if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() {
720+
collected_traits.push((
721+
name,
722+
binding,
723+
r.as_ref().get_module(def_id),
724+
binding.is_ambiguity_recursive(),
725+
));
738726
}
739727
});
740728
*traits = Some(collected_traits.into_boxed_slice());

tests/ui/imports/ambiguous-trait-in-scope.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//@ check-pass
2-
31
mod m1 {
42
pub trait Trait {
53
fn method1(&self) {}
@@ -17,16 +15,18 @@ pub fn test1() {
1715
// Create an ambiguous import for `Trait` in one order
1816
use m1::*;
1917
use m2::*;
20-
0u8.method1(); //~ WARNING Usage of ambiguously imported trait `Trait` [ambiguous_trait_glob_imports]
21-
0u8.method2(); //~ WARNING Usage of ambiguously imported trait `Trait` [ambiguous_trait_glob_imports]
18+
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_trait_glob_imports]
19+
//~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
20+
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
2221
}
2322

2423
fn test2() {
2524
// Create an ambiguous import for `Trait` in another order
2625
use m2::*;
2726
use m1::*;
28-
0u8.method1(); //~ WARNING Usage of ambiguously imported trait `Trait` [ambiguous_trait_glob_imports]
29-
0u8.method2(); //~ WARNING Usage of ambiguously imported trait `Trait` [ambiguous_trait_glob_imports]
27+
0u8.method1(); //~ ERROR: no method named `method1` found for type `u8` in the current scope
28+
0u8.method2(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_trait_glob_imports]
29+
//~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3030
}
3131

3232
fn main() {}
Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,70 @@
1-
warning: Usage of ambiguously imported trait `Trait`
2-
--> $DIR/ambiguous-trait-in-scope.rs:20:9
1+
warning: Use of ambiguously glob imported trait `Trait`
2+
--> $DIR/ambiguous-trait-in-scope.rs:18:9
33
|
44
LL | use m1::*;
55
| -- `Trait`imported ambiguously here
66
LL | use m2::*;
77
LL | 0u8.method1();
88
| ^^^^^^^
99
|
10+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
11+
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
1012
= help: Import `Trait` explicitly
11-
= note: `#[warn(ambiguous_trait_glob_imports)]` on by default
13+
= note: `#[warn(ambiguous_trait_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default
1214

13-
warning: Usage of ambiguously imported trait `Trait`
14-
--> $DIR/ambiguous-trait-in-scope.rs:21:9
15+
error[E0599]: no method named `method2` found for type `u8` in the current scope
16+
--> $DIR/ambiguous-trait-in-scope.rs:20:9
1517
|
16-
LL | use m2::*;
17-
| -- `Trait`imported ambiguously here
18-
LL | 0u8.method1();
18+
LL | fn method2(&self) {}
19+
| ------- the method is available for `u8` here
20+
...
1921
LL | 0u8.method2();
2022
| ^^^^^^^
2123
|
22-
= help: Import `Trait` explicitly
24+
= help: items from traits can only be used if the trait is in scope
25+
help: trait `Trait` which provides `method2` is implemented but not in scope; perhaps you want to import it
26+
|
27+
LL + use m2::Trait;
28+
|
29+
help: there is a method `method1` with a similar name
30+
|
31+
LL - 0u8.method2();
32+
LL + 0u8.method1();
33+
|
2334

24-
warning: Usage of ambiguously imported trait `Trait`
25-
--> $DIR/ambiguous-trait-in-scope.rs:28:9
35+
error[E0599]: no method named `method1` found for type `u8` in the current scope
36+
--> $DIR/ambiguous-trait-in-scope.rs:27:9
2637
|
27-
LL | use m1::*;
28-
| -- `Trait`imported ambiguously here
38+
LL | fn method1(&self) {}
39+
| ------- the method is available for `u8` here
40+
...
2941
LL | 0u8.method1();
3042
| ^^^^^^^
3143
|
32-
= help: Import `Trait` explicitly
44+
= help: items from traits can only be used if the trait is in scope
45+
help: trait `Trait` which provides `method1` is implemented but not in scope; perhaps you want to import it
46+
|
47+
LL + use m1::Trait;
48+
|
49+
help: there is a method `method2` with a similar name
50+
|
51+
LL - 0u8.method1();
52+
LL + 0u8.method2();
53+
|
3354

34-
warning: Usage of ambiguously imported trait `Trait`
35-
--> $DIR/ambiguous-trait-in-scope.rs:29:9
55+
warning: Use of ambiguously glob imported trait `Trait`
56+
--> $DIR/ambiguous-trait-in-scope.rs:28:9
3657
|
3758
LL | use m2::*;
3859
| -- `Trait`imported ambiguously here
3960
...
4061
LL | 0u8.method2();
4162
| ^^^^^^^
4263
|
64+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
65+
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
4366
= help: Import `Trait` explicitly
4467

45-
warning: 4 warnings emitted
68+
error: aborting due to 2 previous errors; 2 warnings emitted
4669

70+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)