Skip to content

Commit

Permalink
Adapt TypeFolder implementors to return a Result
Browse files Browse the repository at this point in the history
Co-authored-by: Alan Egerton <eggyal@gmail.com>
  • Loading branch information
LeSeulArtichaut and eggyal committed Nov 26, 2021
1 parent 6e3fa20 commit 6dc3dae
Show file tree
Hide file tree
Showing 24 changed files with 387 additions and 305 deletions.
49 changes: 26 additions & 23 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
self.tcx
}

fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
where
T: TypeFoldable<'tcx>,
{
Expand All @@ -288,13 +288,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
t
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
match *r {
ty::ReLateBound(index, ..) => {
if index >= self.binder_index {
bug!("escaping late-bound region during canonicalization");
} else {
r
Ok(r)
}
}

Expand All @@ -311,19 +311,19 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
vid, r
);
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
self.canonicalize_region_mode.canonicalize_free_region(self, r)
Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r))
}

ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReFree(_)
| ty::ReEmpty(_)
| ty::RePlaceholder(..)
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
| ty::ReErased => Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r)),
}
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
match *t.kind() {
ty::Infer(ty::TyVar(vid)) => {
debug!("canonical: type var found with vid {:?}", vid);
Expand All @@ -339,40 +339,40 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
Err(mut ui) => {
// FIXME: perf problem described in #55921.
ui = ty::UniverseIndex::ROOT;
self.canonicalize_ty_var(
Ok(self.canonicalize_ty_var(
CanonicalVarInfo {
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
},
t,
)
))
}
}
}

ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
t,
),
)),

ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
t,
),
)),

ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("encountered a fresh type during canonicalization")
}

ty::Placeholder(placeholder) => self.canonicalize_ty_var(
ty::Placeholder(placeholder) => Ok(self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
t,
),
)),

ty::Bound(debruijn, _) => {
if debruijn >= self.binder_index {
bug!("escaping bound type during canonicalization")
} else {
t
Ok(t)
}
}

Expand Down Expand Up @@ -403,13 +403,16 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
if t.flags().intersects(self.needs_canonical_flags) {
t.super_fold_with(self)
} else {
t
Ok(t)
}
}
}
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(
&mut self,
ct: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
match ct.val {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
debug!("canonical: const var found with vid {:?}", vid);
Expand All @@ -424,10 +427,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
Err(mut ui) => {
// FIXME: perf problem described in #55921.
ui = ty::UniverseIndex::ROOT;
return self.canonicalize_const_var(
return Ok(self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
ct,
);
));
}
}
}
Expand All @@ -438,20 +441,20 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
if debruijn >= self.binder_index {
bug!("escaping bound type during canonicalization")
} else {
return ct;
return Ok(ct);
}
}
ty::ConstKind::Placeholder(placeholder) => {
return self.canonicalize_const_var(
return Ok(self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
ct,
);
));
}
_ => {}
}

let flags = FlagComputation::for_const(ct);
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { ct }
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { Ok(ct) }
}
}

Expand Down
37 changes: 20 additions & 17 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
self.infcx.tcx
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
match *r {
ty::ReLateBound(..) => {
// leave bound regions alone
r
Ok(r)
}

ty::ReEarlyBound(..)
Expand All @@ -133,32 +133,32 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::ReEmpty(_)
| ty::ReErased => {
// replace all free regions with 'erased
self.tcx().lifetimes.re_erased
Ok(self.tcx().lifetimes.re_erased)
}
ty::ReStatic => {
if self.keep_static {
r
Ok(r)
} else {
self.tcx().lifetimes.re_erased
Ok(self.tcx().lifetimes.re_erased)
}
}
}
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) {
return t;
return Ok(t);
}

let tcx = self.infcx.tcx;

match *t.kind() {
ty::Infer(ty::TyVar(v)) => {
let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)
Ok(self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy))
}

ty::Infer(ty::IntVar(v)) => self.freshen_ty(
ty::Infer(ty::IntVar(v)) => Ok(self.freshen_ty(
self.infcx
.inner
.borrow_mut()
Expand All @@ -167,9 +167,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
.map(|v| v.to_type(tcx)),
ty::IntVar(v),
ty::FreshIntTy,
),
)),

ty::Infer(ty::FloatVar(v)) => self.freshen_ty(
ty::Infer(ty::FloatVar(v)) => Ok(self.freshen_ty(
self.infcx
.inner
.borrow_mut()
Expand All @@ -178,7 +178,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
.map(|v| v.to_type(tcx)),
ty::FloatVar(v),
ty::FreshFloatTy,
),
)),

ty::Infer(ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct)) => {
if ct >= self.ty_freshen_count {
Expand All @@ -189,7 +189,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
self.ty_freshen_count
);
}
t
Ok(t)
}

ty::Generator(..)
Expand Down Expand Up @@ -221,7 +221,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
}
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(
&mut self,
ct: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
match ct.val {
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
let opt_ct = self
Expand All @@ -232,12 +235,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
.probe_value(v)
.val
.known();
return self.freshen_const(
return Ok(self.freshen_const(
opt_ct,
ty::InferConst::Var(v),
ty::InferConst::Fresh,
ct.ty,
);
));
}
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
if i >= self.const_freshen_count {
Expand All @@ -248,7 +251,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
self.const_freshen_count,
);
}
return ct;
return Ok(ct);
}

ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
Expand Down
33 changes: 14 additions & 19 deletions compiler/rustc_infer/src/infer/fudge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
self.infcx.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
match *ty.kind() {
ty::Infer(ty::InferTy::TyVar(vid)) => {
if self.type_vars.0.contains(&vid) {
// This variable was created during the fudging.
// Recreate it with a fresh variable here.
let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize;
let origin = self.type_vars.1[idx];
self.infcx.next_ty_var(origin)
Ok(self.infcx.next_ty_var(origin))
} else {
// This variable was created before the
// "fudging". Since we refresh all type
Expand All @@ -198,48 +198,43 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
debug_assert!(
self.infcx.inner.borrow_mut().type_variables().probe(vid).is_unknown()
);
ty
Ok(ty)
}
}
ty::Infer(ty::InferTy::IntVar(vid)) => {
if self.int_vars.contains(&vid) {
self.infcx.next_int_var()
} else {
ty
}
Ok(if self.int_vars.contains(&vid) { self.infcx.next_int_var() } else { ty })
}
ty::Infer(ty::InferTy::FloatVar(vid)) => {
if self.float_vars.contains(&vid) {
self.infcx.next_float_var()
} else {
ty
}
Ok(if self.float_vars.contains(&vid) { self.infcx.next_float_var() } else { ty })
}
_ => ty.super_fold_with(self),
}
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
if let ty::ReVar(vid) = *r {
if self.region_vars.0.contains(&vid) {
let idx = vid.index() - self.region_vars.0.start.index();
let origin = self.region_vars.1[idx];
return self.infcx.next_region_var(origin);
return Ok(self.infcx.next_region_var(origin));
}
}
r
Ok(r)
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(
&mut self,
ct: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
if self.const_vars.0.contains(&vid) {
// This variable was created during the fudging.
// Recreate it with a fresh variable here.
let idx = (vid.index - self.const_vars.0.start.index) as usize;
let origin = self.const_vars.1[idx];
self.infcx.next_const_var(ty, origin)
Ok(self.infcx.next_const_var(ty, origin))
} else {
ct
Ok(ct)
}
} else {
ct.super_fold_with(self)
Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1745,12 +1745,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
self.infcx.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.infcx.shallow_resolve_ty(ty)
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
Ok(self.infcx.shallow_resolve_ty(ty))
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
fn fold_const(
&mut self,
ct: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
Ok(if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
self.infcx
.inner
.borrow_mut()
Expand All @@ -1761,7 +1764,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
.unwrap_or(ct)
} else {
ct
}
})
}
}

Expand Down
Loading

0 comments on commit 6dc3dae

Please sign in to comment.