Skip to content

Commit 9ef27bf

Browse files
committed
Auto merge of #88771 - jackh726:wf_tys_set, r=nikomatsakis
Use FxHashSet instead of Vec for well formed tys Trying to recover perf from #88312 r? `@ghost`
2 parents 0212c70 + 8e7613f commit 9ef27bf

File tree

7 files changed

+40
-37
lines changed

7 files changed

+40
-37
lines changed

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
259259
// We add implied bounds from both the unnormalized and normalized ty
260260
// See issue #87748
261261
let constraints_implied_1 = self.add_implied_bounds(ty);
262-
let TypeOpOutput { output: ty, constraints: constraints1, .. } = self
262+
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
263263
.param_env
264264
.and(type_op::normalize::Normalize::new(ty))
265265
.fully_perform(self.infcx)
@@ -286,8 +286,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
286286
// }
287287
// ```
288288
// Both &Self::Bar and &() are WF
289-
let constraints_implied_2 = self.add_implied_bounds(ty);
290-
normalized_inputs_and_output.push(ty);
289+
let constraints_implied_2 =
290+
if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
291+
normalized_inputs_and_output.push(norm_ty);
291292
constraints1.into_iter().chain(constraints_implied_1).chain(constraints_implied_2)
292293
})
293294
.collect();

compiler/rustc_trait_selection/src/infer.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
22
use crate::traits::query::outlives_bounds::InferCtxtExt as _;
33
use crate::traits::{self, TraitEngine, TraitEngineExt};
44

5+
use rustc_data_structures::stable_set::FxHashSet;
56
use rustc_hir as hir;
67
use rustc_hir::def_id::DefId;
78
use rustc_hir::lang_items::LangItem;
@@ -184,7 +185,7 @@ pub trait OutlivesEnvironmentExt<'tcx> {
184185
fn add_implied_bounds(
185186
&mut self,
186187
infcx: &InferCtxt<'a, 'tcx>,
187-
fn_sig_tys: &[Ty<'tcx>],
188+
fn_sig_tys: FxHashSet<Ty<'tcx>>,
188189
body_id: hir::HirId,
189190
span: Span,
190191
);
@@ -210,13 +211,13 @@ impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> {
210211
fn add_implied_bounds(
211212
&mut self,
212213
infcx: &InferCtxt<'a, 'tcx>,
213-
fn_sig_tys: &[Ty<'tcx>],
214+
fn_sig_tys: FxHashSet<Ty<'tcx>>,
214215
body_id: hir::HirId,
215216
span: Span,
216217
) {
217218
debug!("add_implied_bounds()");
218219

219-
for &ty in fn_sig_tys {
220+
for ty in fn_sig_tys {
220221
let ty = infcx.resolve_vars_if_possible(ty);
221222
debug!("add_implied_bounds: ty = {}", ty);
222223
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);

compiler/rustc_typeck/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ fn check_opaque_meets_bounds<'tcx>(
688688
// Finally, resolve all regions. This catches wily misuses of
689689
// lifetime parameters.
690690
let fcx = FnCtxt::new(&inh, param_env, hir_id);
691-
fcx.regionck_item(hir_id, span, &[]);
691+
fcx.regionck_item(hir_id, span, FxHashSet::default());
692692
});
693693
}
694694

compiler/rustc_typeck/src/check/compare_method.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
2+
use rustc_data_structures::stable_set::FxHashSet;
23
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
34
use rustc_hir as hir;
45
use rustc_hir::def::{DefKind, Res};
@@ -250,7 +251,7 @@ fn compare_predicate_entailment<'tcx>(
250251
// Compute placeholder form of impl and trait method tys.
251252
let tcx = infcx.tcx;
252253

253-
let mut wf_tys = vec![];
254+
let mut wf_tys = FxHashSet::default();
254255

255256
let (impl_sig, _) = infcx.replace_bound_vars_with_fresh_vars(
256257
impl_m_span,
@@ -398,7 +399,7 @@ fn compare_predicate_entailment<'tcx>(
398399
// Finally, resolve all regions. This catches wily misuses of
399400
// lifetime parameters.
400401
let fcx = FnCtxt::new(&inh, param_env, impl_m_hir_id);
401-
fcx.regionck_item(impl_m_hir_id, impl_m_span, &wf_tys);
402+
fcx.regionck_item(impl_m_hir_id, impl_m_span, wf_tys);
402403

403404
Ok(())
404405
})
@@ -1098,7 +1099,7 @@ crate fn compare_const_impl<'tcx>(
10981099
}
10991100

11001101
let fcx = FnCtxt::new(&inh, param_env, impl_c_hir_id);
1101-
fcx.regionck_item(impl_c_hir_id, impl_c_span, &[]);
1102+
fcx.regionck_item(impl_c_hir_id, impl_c_span, FxHashSet::default());
11021103
});
11031104
}
11041105

@@ -1216,7 +1217,7 @@ fn compare_type_predicate_entailment<'tcx>(
12161217
// Finally, resolve all regions. This catches wily misuses of
12171218
// lifetime parameters.
12181219
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
1219-
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &[]);
1220+
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, FxHashSet::default());
12201221

12211222
Ok(())
12221223
})
@@ -1436,10 +1437,10 @@ pub fn check_type_bounds<'tcx>(
14361437
// lifetime parameters.
14371438
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
14381439
let implied_bounds = match impl_ty.container {
1439-
ty::TraitContainer(_) => vec![],
1440+
ty::TraitContainer(_) => FxHashSet::default(),
14401441
ty::ImplContainer(def_id) => fcx.impl_implied_bounds(def_id, impl_ty_span),
14411442
};
1442-
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &implied_bounds);
1443+
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, implied_bounds);
14431444

14441445
Ok(())
14451446
})

compiler/rustc_typeck/src/check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ fn typeck_with_fallback<'tcx>(
388388
// from normalization. We could just discard these, but to align with
389389
// compare_method and elsewhere, we just add implied bounds for
390390
// these types.
391-
let mut wf_tys = vec![];
391+
let mut wf_tys = FxHashSet::default();
392392
// Compute the fty from point of view of inside the fn.
393393
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
394394
wf_tys.extend(fn_sig.inputs_and_output.iter());
@@ -451,7 +451,7 @@ fn typeck_with_fallback<'tcx>(
451451

452452
fcx.write_ty(id, expected_type);
453453

454-
(fcx, vec![])
454+
(fcx, FxHashSet::default())
455455
};
456456

457457
let fallback_has_occurred = fcx.type_inference_fallback();
@@ -475,7 +475,7 @@ fn typeck_with_fallback<'tcx>(
475475
fcx.select_all_obligations_or_error();
476476

477477
if fn_sig.is_some() {
478-
fcx.regionck_fn(id, body, span, &wf_tys);
478+
fcx.regionck_fn(id, body, span, wf_tys);
479479
} else {
480480
fcx.regionck_expr(body);
481481
}

compiler/rustc_typeck/src/check/regionck.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ use crate::check::dropck;
7676
use crate::check::FnCtxt;
7777
use crate::mem_categorization as mc;
7878
use crate::middle::region;
79+
use rustc_data_structures::stable_set::FxHashSet;
7980
use rustc_hir as hir;
8081
use rustc_hir::def_id::LocalDefId;
8182
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -126,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
126127

127128
/// Region checking during the WF phase for items. `wf_tys` are the
128129
/// types from which we should derive implied bounds, if any.
129-
pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) {
130+
pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet<Ty<'tcx>>) {
130131
debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
131132
let subject = self.tcx.hir().local_def_id(item_id);
132133
let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
@@ -149,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149150
fn_id: hir::HirId,
150151
body: &'tcx hir::Body<'tcx>,
151152
span: Span,
152-
wf_tys: &[Ty<'tcx>],
153+
wf_tys: FxHashSet<Ty<'tcx>>,
153154
) {
154155
debug!("regionck_fn(id={})", fn_id);
155156
let subject = self.tcx.hir().body_owner_def_id(body.id());
@@ -286,15 +287,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
286287
// because it will have no effect.
287288
//
288289
// FIXME(#27579) return types should not be implied bounds
289-
let fn_sig_tys: Vec<_> =
290+
let fn_sig_tys: FxHashSet<_> =
290291
fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
291292

292-
self.outlives_environment.add_implied_bounds(
293-
self.fcx,
294-
&fn_sig_tys[..],
295-
body_id.hir_id,
296-
span,
297-
);
293+
self.outlives_environment.add_implied_bounds(self.fcx, fn_sig_tys, body_id.hir_id, span);
298294
self.outlives_environment.save_implied_bounds(body_id.hir_id);
299295
self.link_fn_params(&body.params);
300296
self.visit_body(body);

compiler/rustc_typeck/src/check/wfcheck.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct CheckWfFcxBuilder<'tcx> {
4444
impl<'tcx> CheckWfFcxBuilder<'tcx> {
4545
fn with_fcx<F>(&mut self, f: F)
4646
where
47-
F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> Vec<Ty<'tcx>>,
47+
F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>,
4848
{
4949
let id = self.id;
5050
let span = self.span;
@@ -59,7 +59,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
5959
}
6060
let wf_tys = f(&fcx);
6161
fcx.select_all_obligations_or_error();
62-
fcx.regionck_item(id, span, &wf_tys);
62+
fcx.regionck_item(id, span, wf_tys);
6363
});
6464
}
6565
}
@@ -394,7 +394,7 @@ fn check_associated_item(
394394
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
395395

396396
let (mut implied_bounds, self_ty) = match item.container {
397-
ty::TraitContainer(_) => (vec![], fcx.tcx.types.self_param),
397+
ty::TraitContainer(_) => (FxHashSet::default(), fcx.tcx.types.self_param),
398398
ty::ImplContainer(def_id) => {
399399
(fcx.impl_implied_bounds(def_id, span), fcx.tcx.type_of(def_id))
400400
}
@@ -553,7 +553,7 @@ fn check_type_defn<'tcx, F>(
553553
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
554554

555555
// No implied bounds in a struct definition.
556-
vec![]
556+
FxHashSet::default()
557557
});
558558
}
559559

@@ -579,7 +579,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
579579
for_item(tcx, item).with_fcx(|fcx| {
580580
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
581581

582-
vec![]
582+
FxHashSet::default()
583583
});
584584
}
585585

@@ -620,7 +620,7 @@ fn check_item_fn(
620620
for_id(tcx, item_id, span).with_fcx(|fcx| {
621621
let def_id = tcx.hir().local_def_id(item_id);
622622
let sig = tcx.fn_sig(def_id);
623-
let mut implied_bounds = vec![];
623+
let mut implied_bounds = FxHashSet::default();
624624
check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds);
625625
implied_bounds
626626
})
@@ -659,7 +659,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
659659
}
660660

661661
// No implied bounds in a const, etc.
662-
vec![]
662+
FxHashSet::default()
663663
});
664664
}
665665

@@ -918,14 +918,14 @@ fn check_fn_or_method<'fcx, 'tcx>(
918918
sig: ty::PolyFnSig<'tcx>,
919919
hir_decl: &hir::FnDecl<'_>,
920920
def_id: DefId,
921-
implied_bounds: &mut Vec<Ty<'tcx>>,
921+
implied_bounds: &mut FxHashSet<Ty<'tcx>>,
922922
) {
923923
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
924924

925925
// Unnormalized types in signature are WF too
926926
implied_bounds.extend(sig.inputs());
927927
// FIXME(#27579) return types should not be implied bounds
928-
implied_bounds.push(sig.output());
928+
implied_bounds.insert(sig.output());
929929

930930
// Normalize the input and output types one at a time, using a different
931931
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
@@ -977,7 +977,7 @@ fn check_fn_or_method<'fcx, 'tcx>(
977977
);
978978

979979
// FIXME(#27579) return types should not be implied bounds
980-
implied_bounds.push(sig.output());
980+
implied_bounds.insert(sig.output());
981981

982982
debug!(?implied_bounds);
983983

@@ -1513,7 +1513,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15131513
.collect()
15141514
}
15151515

1516-
pub(super) fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
1516+
pub(super) fn impl_implied_bounds(
1517+
&self,
1518+
impl_def_id: DefId,
1519+
span: Span,
1520+
) -> FxHashSet<Ty<'tcx>> {
15171521
match self.tcx.impl_trait_ref(impl_def_id) {
15181522
Some(trait_ref) => {
15191523
// Trait impl: take implied bounds from all types that
@@ -1526,7 +1530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15261530
// Inherent impl: take implied bounds from the `self` type.
15271531
let self_ty = self.tcx.type_of(impl_def_id);
15281532
let self_ty = self.normalize_associated_types_in(span, self_ty);
1529-
vec![self_ty]
1533+
std::array::IntoIter::new([self_ty]).collect()
15301534
}
15311535
}
15321536
}

0 commit comments

Comments
 (0)