Skip to content

Commit 9a6be1c

Browse files
authored
Rollup merge of #57908 - petrochenkov:errepice, r=estebank
resolve: Fix span arithmetics in the import conflict error #56937 rebased and fixed Fixes #56411 Fixes #57071 Fixes #57787 r? @estebank
2 parents 9230311 + 1b659d6 commit 9a6be1c

File tree

4 files changed

+98
-46
lines changed

4 files changed

+98
-46
lines changed

src/librustc_resolve/lib.rs

+45-46
Original file line numberDiff line numberDiff line change
@@ -5134,60 +5134,59 @@ impl<'a> Resolver<'a> {
51345134
);
51355135

51365136
// See https://github.com/rust-lang/rust/issues/32354
5137-
if old_binding.is_import() || new_binding.is_import() {
5138-
let binding = if new_binding.is_import() && !new_binding.span.is_dummy() {
5139-
new_binding
5137+
let directive = match (&new_binding.kind, &old_binding.kind) {
5138+
(NameBindingKind::Import { directive, .. }, _) if !new_binding.span.is_dummy() =>
5139+
Some((directive, new_binding.span)),
5140+
(_, NameBindingKind::Import { directive, .. }) if !old_binding.span.is_dummy() =>
5141+
Some((directive, old_binding.span)),
5142+
_ => None,
5143+
};
5144+
if let Some((directive, binding_span)) = directive {
5145+
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
5146+
format!("Other{}", name)
51405147
} else {
5141-
old_binding
5148+
format!("other_{}", name)
51425149
};
51435150

5144-
let cm = self.session.source_map();
5145-
let rename_msg = "you can use `as` to change the binding name of the import";
5146-
5147-
if let (
5148-
Ok(snippet),
5149-
NameBindingKind::Import { directive, ..},
5150-
_dummy @ false,
5151-
) = (
5152-
cm.span_to_snippet(binding.span),
5153-
binding.kind.clone(),
5154-
binding.span.is_dummy(),
5155-
) {
5156-
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
5157-
format!("Other{}", name)
5158-
} else {
5159-
format!("other_{}", name)
5160-
};
5151+
let mut suggestion = None;
5152+
match directive.subclass {
5153+
ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } =>
5154+
suggestion = Some(format!("self as {}", suggested_name)),
5155+
ImportDirectiveSubclass::SingleImport { source, .. } => {
5156+
if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0)
5157+
.map(|pos| pos as usize) {
5158+
if let Ok(snippet) = self.session.source_map()
5159+
.span_to_snippet(binding_span) {
5160+
if pos <= snippet.len() {
5161+
suggestion = Some(format!(
5162+
"{} as {}{}",
5163+
&snippet[..pos],
5164+
suggested_name,
5165+
if snippet.ends_with(";") { ";" } else { "" }
5166+
))
5167+
}
5168+
}
5169+
}
5170+
}
5171+
ImportDirectiveSubclass::ExternCrate { source, target, .. } =>
5172+
suggestion = Some(format!(
5173+
"extern crate {} as {};",
5174+
source.unwrap_or(target.name),
5175+
suggested_name,
5176+
)),
5177+
_ => unreachable!(),
5178+
}
51615179

5180+
let rename_msg = "you can use `as` to change the binding name of the import";
5181+
if let Some(suggestion) = suggestion {
51625182
err.span_suggestion_with_applicability(
5163-
binding.span,
5164-
&rename_msg,
5165-
match directive.subclass {
5166-
ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } =>
5167-
format!("self as {}", suggested_name),
5168-
ImportDirectiveSubclass::SingleImport { source, .. } =>
5169-
format!(
5170-
"{} as {}{}",
5171-
&snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
5172-
suggested_name,
5173-
if snippet.ends_with(";") {
5174-
";"
5175-
} else {
5176-
""
5177-
}
5178-
),
5179-
ImportDirectiveSubclass::ExternCrate { source, target, .. } =>
5180-
format!(
5181-
"extern crate {} as {};",
5182-
source.unwrap_or(target.name),
5183-
suggested_name,
5184-
),
5185-
_ => unreachable!(),
5186-
},
5183+
binding_span,
5184+
rename_msg,
5185+
suggestion,
51875186
Applicability::MaybeIncorrect,
51885187
);
51895188
} else {
5190-
err.span_label(binding.span, rename_msg);
5189+
err.span_label(binding_span, rename_msg);
51915190
}
51925191
}
51935192

src/test/ui/issues/issue-56411.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
macro_rules! import {
2+
( $($name:ident),* ) => {
3+
$(
4+
mod $name;
5+
pub use self::$name;
6+
//~^ ERROR the name `issue_56411_aux` is defined multiple times
7+
//~| ERROR `issue_56411_aux` is private, and cannot be re-exported
8+
9+
)*
10+
}
11+
}
12+
13+
import!(issue_56411_aux);
14+
15+
fn main() {
16+
println!("Hello, world!");
17+
}

src/test/ui/issues/issue-56411.stderr

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0255]: the name `issue_56411_aux` is defined multiple times
2+
--> $DIR/issue-56411.rs:5:21
3+
|
4+
LL | mod $name;
5+
| ---------- previous definition of the module `issue_56411_aux` here
6+
LL | pub use self::$name;
7+
| ^^^^^^^^^^^
8+
| |
9+
| `issue_56411_aux` reimported here
10+
| you can use `as` to change the binding name of the import
11+
...
12+
LL | import!(issue_56411_aux);
13+
| ------------------------- in this macro invocation
14+
|
15+
= note: `issue_56411_aux` must be defined only once in the type namespace of this module
16+
17+
error[E0365]: `issue_56411_aux` is private, and cannot be re-exported
18+
--> $DIR/issue-56411.rs:5:21
19+
|
20+
LL | pub use self::$name;
21+
| ^^^^^^^^^^^ re-export of private `issue_56411_aux`
22+
...
23+
LL | import!(issue_56411_aux);
24+
| ------------------------- in this macro invocation
25+
|
26+
= note: consider declaring type or module `issue_56411_aux` with `pub`
27+
28+
error: aborting due to 2 previous errors
29+
30+
Some errors occurred: E0255, E0365.
31+
For more information about an error, try `rustc --explain E0255`.

src/test/ui/issues/issue_56411_aux.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// compile-pass
2+
3+
struct T {}
4+
5+
fn main() {}

0 commit comments

Comments
 (0)