diff options
| author | LeSeulArtichaut <leseulartichaut@gmail.com> | 2021-05-19 15:01:30 +0200 |
|---|---|---|
| committer | Alan Egerton <eggyal@gmail.com> | 2021-11-26 07:25:16 +0000 |
| commit | 6dc3dae46f600efe75627a7ad386e7462066e34d (patch) | |
| tree | 998df08bd8035cb6a9e2435d15a93fd0a4a0c450 | |
| parent | 6e3fa20b00d5b3713848aa162969d7a460bd194a (diff) | |
| download | rust-6dc3dae46f600efe75627a7ad386e7462066e34d.tar.gz rust-6dc3dae46f600efe75627a7ad386e7462066e34d.zip | |
Adapt `TypeFolder` implementors to return a `Result`
Co-authored-by: Alan Egerton <eggyal@gmail.com>
24 files changed, 387 insertions, 305 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 934ada9932e..dd1f0d63aff 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -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>, { @@ -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) } } @@ -311,7 +311,7 @@ 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 @@ -319,11 +319,11 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | 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); @@ -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) } } @@ -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); @@ -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, - ); + )); } } } @@ -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) } } } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index c40e409891b..fce6403575b 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -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(..) @@ -133,21 +133,21 @@ 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; @@ -155,10 +155,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, '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() @@ -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() @@ -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 { @@ -189,7 +189,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { self.ty_freshen_count ); } - t + Ok(t) } ty::Generator(..) @@ -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 @@ -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 { @@ -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(_) => { diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 773753a0363..c889abf3d3c 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -180,7 +180,7 @@ 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) { @@ -188,7 +188,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { // 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 @@ -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) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2fd01c2d595..afac40b0ebd 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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() @@ -1761,7 +1764,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { .unwrap_or(ct) } else { ct - } + }) } } diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 4b08c2eb9c1..d09c585a025 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -30,25 +30,28 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { self.infcx.tcx } - 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.has_infer_types_or_consts() { - t // micro-optimize -- if there is nothing in this type that this fold affects... + Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t = self.infcx.shallow_resolve(t); t.super_fold_with(self) } } - fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> { + fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> Result<&'tcx Const<'tcx>, Self::Error> { if !ct.has_infer_types_or_consts() { - ct // micro-optimize -- if there is nothing in this const that this fold affects... + Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects... } else { let ct = self.infcx.shallow_resolve(ct); ct.super_fold_with(self) } } - fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + fn fold_mir_const( + &mut self, + constant: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { constant.super_fold_with(self) } } @@ -75,16 +78,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { self.infcx.tcx } - 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.has_infer_regions() { - t // micro-optimize -- if there is nothing in this type that this fold affects... + Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... } else { t.super_fold_with(self) } } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + Ok(match *r { ty::ReVar(rid) => { let resolved = self .infcx @@ -95,12 +98,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved)) } _ => 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 !ct.has_infer_regions() { - ct // micro-optimize -- if there is nothing in this const that this fold affects... + Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects... } else { ct.super_fold_with(self) } @@ -195,23 +201,23 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { self.infcx.tcx } - 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 // micro-optimize -- if there is nothing in this type that this fold affects... + Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t = self.infcx.shallow_resolve(t); match *t.kind() { ty::Infer(ty::TyVar(vid)) => { self.err = Some(FixupError::UnresolvedTy(vid)); - self.tcx().ty_error() + Ok(self.tcx().ty_error()) } ty::Infer(ty::IntVar(vid)) => { self.err = Some(FixupError::UnresolvedIntTy(vid)); - self.tcx().ty_error() + Ok(self.tcx().ty_error()) } ty::Infer(ty::FloatVar(vid)) => { self.err = Some(FixupError::UnresolvedFloatTy(vid)); - self.tcx().ty_error() + Ok(self.tcx().ty_error()) } ty::Infer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); @@ -221,28 +227,31 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, '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::ReVar(rid) => self + ty::ReVar(rid) => Ok(self .infcx .lexical_region_resolutions .borrow() .as_ref() .expect("region resolution not performed") - .resolve_var(rid), - _ => r, + .resolve_var(rid)), + _ => Ok(r), } } - fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + fn fold_const( + &mut self, + c: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { if !c.needs_infer() { - c // micro-optimize -- if there is nothing in this const that this fold affects... + Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects... } else { let c = self.infcx.shallow_resolve(c); match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { self.err = Some(FixupError::UnresolvedConst(vid)); - return self.tcx().const_error(c.ty); + return Ok(self.tcx().const_error(c.ty)); } ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 63eb55ed1a6..559534a7aa4 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) } } - 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>, { @@ -54,7 +54,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { u.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> { // because late-bound regions affect subtyping, we can't // erase the bound/free distinction, but we can replace // all free regions with 'erased. @@ -64,12 +64,15 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { // away. In codegen, they will always be erased to 'erased // whenever a substitution occurs. match *r { - ty::ReLateBound(..) => r, - _ => self.tcx.lifetimes.re_erased, + ty::ReLateBound(..) => Ok(r), + _ => Ok(self.tcx.lifetimes.re_erased), } } - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + fn fold_mir_const( + &mut self, + c: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 3b77b5a9d46..639606f6b89 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -301,19 +301,22 @@ where self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let t = ty.super_fold_with(self); - (self.ty_op)(t) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + let t = ty.super_fold_with(self)?; + Ok((self.ty_op)(t)) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - let r = r.super_fold_with(self); - (self.lt_op)(r) + fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + let r = r.super_fold_with(self)?; + Ok((self.lt_op)(r)) } - fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - let ct = ct.super_fold_with(self); - (self.ct_op)(ct) + fn fold_const( + &mut self, + ct: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + let ct = ct.super_fold_with(self)?; + Ok((self.ct_op)(ct)) } } @@ -481,7 +484,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -489,16 +492,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - 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(debruijn, _) if debruijn < self.current_index => { debug!(?self.current_index, "skipped bound region"); *self.skipped_regions = true; - r + Ok(r) } _ => { debug!(?self.current_index, "folding free region"); - (self.fold_region_fn)(r, self.current_index) + Ok((self.fold_region_fn)(r, self.current_index)) } } } @@ -539,19 +542,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); t } - 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::Bound(debruijn, bound_ty) if debruijn == self.current_index => { if let Some(fld_t) = self.fld_t.as_mut() { let ty = fld_t(bound_ty); - return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()); + return Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32())); } } _ if t.has_vars_bound_at_or_above(self.current_index) => { @@ -559,10 +562,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - t + Ok(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(debruijn, br) if debruijn == self.current_index => { if let Some(fld_r) = self.fld_r.as_mut() { @@ -573,25 +576,28 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { // debruijn index. Then we adjust it to the // correct depth. assert_eq!(debruijn1, ty::INNERMOST); - self.tcx.mk_region(ty::ReLateBound(debruijn, br)) + Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br))) } else { - region + Ok(region) }; } } _ => {} } - 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> { match *ct { ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } if debruijn == self.current_index => { if let Some(fld_c) = self.fld_c.as_mut() { let ct = fld_c(bound_const, ty); - return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()); + return Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())); } } _ if ct.has_vars_bound_at_or_above(self.current_index) => { @@ -599,7 +605,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - ct + Ok(ct) } } @@ -949,36 +955,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); 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(debruijn, br) => { if self.amount == 0 || debruijn < self.current_index { - r + Ok(r) } else { let debruijn = debruijn.shifted_in(self.amount); let shifted = ty::ReLateBound(debruijn, br); - self.tcx.mk_region(shifted) + Ok(self.tcx.mk_region(shifted)) } } - _ => r, + _ => Ok(r), } } - 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::Bound(debruijn, bound_ty) => { if self.amount == 0 || debruijn < self.current_index { - ty + Ok(ty) } else { let debruijn = debruijn.shifted_in(self.amount); - self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)) + Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))) } } @@ -986,13 +992,18 @@ impl TypeFolder<'tcx> for Shifter<'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> { if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct { if self.amount == 0 || debruijn < self.current_index { - ct + Ok(ct) } else { let debruijn = debruijn.shifted_in(self.amount); - self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }) + Ok(self + .tcx + .mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })) } } else { ct.super_fold_with(self) @@ -1295,19 +1306,22 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { ty.super_fold_with(self) } else { - ty + Ok(ty) } } - fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate( + &mut self, + pred: ty::Predicate<'tcx>, + ) -> Result<ty::Predicate<'tcx>, Self::Error> { if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { pred.super_fold_with(self) } else { - pred + Ok(pred) } } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 4b38105e447..23863bf389e 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -622,7 +622,7 @@ fn polymorphize<'tcx>( self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { debug!("fold_ty: ty={:?}", ty); match ty.kind { ty::Closure(def_id, substs) => { @@ -631,11 +631,11 @@ fn polymorphize<'tcx>( ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs, ); - if substs == polymorphized_substs { + Ok(if substs == polymorphized_substs { ty } else { self.tcx.mk_closure(def_id, polymorphized_substs) - } + }) } ty::Generator(def_id, substs, movability) => { let polymorphized_substs = polymorphize( @@ -643,11 +643,11 @@ fn polymorphize<'tcx>( ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs, ); - if substs == polymorphized_substs { + Ok(if substs == polymorphized_substs { ty } else { self.tcx.mk_generator(def_id, polymorphized_substs, movability) - } + }) } _ => ty.super_fold_with(self), } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 11399506b96..c5d845f9755 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -103,18 +103,24 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty() + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()) } - fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const() + fn fold_const( + &mut self, + c: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + Ok(self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()) } #[inline] - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + fn fold_mir_const( + &mut self, + c: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { // FIXME: This *probably* needs canonicalization too! let arg = self.param_env.and(c); - self.tcx.normalize_mir_const_after_erasing_regions(arg) + Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 175295b3199..13c6b4d6b01 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2016,24 +2016,24 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); t } - 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() { _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => { return t.super_fold_with(self); } _ => {} } - t + Ok(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> { let name = &mut self.name; let region = match *r { ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)), @@ -2049,13 +2049,13 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { } } } - _ => return r, + _ => return Ok(r), }; if let ty::ReLateBound(debruijn1, br) = *region { assert_eq!(debruijn1, ty::INNERMOST); - self.tcx.mk_region(ty::ReLateBound(self.current_index, br)) + Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br))) } else { - region + Ok(region) } } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a2612df5a44..ee6eed0f39b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1087,12 +1087,12 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { - ty::Unevaluated { + fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(ty::Unevaluated { def: self.def, substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), promoted: self.promoted, - } + }) } fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -1112,12 +1112,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { - ty::Unevaluated { + fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(ty::Unevaluated { def: self.def, substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), promoted: self.promoted, - } + }) } fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 67cf21a9556..419cf164db3 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -465,14 +465,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.binders_passed += 1; - let t = t.super_fold_with(self); + let t = t.super_fold_with(self)?; self.binders_passed -= 1; - t + Ok(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> { // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those // bound in *fn types*. Region substitution of the bound @@ -482,7 +482,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { ty::ReEarlyBound(data) => { let rk = self.substs.get(data.index as usize).map(|k| k.unpack()); match rk { - Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), + Some(GenericArgKind::Lifetime(lt)) => Ok(self.shift_region_through_binders(lt)), _ => { let span = self.span.unwrap_or(DUMMY_SP); let msg = format!( @@ -494,31 +494,41 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } } } - _ => r, + _ => Ok(r), } } - 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.potentially_needs_subst() { - return t; + return Ok(t); } match *t.kind() { - ty::Param(p) => self.ty_for_param(p, t), + ty::Param(p) => Ok(self.ty_for_param(p, t)), _ => t.super_fold_with(self), } } - fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + fn fold_const( + &mut self, + c: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + if !c.potentially_needs_subst() { + return Ok(c); + } + if let ty::ConstKind::Param(p) = c.val { - self.const_for_param(p, c) + Ok(self.const_for_param(p, c)) } else { c.super_fold_with(self) } } #[inline] - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + fn fold_mir_const( + &mut self, + c: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6e7acb244d1..b90123b4cee 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { self.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if let ty::Opaque(def_id, substs) = t.kind { - self.expand_opaque_ty(def_id, substs).unwrap_or(t) + Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t)) } else if t.has_opaque_types() { t.super_fold_with(self) } else { - t + Ok(t) } } } @@ -1046,25 +1046,31 @@ pub fn fold_list<'tcx, F, T>( list: &'tcx ty::List<T>, folder: &mut F, intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>, -) -> &'tcx ty::List<T> +) -> Result<&'tcx ty::List<T>, F::Error> where F: TypeFolder<'tcx>, T: TypeFoldable<'tcx> + PartialEq + Copy, { let mut iter = list.iter(); // Look for the first element that changed - if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| { - let new_t = t.fold_with(folder); - if new_t == t { None } else { Some((i, new_t)) } + match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) { + Ok(new_t) if new_t == t => None, + new_t => Some((i, new_t)), }) { - // An element changed, prepare to intern the resulting list - let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len()); - new_list.extend_from_slice(&list[..i]); - new_list.push(new_t); - new_list.extend(iter.map(|t| t.fold_with(folder))); - intern(folder.tcx(), &new_list) - } else { - list + Some((i, Ok(new_t))) => { + // An element changed, prepare to intern the resulting list + let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len()); + new_list.extend_from_slice(&list[..i]); + new_list.push(new_t); + for t in iter { + new_list.push(t.fold_with(folder)?) + } + Ok(intern(folder.tcx(), &new_list)) + } + Some((_, Err(err))) => { + return Err(err); + } + None => Ok(list), } } diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 75d57d78e3b..eb7293ae86e 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -140,17 +140,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } #[instrument(skip(self), level = "debug")] - 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 { // Ignore bound regions and `'static` regions that appear in the // type, we only need to remap regions that reference lifetimes // from the function declaraion. // This would ignore `'r` in a type like `for<'r> fn(&'r u32)`. - ty::ReLateBound(..) | ty::ReStatic => return r, + ty::ReLateBound(..) | ty::ReStatic => return Ok(r), // If regions have been erased (by writeback), don't try to unerase // them. - ty::ReErased => return r, + ty::ReErased => return Ok(r), // The regions that we expect from borrow checking. ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {} @@ -165,10 +165,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { let generics = self.tcx().generics_of(self.opaque_type_def_id); match self.map.get(&r.into()).map(|k| k.unpack()) { - Some(GenericArgKind::Lifetime(r1)) => r1, + Some(GenericArgKind::Lifetime(r1)) => Ok(r1), Some(u) => panic!("region mapped to unexpected kind: {:?}", u), None if self.map_missing_regions_to_empty || self.tainted_by_errors => { - self.tcx.lifetimes.re_root_empty + Ok(self.tcx.lifetimes.re_root_empty) } None if generics.parent.is_some() => { if let Some(hidden_ty) = self.hidden_ty.take() { @@ -180,7 +180,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); } - self.tcx.lifetimes.re_root_empty + Ok(self.tcx.lifetimes.re_root_empty) } None => { self.tcx @@ -196,12 +196,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().lifetimes.re_static + Ok(self.tcx().lifetimes.re_static) } } } - 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::Closure(def_id, substs) => { // I am a horrible monster and I pray for death. When @@ -239,7 +239,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } })); - self.tcx.mk_closure(def_id, substs) + Ok(self.tcx.mk_closure(def_id, substs)) } ty::Generator(def_id, substs, movability) => { @@ -254,7 +254,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } })); - self.tcx.mk_generator(def_id, substs, movability) + Ok(self.tcx.mk_generator(def_id, substs, movability)) } ty::Param(param) => { @@ -262,7 +262,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { match self.map.get(&ty.into()).map(|k| k.unpack()) { // Found it in the substitution list; replace with the parameter from the // opaque type. - Some(GenericArgKind::Type(t1)) => t1, + Some(GenericArgKind::Type(t1)) => Ok(t1), Some(u) => panic!("type mapped to unexpected kind: {:?}", u), None => { debug!(?param, ?self.map); @@ -278,7 +278,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().ty_error() + Ok(self.tcx().ty_error()) } } } @@ -287,10 +287,13 @@ impl TypeFolder<'tcx> for ReverseMapper<'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> { trace!("checking const {:?}", ct); // Find a const parameter - match ct.val { + Ok(match ct.val { ty::ConstKind::Param(..) => { // Look it up in the substitution list. match self.map.get(&ct.into()).map(|k| k.unpack()) { @@ -317,7 +320,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } _ => ct, - } + }) } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 54f7b91080d..7af32b2f3b1 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -860,11 +860,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { self.tcx } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - (match r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + Ok((match r { ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(), _ => None, }) - .unwrap_or_else(|| r.super_fold_with(self)) + .unwrap_or_else(|| r.super_fold_with(self).into_ok())) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f8df0e25959..1876b0ce80e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1898,15 +1898,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'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> { if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() { let infcx = self.infcx; - self.var_map.entry(ty).or_insert_with(|| { + Ok(self.var_map.entry(ty).or_insert_with(|| { infcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), span: DUMMY_SP, }) - }) + })) } else { ty.super_fold_with(self) } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b8c66931cbe..2baa21a43d6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -352,16 +352,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.universes.push(None); let t = t.super_fold_with(self); self.universes.pop(); t } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if !needs_normalization(&ty, self.param_env.reveal()) { - return ty; + return Ok(ty); } // We try to be a little clever here as a performance optimization in @@ -387,14 +387,14 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // replace bound vars if the current type is a `Projection` and we need // to make sure we don't forget to fold the substs regardless. - match *ty.kind() { + Ok(match *ty.kind() { // This is really important. While we *can* handle this, this has // severe performance implications for large opaque types with // late-bound regions. See `issue-88862` benchmark. ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { - Reveal::UserFacing => ty.super_fold_with(self), + Reveal::UserFacing => ty.super_fold_with(self)?, Reveal::All => { let recursion_limit = self.tcx().recursion_limit(); @@ -408,11 +408,11 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { self.selcx.infcx().report_overflow_error(&obligation, true); } - let substs = substs.super_fold_with(self); + let substs = substs.super_fold_with(self)?; let generic_ty = self.tcx().type_of(def_id); let concrete_ty = generic_ty.subst(self.tcx(), substs); self.depth += 1; - let folded_ty = self.fold_ty(concrete_ty); + let folded_ty = self.fold_ty(concrete_ty)?; self.depth -= 1; folded_ty } @@ -426,7 +426,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // register an obligation to *later* project, since we know // there won't be bound vars there. - let data = data.super_fold_with(self); + let data = data.super_fold_with(self)?; let normalized_ty = normalize_projection_type( self.selcx, self.param_env, @@ -461,7 +461,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let infcx = self.selcx.infcx(); let (data, mapped_regions, mapped_types, mapped_consts) = BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - let data = data.super_fold_with(self); + let data = data.super_fold_with(self)?; let normalized_ty = opt_normalize_projection_type( self.selcx, self.param_env, @@ -473,16 +473,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { .ok() .flatten() .map(|normalized_ty| { - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - normalized_ty, - ) + Ok({ + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + normalized_ty, + ) + }) }) - .unwrap_or_else(|| ty.super_fold_with(self)); + .unwrap_or_else(|| ty.super_fold_with(self))?; debug!( ?self.depth, @@ -494,16 +496,19 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { normalized_ty } - _ => ty.super_fold_with(self), - } + _ => ty.super_fold_with(self)?, + }) } - fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + fn fold_const( + &mut self, + constant: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { if self.selcx.tcx().lazy_normalization() { - constant + Ok(constant) } else { - let constant = constant.super_fold_with(self); - constant.eval(self.selcx.tcx(), self.param_env) + let constant = constant.super_fold_with(self)?; + Ok(constant.eval(self.selcx.tcx(), self.param_env)) } } } @@ -577,14 +582,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); 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(debruijn, _) if debruijn.as_usize() + 1 @@ -596,13 +601,13 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderRegion { universe, name: br.kind }; self.mapped_regions.insert(p, br); - self.infcx.tcx.mk_region(ty::RePlaceholder(p)) + Ok(self.infcx.tcx.mk_region(ty::RePlaceholder(p))) } - _ => r, + _ => Ok(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::Bound(debruijn, _) if debruijn.as_usize() + 1 @@ -614,14 +619,17 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderType { universe, name: bound_ty.var }; self.mapped_types.insert(p, bound_ty); - self.infcx.tcx.mk_ty(ty::Placeholder(p)) + Ok(self.infcx.tcx.mk_ty(ty::Placeholder(p))) } _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self), - _ => 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 { ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ } if debruijn.as_usize() + 1 @@ -638,10 +646,10 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { name: ty::BoundConst { var: bound_const, ty }, }; self.mapped_consts.insert(p, bound_const); - self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty }) + Ok(self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })) } _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self), - _ => ct, + _ => Ok(ct), } } } @@ -685,9 +693,9 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { if !t.has_placeholders() && !t.has_infer_regions() { - return t; + return Ok(t); } self.current_index.shift_in(1); let t = t.super_fold_with(self); @@ -695,7 +703,7 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { t } - fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> { + fn fold_region(&mut self, r0: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { let r1 = match r0 { ty::ReVar(_) => self .infcx @@ -729,10 +737,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { debug!(?r0, ?r1, ?r2, "fold_region"); - r2 + Ok(r2) } - 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::Placeholder(p) => { let replace_var = self.mapped_types.get(&p); @@ -746,18 +754,21 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_ty(ty::Bound(db, *replace_var)) + Ok(self.tcx().mk_ty(ty::Bound(db, *replace_var))) } - None => ty, + None => Ok(ty), } } _ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self), - _ => ty, + _ => Ok(ty), } } - 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::Placeholder(p), ty } = *ct { let replace_var = self.mapped_consts.get(&p); match replace_var { @@ -770,10 +781,11 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx() - .mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty }) + Ok(self + .tcx() + .mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })) } - None => ct, + None => Ok(ct), } } else { ct.super_fold_with(self) diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 1364cf1c995..f3a90935a9f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -184,7 +184,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { + ) -> Result<ty::Binder<'tcx, T>, Self::Error> { self.universes.push(None); let t = t.super_fold_with(self); self.universes.pop(); @@ -192,13 +192,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } #[instrument(level = "debug", skip(self))] - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if !needs_normalization(&ty, self.param_env.reveal()) { - return ty; + return Ok(ty); } if let Some(ty) = self.cache.get(&ty) { - return ty; + return Ok(ty); } // See note in `rustc_trait_selection::traits::project` about why we @@ -215,7 +215,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { Reveal::UserFacing => ty.super_fold_with(self), Reveal::All => { - let substs = substs.super_fold_with(self); + let substs = substs.super_fold_with(self)?; let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.anon_depth) { let obligation = Obligation::with_depth( @@ -252,7 +252,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // we don't need to replace them with placeholders (see branch below). let tcx = self.infcx.tcx; - let data = data.super_fold_with(self); + let data = data.super_fold_with(self)?; let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, @@ -280,7 +280,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); - result.normalized_ty + Ok(result.normalized_ty) } Err(_) => { @@ -308,7 +308,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { &mut self.universes, data, ); - let data = data.super_fold_with(self); + let data = data.super_fold_with(self)?; let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, @@ -335,14 +335,14 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); - crate::traits::project::PlaceholderReplacer::replace_placeholders( + Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( infcx, mapped_regions, mapped_types, mapped_consts, &self.universes, result.normalized_ty, - ) + )) } Err(_) => { self.error = true; @@ -358,17 +358,23 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } _ => ty.super_fold_with(self), - })(); + })()?; self.cache.insert(ty, res); - res + Ok(res) } - fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - let constant = constant.super_fold_with(self); - constant.eval(self.infcx.tcx, self.param_env) + fn fold_const( + &mut self, + constant: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + let constant = constant.super_fold_with(self)?; + Ok(constant.eval(self.infcx.tcx, self.param_env)) } - fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + fn fold_mir_const( + &mut self, + constant: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { constant.super_fold_with(self) } } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index e24f699adf6..033a9465842 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -943,20 +943,23 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder<T: TypeFoldable<'tcx>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Result<Binder<'tcx, T>, Self::Error> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); result } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> { match r { ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { Some(idx) => { let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) }; - return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)); + return Ok(self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br))); } None => panic!("Missing `BrNamed`."), }, @@ -999,32 +1002,35 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder<T: TypeFoldable<'tcx>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Result<Binder<'tcx, T>, Self::Error> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); result } - 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() { // FIXME(chalk): currently we convert params to placeholders starting at // index `0`. To support placeholders, we'll actually need to do a // first pass to collect placeholders. Then we can insert params after. ty::Placeholder(_) => unimplemented!(), ty::Param(param) => match self.list.iter().position(|r| r == ¶m) { - Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + Some(idx) => Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), name: ty::BoundVar::from_usize(idx), - })), + }))), None => { self.list.push(param); let idx = self.list.len() - 1 + self.next_ty_placeholder; self.params.insert(idx, param); - self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), name: ty::BoundVar::from_usize(idx), - })) + }))) } }, @@ -1032,7 +1038,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { } } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> { match r { // FIXME(chalk) - jackh726 - this currently isn't hit in any tests. // This covers any region variables in a goal, right? @@ -1042,14 +1048,14 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { var: ty::BoundVar::from_u32(*idx), kind: ty::BrAnon(*idx), }; - self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) + Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))) } None => { let idx = self.named_regions.len() as u32; let br = ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) }; self.named_regions.insert(_re.def_id, idx); - self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) + Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))) } }, @@ -1125,11 +1131,11 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> { self.tcx } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> { match r { ty::ReEmpty(ui) => { assert_eq!(ui.as_usize(), 0); - self.reempty_placeholder + Ok(self.reempty_placeholder) } _ => r.super_fold_with(self), diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index f83209f57a8..8f852c0b51c 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -1015,12 +1015,12 @@ impl TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> { self.0.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::Param(_) => self.0.next_ty_var(TypeVariableOrigin { + ty::Param(_) => Ok(self.0.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: self.1, - }), + })), _ => ty.super_fold_with(self), } } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index fdc8b6b5e64..ecf0332db7b 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -749,15 +749,15 @@ impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) { ty.super_fold_with(self) } else { - ty + Ok(ty) } } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased } + fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + Ok(if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased }) } } @@ -766,7 +766,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { self.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { match self.infcx.fully_resolve(t) { Ok(t) => { // Do not anonymize late-bound regions @@ -779,18 +779,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); self.report_type_error(t); self.replaced_with_error = true; - self.tcx().ty_error() + Ok(self.tcx().ty_error()) } } } - 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> { debug_assert!(!r.is_late_bound(), "Should not be resolving bound region."); - self.tcx.lifetimes.re_erased + Ok(self.tcx.lifetimes.re_erased) } - fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - match self.infcx.fully_resolve(ct) { + fn fold_const( + &mut self, + ct: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + Ok(match self.infcx.fully_resolve(ct) { Ok(ct) => self.infcx.tcx.erase_regions(ct), Err(_) => { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); @@ -798,7 +801,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { self.replaced_with_error = true; self.tcx().const_error(ct.ty) } - } + }) } } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 04a68250ced..1dce63416dc 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -729,17 +729,17 @@ fn infer_placeholder_type<'a>( self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { if !self.success { - return ty; + return Ok(ty); } match ty.kind() { - ty::FnDef(def_id, _) => self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id)), + ty::FnDef(def_id, _) => Ok(self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id))), // FIXME: non-capturing closures should also suggest a function pointer ty::Closure(..) | ty::Generator(..) => { self.success = false; - ty + Ok(ty) } _ => ty.super_fold_with(self), } diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs index a49eda6572d..5c229c86ddc 100644 --- a/compiler/rustc_typeck/src/hir_wf_check.rs +++ b/compiler/rustc_typeck/src/hir_wf_check.rs @@ -183,7 +183,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { - if let ty::ReLateBound(..) = r { &ty::ReErased } else { r } + fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> { + if let ty::ReLateBound(..) = r { Ok(&ty::ReErased) } else { Ok(r) } } } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 2ccf17387d1..3a6f611660e 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -714,11 +714,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { self.tcx } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - (match *r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + Ok((match *r { ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), _ => None, }) - .unwrap_or_else(|| r.super_fold_with(self)) + .unwrap_or_else(|| r.super_fold_with(self).into_ok())) } } |
