Skip to content

Commit abada5f

Browse files
Only walk ribs to collect possibly shadowed params if we are adding params in our new rib
1 parent 5367673 commit abada5f

File tree

1 file changed

+105
-96
lines changed

1 file changed

+105
-96
lines changed

Diff for: compiler/rustc_resolve/src/late.rs

+105-96
Original file line numberDiff line numberDiff line change
@@ -2667,119 +2667,128 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26672667
let mut function_type_rib = Rib::new(kind);
26682668
let mut function_value_rib = Rib::new(kind);
26692669
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
2670-
let mut seen_bindings = FxHashMap::default();
2671-
// Store all seen lifetimes names from outer scopes.
2672-
let mut seen_lifetimes = FxHashSet::default();
2673-
2674-
// We also can't shadow bindings from associated parent items.
2675-
for ns in [ValueNS, TypeNS] {
2676-
for parent_rib in self.ribs[ns].iter().rev() {
2677-
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
2678-
2679-
// Break at mod level, to account for nested items which are
2680-
// allowed to shadow generic param names.
2681-
if matches!(parent_rib.kind, RibKind::Module(..)) {
2682-
break;
2683-
}
2684-
}
2685-
}
26862670

2687-
// Forbid shadowing lifetime bindings
2688-
for rib in self.lifetime_ribs.iter().rev() {
2689-
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident));
2690-
if let LifetimeRibKind::Item = rib.kind {
2691-
break;
2671+
// Only check for shadowed bindings if we're declaring new params.
2672+
if !params.is_empty() {
2673+
let mut seen_bindings = FxHashMap::default();
2674+
// Store all seen lifetimes names from outer scopes.
2675+
let mut seen_lifetimes = FxHashSet::default();
2676+
2677+
// We also can't shadow bindings from associated parent items.
2678+
for ns in [ValueNS, TypeNS] {
2679+
for parent_rib in self.ribs[ns].iter().rev() {
2680+
seen_bindings
2681+
.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
2682+
2683+
// Break at mod level, to account for nested items which are
2684+
// allowed to shadow generic param names.
2685+
if matches!(parent_rib.kind, RibKind::Module(..)) {
2686+
break;
2687+
}
2688+
}
26922689
}
2693-
}
2694-
2695-
for param in params {
2696-
let ident = param.ident.normalize_to_macros_2_0();
2697-
debug!("with_generic_param_rib: {}", param.id);
26982690

2699-
if let GenericParamKind::Lifetime = param.kind
2700-
&& let Some(&original) = seen_lifetimes.get(&ident)
2701-
{
2702-
diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
2703-
// Record lifetime res, so lowering knows there is something fishy.
2704-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2705-
continue;
2691+
// Forbid shadowing lifetime bindings
2692+
for rib in self.lifetime_ribs.iter().rev() {
2693+
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident));
2694+
if let LifetimeRibKind::Item = rib.kind {
2695+
break;
2696+
}
27062697
}
27072698

2708-
match seen_bindings.entry(ident) {
2709-
Entry::Occupied(entry) => {
2710-
let span = *entry.get();
2711-
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
2712-
self.report_error(param.ident.span, err);
2713-
let rib = match param.kind {
2714-
GenericParamKind::Lifetime => {
2715-
// Record lifetime res, so lowering knows there is something fishy.
2716-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2717-
continue;
2718-
}
2719-
GenericParamKind::Type { .. } => &mut function_type_rib,
2720-
GenericParamKind::Const { .. } => &mut function_value_rib,
2721-
};
2699+
for param in params {
2700+
let ident = param.ident.normalize_to_macros_2_0();
2701+
debug!("with_generic_param_rib: {}", param.id);
27222702

2723-
// Taint the resolution in case of errors to prevent follow up errors in typeck
2724-
self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
2725-
rib.bindings.insert(ident, Res::Err);
2703+
if let GenericParamKind::Lifetime = param.kind
2704+
&& let Some(&original) = seen_lifetimes.get(&ident)
2705+
{
2706+
diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
2707+
// Record lifetime res, so lowering knows there is something fishy.
2708+
self.record_lifetime_param(param.id, LifetimeRes::Error);
27262709
continue;
27272710
}
2728-
Entry::Vacant(entry) => {
2729-
entry.insert(param.ident.span);
2730-
}
2731-
}
27322711

2733-
if param.ident.name == kw::UnderscoreLifetime {
2734-
self.r
2735-
.dcx()
2736-
.emit_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span });
2737-
// Record lifetime res, so lowering knows there is something fishy.
2738-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2739-
continue;
2740-
}
2712+
match seen_bindings.entry(ident) {
2713+
Entry::Occupied(entry) => {
2714+
let span = *entry.get();
2715+
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
2716+
self.report_error(param.ident.span, err);
2717+
let rib = match param.kind {
2718+
GenericParamKind::Lifetime => {
2719+
// Record lifetime res, so lowering knows there is something fishy.
2720+
self.record_lifetime_param(param.id, LifetimeRes::Error);
2721+
continue;
2722+
}
2723+
GenericParamKind::Type { .. } => &mut function_type_rib,
2724+
GenericParamKind::Const { .. } => &mut function_value_rib,
2725+
};
27412726

2742-
if param.ident.name == kw::StaticLifetime {
2743-
self.r.dcx().emit_err(errors::StaticLifetimeIsReserved {
2744-
span: param.ident.span,
2745-
lifetime: param.ident,
2746-
});
2747-
// Record lifetime res, so lowering knows there is something fishy.
2748-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2749-
continue;
2750-
}
2727+
// Taint the resolution in case of errors to prevent follow up errors in typeck
2728+
self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
2729+
rib.bindings.insert(ident, Res::Err);
2730+
continue;
2731+
}
2732+
Entry::Vacant(entry) => {
2733+
entry.insert(param.ident.span);
2734+
}
2735+
}
27512736

2752-
let def_id = self.r.local_def_id(param.id);
2737+
if param.ident.name == kw::UnderscoreLifetime {
2738+
self.r
2739+
.dcx()
2740+
.emit_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span });
2741+
// Record lifetime res, so lowering knows there is something fishy.
2742+
self.record_lifetime_param(param.id, LifetimeRes::Error);
2743+
continue;
2744+
}
27532745

2754-
// Plain insert (no renaming).
2755-
let (rib, def_kind) = match param.kind {
2756-
GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
2757-
GenericParamKind::Const { .. } => (&mut function_value_rib, DefKind::ConstParam),
2758-
GenericParamKind::Lifetime => {
2759-
let res = LifetimeRes::Param { param: def_id, binder };
2760-
self.record_lifetime_param(param.id, res);
2761-
function_lifetime_rib.bindings.insert(ident, (param.id, res));
2746+
if param.ident.name == kw::StaticLifetime {
2747+
self.r.dcx().emit_err(errors::StaticLifetimeIsReserved {
2748+
span: param.ident.span,
2749+
lifetime: param.ident,
2750+
});
2751+
// Record lifetime res, so lowering knows there is something fishy.
2752+
self.record_lifetime_param(param.id, LifetimeRes::Error);
27622753
continue;
27632754
}
2764-
};
27652755

2766-
let res = match kind {
2767-
RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()),
2768-
RibKind::Normal => {
2769-
// FIXME(non_lifetime_binders): Stop special-casing
2770-
// const params to error out here.
2771-
if self.r.tcx.features().non_lifetime_binders
2772-
&& matches!(param.kind, GenericParamKind::Type { .. })
2773-
{
2756+
let def_id = self.r.local_def_id(param.id);
2757+
2758+
// Plain insert (no renaming).
2759+
let (rib, def_kind) = match param.kind {
2760+
GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
2761+
GenericParamKind::Const { .. } => {
2762+
(&mut function_value_rib, DefKind::ConstParam)
2763+
}
2764+
GenericParamKind::Lifetime => {
2765+
let res = LifetimeRes::Param { param: def_id, binder };
2766+
self.record_lifetime_param(param.id, res);
2767+
function_lifetime_rib.bindings.insert(ident, (param.id, res));
2768+
continue;
2769+
}
2770+
};
2771+
2772+
let res = match kind {
2773+
RibKind::Item(..) | RibKind::AssocItem => {
27742774
Res::Def(def_kind, def_id.to_def_id())
2775-
} else {
2776-
Res::Err
27772775
}
2778-
}
2779-
_ => span_bug!(param.ident.span, "Unexpected rib kind {:?}", kind),
2780-
};
2781-
self.r.record_partial_res(param.id, PartialRes::new(res));
2782-
rib.bindings.insert(ident, res);
2776+
RibKind::Normal => {
2777+
// FIXME(non_lifetime_binders): Stop special-casing
2778+
// const params to error out here.
2779+
if self.r.tcx.features().non_lifetime_binders
2780+
&& matches!(param.kind, GenericParamKind::Type { .. })
2781+
{
2782+
Res::Def(def_kind, def_id.to_def_id())
2783+
} else {
2784+
Res::Err
2785+
}
2786+
}
2787+
_ => span_bug!(param.ident.span, "Unexpected rib kind {:?}", kind),
2788+
};
2789+
self.r.record_partial_res(param.id, PartialRes::new(res));
2790+
rib.bindings.insert(ident, res);
2791+
}
27832792
}
27842793

27852794
self.lifetime_ribs.push(function_lifetime_rib);

0 commit comments

Comments
 (0)