Skip to content

Commit b9af4aa

Browse files
committed
resolve: Harden some invariant checks for visibilities
1 parent c1e21fb commit b9af4aa

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

compiler/rustc_resolve/src/imports.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ impl<'ra> ImportData<'ra> {
276276
vis: self.vis,
277277
nearest_parent_mod: self.parent_scope.module.nearest_parent_mod().expect_local(),
278278
is_single: matches!(self.kind, ImportKind::Single { .. }),
279+
priv_macro_use: matches!(self.kind, ImportKind::MacroUse { warn_private: true }),
280+
span: self.span,
279281
}
280282
}
281283
}
@@ -384,22 +386,31 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
384386
) -> Visibility {
385387
assert!(import.vis.is_accessible_from(import.nearest_parent_mod, self.tcx));
386388
let decl_vis = if min { decl.min_vis() } else { decl.vis() };
387-
if decl_vis.partial_cmp(import.vis, self.tcx) == Some(Ordering::Less)
389+
let ord = decl_vis.partial_cmp(import.vis, self.tcx);
390+
let extern_crate_hack = pub_use_of_private_extern_crate_hack(import, decl).is_some();
391+
if ord == Some(Ordering::Less)
388392
&& decl_vis.is_accessible_from(import.nearest_parent_mod, self.tcx)
389-
&& pub_use_of_private_extern_crate_hack(import, decl).is_none()
393+
&& !extern_crate_hack
390394
{
391395
// Imported declaration is less visible than the import, but is still visible
392396
// from the current module, use the declaration's visibility.
393397
decl_vis.expect_local()
394398
} else {
395399
// Good case - imported declaration is more visible than the import, or the same,
396400
// use the import's visibility.
401+
//
397402
// Bad case - imported declaration is too private for the current module.
398403
// It doesn't matter what visibility we choose here (except in the `PRIVATE_MACRO_USE`
399-
// and `PUB_USE_OF_PRIVATE_EXTERN_CRATE` cases), because either some error will be
400-
// reported, or the import declaration will be thrown away (unfortunately cannot use
401-
// delayed bug here for this reason).
404+
// and `PUB_USE_OF_PRIVATE_EXTERN_CRATE` cases), because an error will be reported.
402405
// Use import visibility to keep the all declaration visibilities in a module ordered.
406+
if !min
407+
&& matches!(ord, None | Some(Ordering::Less))
408+
&& !extern_crate_hack
409+
&& !import.priv_macro_use
410+
{
411+
let msg = format!("cannot extend visibility from {decl_vis:?} to {:?}", import.vis);
412+
self.dcx().span_delayed_bug(import.span, msg);
413+
}
403414
import.vis
404415
}
405416
}

compiler/rustc_resolve/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,6 +2730,8 @@ struct ImportSummary {
27302730
vis: Visibility,
27312731
nearest_parent_mod: LocalDefId,
27322732
is_single: bool,
2733+
priv_macro_use: bool,
2734+
span: Span,
27332735
}
27342736

27352737
/// Invariant: if `Finalize` is used, expansion and import resolution must be complete.

0 commit comments

Comments
 (0)