Skip to content

Commit 0d65e5a

Browse files
committed
Auto merge of rust-lang#128550 - compiler-errors:shadowed-params-perf, r=petrochenkov
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 rust-lang#128357 (comment). Please review with whitespace *off*, the diff should be like 2 lines. r? petrochenkov
2 parents 86e7875 + abada5f commit 0d65e5a

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

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

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

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

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

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

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

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

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

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

27862795
self.lifetime_ribs.push(function_lifetime_rib);

0 commit comments

Comments
 (0)