Skip to content

Commit 77379b8

Browse files
committed
Auto merge of #128550 - compiler-errors:shadowed-params-perf, r=<try>
Only walk ribs to collect possibly shadowed params if we are adding params in our new rib No need to collect params from parent ribs if we literally have no params to declare in this new rib. Attempt to win back some of the perf in #128357 (comment). Please review with whitespace *off*, the diff should be like 2 lines. r? petrochenkov
2 parents 5367673 + abada5f commit 77379b8

File tree

1 file changed

+105
-96
lines changed

1 file changed

+105
-96
lines changed

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)