|
1 | 1 | use crate::infer::outlives::components::{compute_alias_components_recursive, Component};
|
2 | 2 | use crate::infer::outlives::env::RegionBoundPairs;
|
3 | 3 | use crate::infer::region_constraints::VerifyIfEq;
|
4 |
| -use crate::infer::VerifyBound; |
| 4 | +use crate::infer::{GenericKind, VerifyBound}; |
5 | 5 | use rustc_data_structures::sso::SsoHashSet;
|
6 | 6 | use rustc_middle::ty::GenericArg;
|
7 | 7 | use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
|
@@ -240,10 +240,20 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
240 | 240 | "declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
|
241 | 241 | (r, p)
|
242 | 242 | );
|
| 243 | + // Fast path for the common case. |
| 244 | + match (&p, erased_ty.kind()) { |
| 245 | + // In outlive routines, all types are expected to be fully normalized. |
| 246 | + // And therefore we can safely use structural equality for alias types. |
| 247 | + (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {} |
| 248 | + (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {} |
| 249 | + (GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {} |
| 250 | + _ => return None, |
| 251 | + } |
| 252 | + |
243 | 253 | let p_ty = p.to_ty(tcx);
|
244 | 254 | let erased_p_ty = self.tcx.erase_regions(p_ty);
|
245 | 255 | (erased_p_ty == erased_ty)
|
246 |
| - .then_some(ty::Binder::dummy(ty::OutlivesPredicate(p.to_ty(tcx), r))) |
| 256 | + .then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r))) |
247 | 257 | });
|
248 | 258 |
|
249 | 259 | param_bounds
|
|
0 commit comments