Skip to content

Commit a34cead

Browse files
committed
Auto merge of #112847 - bvanjoi:fix-112831, r=Nilstrieb
Revert #112758 and add test case Fixes #112831. Cannot unwrap `update_resolution` for `resolution.single_imports.remove(&Interned::new_unchecked(import));` because there is a relationship between the `Import` and `&NameBinding` in `NameResolution`. This issue caused by my unfamiliarity with the data structure and I apologize for it. This PR had been reverted, and test case have been added. r? `@Nilstrieb` cc `@petrochenkov`
2 parents 1b6d4cd + 09d4a82 commit a34cead

File tree

3 files changed

+86
-40
lines changed

3 files changed

+86
-40
lines changed

compiler/rustc_resolve/src/imports.rs

+53-40
Original file line numberDiff line numberDiff line change
@@ -304,23 +304,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
304304
let res = binding.res();
305305
self.check_reserved_macro_name(key.ident, res);
306306
self.set_binding_parent_module(binding, module);
307-
308-
let mut resolution = self.resolution(module, key).borrow_mut();
309-
let old_binding = resolution.binding();
310-
let mut t = Ok(());
311-
if let Some(old_binding) = resolution.binding {
312-
if res == Res::Err && old_binding.res() != Res::Err {
313-
// Do not override real bindings with `Res::Err`s from error recovery.
314-
} else {
307+
self.update_resolution(module, key, |this, resolution| {
308+
if let Some(old_binding) = resolution.binding {
309+
if res == Res::Err && old_binding.res() != Res::Err {
310+
// Do not override real bindings with `Res::Err`s from error recovery.
311+
return Ok(());
312+
}
315313
match (old_binding.is_glob_import(), binding.is_glob_import()) {
316314
(true, true) => {
317315
if res != old_binding.res() {
318-
resolution.binding = Some(self.ambiguity(
316+
resolution.binding = Some(this.ambiguity(
319317
AmbiguityKind::GlobVsGlob,
320318
old_binding,
321319
binding,
322320
));
323-
} else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
321+
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
324322
// We are glob-importing the same item but with greater visibility.
325323
resolution.binding = Some(binding);
326324
}
@@ -332,7 +330,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
332330
&& key.ns == MacroNS
333331
&& nonglob_binding.expansion != LocalExpnId::ROOT
334332
{
335-
resolution.binding = Some(self.ambiguity(
333+
resolution.binding = Some(this.ambiguity(
336334
AmbiguityKind::GlobVsExpanded,
337335
nonglob_binding,
338336
glob_binding,
@@ -344,40 +342,66 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
344342
if let Some(old_binding) = resolution.shadowed_glob {
345343
assert!(old_binding.is_glob_import());
346344
if glob_binding.res() != old_binding.res() {
347-
resolution.shadowed_glob = Some(self.ambiguity(
345+
resolution.shadowed_glob = Some(this.ambiguity(
348346
AmbiguityKind::GlobVsGlob,
349347
old_binding,
350348
glob_binding,
351349
));
352-
} else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
350+
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
353351
resolution.shadowed_glob = Some(glob_binding);
354352
}
355353
} else {
356354
resolution.shadowed_glob = Some(glob_binding);
357355
}
358356
}
359357
(false, false) => {
360-
t = Err(old_binding);
358+
return Err(old_binding);
361359
}
362360
}
361+
} else {
362+
resolution.binding = Some(binding);
363363
}
364-
} else {
365-
resolution.binding = Some(binding);
366-
};
367364

365+
Ok(())
366+
})
367+
}
368+
369+
fn ambiguity(
370+
&self,
371+
kind: AmbiguityKind,
372+
primary_binding: &'a NameBinding<'a>,
373+
secondary_binding: &'a NameBinding<'a>,
374+
) -> &'a NameBinding<'a> {
375+
self.arenas.alloc_name_binding(NameBinding {
376+
ambiguity: Some((secondary_binding, kind)),
377+
..primary_binding.clone()
378+
})
379+
}
380+
381+
// Use `f` to mutate the resolution of the name in the module.
382+
// If the resolution becomes a success, define it in the module's glob importers.
383+
fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T
384+
where
385+
F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
386+
{
368387
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
369388
// during which the resolution might end up getting re-defined via a glob cycle.
370-
let (binding, t) = match resolution.binding() {
371-
_ if old_binding.is_some() => return t,
372-
None => return t,
373-
Some(binding) => match old_binding {
374-
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
375-
_ => (binding, t),
376-
},
389+
let (binding, t) = {
390+
let resolution = &mut *self.resolution(module, key).borrow_mut();
391+
let old_binding = resolution.binding();
392+
393+
let t = f(self, resolution);
394+
395+
match resolution.binding() {
396+
_ if old_binding.is_some() => return t,
397+
None => return t,
398+
Some(binding) => match old_binding {
399+
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
400+
_ => (binding, t),
401+
},
402+
}
377403
};
378404

379-
drop(resolution);
380-
381405
// Define `binding` in `module`s glob importers.
382406
for import in module.glob_importers.borrow_mut().iter() {
383407
let mut ident = key.ident;
@@ -396,18 +420,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
396420
t
397421
}
398422

399-
fn ambiguity(
400-
&self,
401-
kind: AmbiguityKind,
402-
primary_binding: &'a NameBinding<'a>,
403-
secondary_binding: &'a NameBinding<'a>,
404-
) -> &'a NameBinding<'a> {
405-
self.arenas.alloc_name_binding(NameBinding {
406-
ambiguity: Some((secondary_binding, kind)),
407-
..primary_binding.clone()
408-
})
409-
}
410-
411423
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
412424
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
413425
fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
@@ -757,8 +769,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
757769
.emit();
758770
}
759771
let key = BindingKey::new(target, ns);
760-
let mut resolution = this.resolution(parent, key).borrow_mut();
761-
resolution.single_imports.remove(&Interned::new_unchecked(import));
772+
this.update_resolution(parent, key, |_, resolution| {
773+
resolution.single_imports.remove(&Interned::new_unchecked(import));
774+
});
762775
}
763776
}
764777
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
8+
struct Zeroable;
9+
10+
#[proc_macro_derive(Zeroable)]
11+
pub fn derive_zeroable(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
12+
proc_macro::TokenStream::default()
13+
}

tests/ui/resolve/issue-112831.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// check-pass
2+
// aux-build:issue-112831-aux.rs
3+
4+
mod zeroable {
5+
pub trait Zeroable {}
6+
}
7+
8+
use zeroable::*;
9+
10+
mod pod {
11+
use super::*;
12+
pub trait Pod: Zeroable {}
13+
}
14+
15+
use pod::*;
16+
17+
extern crate issue_112831_aux;
18+
use issue_112831_aux::Zeroable;
19+
20+
fn main() {}

0 commit comments

Comments
 (0)