diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 0d36466f6e3e7..f308e764e861d 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -23,7 +23,6 @@ Rust MIR: a lowered representation of Rust. #![feature(trusted_len)] #![feature(trusted_step)] #![feature(try_blocks)] -#![feature(unwrap_infallible)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index c86c8f81dbd96..b4bb6390db486 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -94,8 +94,7 @@ pub fn equal_up_to_regions( // Leave consts and types unchanged. ct_op: |ct| ct, ty_op: |ty| ty, - }) - .into_ok(), + }), ) }; tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok()) diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs index 920f7b1ed0a54..9e1497961d9ea 100644 --- a/compiler/rustc_data_structures/src/functor.rs +++ b/compiler/rustc_data_structures/src/functor.rs @@ -4,14 +4,6 @@ use std::mem; pub trait IdFunctor: Sized { type Inner; - #[inline] - fn map_id(self, mut f: F) -> Self - where - F: FnMut(Self::Inner) -> Self::Inner, - { - self.try_map_id::<_, !>(|value| Ok(f(value))).into_ok() - } - fn try_map_id(self, f: F) -> Result where F: FnMut(Self::Inner) -> Result; diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index d4eb622e780ce..77784bf170523 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -25,7 +25,6 @@ #![feature(once_cell)] #![feature(test)] #![feature(thread_id_value)] -#![feature(unwrap_infallible)] #![allow(rustc::default_hash_types)] #![deny(unaligned_references)] diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 27e73738b7f35..934ada9932e71 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(&mut self, t: ty::Binder<'tcx, T>) -> Result, Self::Error> + fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(index, ..) => { if index >= self.binder_index { bug!("escaping late-bound region during canonicalization"); } else { - Ok(r) + 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)); - Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r)) + 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 => Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r)), + | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), } } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { 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; - Ok(self.canonicalize_ty_var( + self.canonicalize_ty_var( CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)), }, t, - )) + ) } } } - ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var( + ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var( CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) }, t, - )), + ), - ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var( + ty::Infer(ty::FloatVar(_)) => 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) => Ok(self.canonicalize_ty_var( + ty::Placeholder(placeholder) => 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 { - Ok(t) + t } } @@ -403,16 +403,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { if t.flags().intersects(self.needs_canonical_flags) { t.super_fold_with(self) } else { - Ok(t) + t } } } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { match ct.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { debug!("canonical: const var found with vid {:?}", vid); @@ -427,10 +424,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { Err(mut ui) => { // FIXME: perf problem described in #55921. ui = ty::UniverseIndex::ROOT; - return Ok(self.canonicalize_const_var( + return self.canonicalize_const_var( CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) }, ct, - )); + ); } } } @@ -441,20 +438,20 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { if debruijn >= self.binder_index { bug!("escaping bound type during canonicalization") } else { - return Ok(ct); + return ct; } } ty::ConstKind::Placeholder(placeholder) => { - return Ok(self.canonicalize_const_var( + return 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 { Ok(ct) } + if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { ct } } } @@ -503,7 +500,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { indices: FxHashMap::default(), binder_index: ty::INNERMOST, }; - let out_value = value.fold_with(&mut canonicalizer).into_ok(); + let out_value = value.fold_with(&mut canonicalizer); // Once we have canonicalized `out_value`, it should not // contain anything that ties it to this inference context @@ -621,7 +618,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { let infcx = self.infcx; let bound_to = infcx.shallow_resolve(ty_var); if bound_to != ty_var { - self.fold_ty(bound_to).into_ok() + self.fold_ty(bound_to) } else { let var = self.canonical_var(info, ty_var.into()); self.tcx().mk_ty(ty::Bound(self.binder_index, var.into())) @@ -640,12 +637,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { let infcx = self.infcx; let bound_to = infcx.shallow_resolve(const_var); if bound_to != const_var { - self.fold_const(bound_to).into_ok() + self.fold_const(bound_to) } else { let var = self.canonical_var(info, const_var.into()); self.tcx().mk_const(ty::Const { val: ty::ConstKind::Bound(self.binder_index, var), - ty: self.fold_ty(const_var.ty).into_ok(), + ty: self.fold_ty(const_var.ty), }) } } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 7599e98167fb5..c40e409891bc2 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { F: FnOnce(u32) -> ty::InferTy, { if let Some(ty) = opt_ty { - return ty.fold_with(self).into_ok(); + return ty.fold_with(self); } match self.ty_freshen_map.entry(key) { @@ -98,7 +98,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { F: FnOnce(u32) -> ty::InferConst<'tcx>, { if let Some(ct) = opt_ct { - return ct.fold_with(self).into_ok(); + return ct.fold_with(self); } match self.const_freshen_map.entry(key) { @@ -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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(..) => { // leave bound regions alone - Ok(r) + 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 - Ok(self.tcx().lifetimes.re_erased) + self.tcx().lifetimes.re_erased } ty::ReStatic => { if self.keep_static { - Ok(r) + r } else { - Ok(self.tcx().lifetimes.re_erased) + self.tcx().lifetimes.re_erased } } } } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) { - return Ok(t); + return 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(); - Ok(self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)) + self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy) } - ty::Infer(ty::IntVar(v)) => Ok(self.freshen_ty( + ty::Infer(ty::IntVar(v)) => 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)) => Ok(self.freshen_ty( + ty::Infer(ty::FloatVar(v)) => 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 ); } - Ok(t) + t } ty::Generator(..) @@ -221,10 +221,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { match ct.val { ty::ConstKind::Infer(ty::InferConst::Var(v)) => { let opt_ct = self @@ -235,12 +232,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { .probe_value(v) .val .known(); - return Ok(self.freshen_const( + return 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 { @@ -251,7 +248,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { self.const_freshen_count, ); } - return Ok(ct); + return 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 4e6f1315d1024..773753a036326 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -161,7 +161,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { Ok(value) } else { - Ok(value.fold_with(&mut fudger).into_ok()) + Ok(value.fold_with(&mut fudger)) } } } @@ -180,7 +180,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { self.infcx.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { 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]; - Ok(self.infcx.next_ty_var(origin)) + self.infcx.next_ty_var(origin) } else { // This variable was created before the // "fudging". Since we refresh all type @@ -198,43 +198,48 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { debug_assert!( self.infcx.inner.borrow_mut().type_variables().probe(vid).is_unknown() ); - Ok(ty) + ty } } ty::Infer(ty::InferTy::IntVar(vid)) => { - Ok(if self.int_vars.contains(&vid) { self.infcx.next_int_var() } else { ty }) + if self.int_vars.contains(&vid) { + self.infcx.next_int_var() + } else { + ty + } } ty::Infer(ty::InferTy::FloatVar(vid)) => { - Ok(if self.float_vars.contains(&vid) { self.infcx.next_float_var() } else { ty }) + 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { 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 Ok(self.infcx.next_region_var(origin)); + return self.infcx.next_region_var(origin); } } - Ok(r) + r } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { 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]; - Ok(self.infcx.next_const_var(ty, origin)) + self.infcx.next_const_var(ty, origin) } else { - Ok(ct) + 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 4a9a63e1c7602..2fd01c2d595fa 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -681,7 +681,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn freshen>(&self, t: T) -> T { - t.fold_with(&mut self.freshener()).into_ok() + t.fold_with(&mut self.freshener()) } /// Returns the origin of the type variable identified by `vid`, or `None` @@ -1381,7 +1381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { where T: TypeFoldable<'tcx>, { - value.fold_with(&mut ShallowResolver { infcx: self }).into_ok() + value.fold_with(&mut ShallowResolver { infcx: self }) } pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { @@ -1402,7 +1402,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return value; // Avoid duplicated subst-folding. } let mut r = resolve::OpportunisticVarResolver::new(self); - value.fold_with(&mut r).into_ok() + value.fold_with(&mut r) } /// Returns the first unresolved variable contained in `T`. In the @@ -1745,15 +1745,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { self.infcx.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - Ok(self.infcx.shallow_resolve_ty(ty)) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.infcx.shallow_resolve_ty(ty) } - 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 { + 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 { self.infcx .inner .borrow_mut() @@ -1764,7 +1761,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { .unwrap_or(ct) } else { ct - }) + } } } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 7893abbfc9bf7..89c14bcc2ce2b 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -418,94 +418,91 @@ struct Instantiator<'a, 'tcx> { impl<'a, 'tcx> Instantiator<'a, 'tcx> { fn instantiate_opaque_types_in_map>(&mut self, value: T) -> T { let tcx = self.infcx.tcx; - value - .fold_with(&mut BottomUpFolder { - tcx, - ty_op: |ty| { - if ty.references_error() { - return tcx.ty_error(); - } else if let ty::Opaque(def_id, substs) = ty.kind() { - // Check that this is `impl Trait` type is - // declared by `parent_def_id` -- i.e., one whose - // value we are inferring. At present, this is - // always true during the first phase of - // type-check, but not always true later on during - // NLL. Once we support named opaque types more fully, - // this same scenario will be able to arise during all phases. - // - // Here is an example using type alias `impl Trait` - // that indicates the distinction we are checking for: - // - // ```rust - // mod a { - // pub type Foo = impl Iterator; - // pub fn make_foo() -> Foo { .. } - // } - // - // mod b { - // fn foo() -> a::Foo { a::make_foo() } - // } - // ``` - // - // Here, the return type of `foo` references an - // `Opaque` indeed, but not one whose value is - // presently being inferred. You can get into a - // similar situation with closure return types - // today: - // - // ```rust - // fn foo() -> impl Iterator { .. } - // fn bar() { - // let x = || foo(); // returns the Opaque assoc with `foo` - // } - // ``` - if let Some(def_id) = def_id.as_local() { - let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let parent_def_id = self.infcx.defining_use_anchor; - let def_scope_default = || { - let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); - parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id) - }; - let (in_definition_scope, origin) = - match tcx.hir().expect_item(def_id).kind { - // Anonymous `impl Trait` - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: Some(parent), - origin, - .. - }) => (parent == parent_def_id.to_def_id(), origin), - // Named `type Foo = impl Bar;` - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: None, - origin, - .. - }) => ( - may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), - origin, - ), - _ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias), - }; - if in_definition_scope { - let opaque_type_key = - OpaqueTypeKey { def_id: def_id.to_def_id(), substs }; - return self.fold_opaque_ty(ty, opaque_type_key, origin); + value.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| { + if ty.references_error() { + return tcx.ty_error(); + } else if let ty::Opaque(def_id, substs) = ty.kind() { + // Check that this is `impl Trait` type is + // declared by `parent_def_id` -- i.e., one whose + // value we are inferring. At present, this is + // always true during the first phase of + // type-check, but not always true later on during + // NLL. Once we support named opaque types more fully, + // this same scenario will be able to arise during all phases. + // + // Here is an example using type alias `impl Trait` + // that indicates the distinction we are checking for: + // + // ```rust + // mod a { + // pub type Foo = impl Iterator; + // pub fn make_foo() -> Foo { .. } + // } + // + // mod b { + // fn foo() -> a::Foo { a::make_foo() } + // } + // ``` + // + // Here, the return type of `foo` references an + // `Opaque` indeed, but not one whose value is + // presently being inferred. You can get into a + // similar situation with closure return types + // today: + // + // ```rust + // fn foo() -> impl Iterator { .. } + // fn bar() { + // let x = || foo(); // returns the Opaque assoc with `foo` + // } + // ``` + if let Some(def_id) = def_id.as_local() { + let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let parent_def_id = self.infcx.defining_use_anchor; + let def_scope_default = || { + let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); + parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id) + }; + let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind + { + // Anonymous `impl Trait` + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + impl_trait_fn: Some(parent), + origin, + .. + }) => (parent == parent_def_id.to_def_id(), origin), + // Named `type Foo = impl Bar;` + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + impl_trait_fn: None, + origin, + .. + }) => { + (may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin) } + _ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias), + }; + if in_definition_scope { + let opaque_type_key = + OpaqueTypeKey { def_id: def_id.to_def_id(), substs }; + return self.fold_opaque_ty(ty, opaque_type_key, origin); + } - debug!( - "instantiate_opaque_types_in_map: \ + debug!( + "instantiate_opaque_types_in_map: \ encountered opaque outside its definition scope \ def_id={:?}", - def_id, - ); - } + def_id, + ); } + } - ty - }, - lt_op: |lt| lt, - ct_op: |ct| ct, - }) - .into_ok() + ty + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }) } #[instrument(skip(self), level = "debug")] @@ -558,23 +555,21 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { debug!(?predicate); // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them. - let predicate = predicate - .fold_with(&mut BottomUpFolder { - tcx, - ty_op: |ty| match ty.kind() { - ty::Projection(projection_ty) => infcx.infer_projection( - self.param_env, - *projection_ty, - traits::ObligationCause::misc(self.value_span, self.body_id), - 0, - &mut self.obligations, - ), - _ => ty, - }, - lt_op: |lt| lt, - ct_op: |ct| ct, - }) - .into_ok(); + let predicate = predicate.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| match ty.kind() { + ty::Projection(projection_ty) => infcx.infer_projection( + self.param_env, + *projection_ty, + traits::ObligationCause::misc(self.value_span, self.body_id), + 0, + &mut self.obligations, + ), + _ => ty, + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }); debug!(?predicate); if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index cccdfb7452a77..f036e1214aaf7 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,7 +1,7 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{FixupError, FixupResult, InferCtxt, Span}; use rustc_middle::mir; -use rustc_middle::ty::fold::{TypeFolder, TypeVisitor}; +use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeVisitor}; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; use std::ops::ControlFlow; @@ -30,28 +30,25 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { self.infcx.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.has_infer_types_or_consts() { - Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... + 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>) -> Result<&'tcx Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> { if !ct.has_infer_types_or_consts() { - Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects... + 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>, - ) -> Result, Self::Error> { + fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { constant.super_fold_with(self) } } @@ -78,16 +75,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { self.infcx.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.has_infer_regions() { - Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... + 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>) -> Result, Self::Error> { - Ok(match *r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + match *r { ty::ReVar(rid) => { let resolved = self .infcx @@ -98,15 +95,12 @@ 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>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if !ct.has_infer_regions() { - Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects... + ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { ct.super_fold_with(self) } @@ -181,7 +175,7 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu where T: TypeFoldable<'tcx>, { - value.fold_with(&mut FullTypeResolver { infcx }) + value.try_fold_with(&mut FullTypeResolver { infcx }) } // N.B. This type is not public because the protocol around checking the @@ -196,8 +190,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } +} - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { +impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { + fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { if !t.needs_infer() { Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects... } else { @@ -209,12 +205,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { ty::Infer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); } - _ => t.super_fold_with(self), + _ => t.try_super_fold_with(self), } } } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { match *r { ty::ReVar(rid) => Ok(self .infcx @@ -227,7 +223,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { } } - fn fold_const( + fn try_fold_const( &mut self, c: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { @@ -244,7 +240,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { } _ => {} } - c.super_fold_with(self) + c.try_super_fold_with(self) } } } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 5153427954ccc..e4b407e7c112d 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -24,7 +24,6 @@ #![feature(control_flow_enum)] #![feature(min_specialization)] #![feature(label_break_value)] -#![feature(unwrap_infallible)] #![recursion_limit = "512"] // For rustdoc #[macro_use] diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 544b89397790a..20453eeb1474e 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -1,7 +1,7 @@ use crate::traits; use crate::traits::project::Normalized; use rustc_middle::ty; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use std::fmt; use std::ops::ControlFlow; @@ -60,12 +60,15 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { // TypeFoldable implementations. impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(traits::Obligation { cause: self.cause, recursion_depth: self.recursion_depth, - predicate: self.predicate.fold_with(folder)?, - param_env: self.param_env.fold_with(folder)?, + predicate: self.predicate.try_fold_with(folder)?, + param_env: self.param_env.try_fold_with(folder)?, }) } diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index 769f009b49206..9f448a593da50 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -17,7 +17,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: vi.construct(|_, index| { let bind = &bindings[index]; quote! { - ::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)? + ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)? } }) }); @@ -25,7 +25,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: s.bound_impl( quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>), quote! { - fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>( + fn try_super_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>( self, __folder: &mut __F ) -> Result { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index c0cf265b22879..4e927f00acd5e 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -52,7 +52,7 @@ macro_rules! TrivialTypeFoldableImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { - fn super_fold_with>( + fn try_super_fold_with>( self, _: &mut F ) -> ::std::result::Result<$ty, F::Error> { @@ -95,7 +95,7 @@ macro_rules! EnumTypeFoldableImpl { impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s $(where $($wc)*)* { - fn super_fold_with>( + fn try_super_fold_with>( self, folder: &mut V, ) -> ::std::result::Result { @@ -126,7 +126,7 @@ macro_rules! EnumTypeFoldableImpl { output( $variant ( $($variant_arg),* ) => { $variant ( - $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)?),* + $($crate::ty::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),* ) } $($output)* diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a05b8a1da8d7f..e67aa75c10033 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -7,7 +7,7 @@ use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::adjustment::PointerCast; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, List, Ty, TyCtxt}; @@ -2760,10 +2760,13 @@ impl UserTypeProjection { TrivialTypeFoldableAndLiftImpls! { ProjectionKind, } impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(UserTypeProjection { - base: self.base.fold_with(folder)?, - projs: self.projs.fold_with(folder)?, + base: self.base.try_fold_with(folder)?, + projs: self.projs.try_fold_with(folder)?, }) } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index df7c6d9cf6650..ad8b9d323eed5 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -16,39 +16,42 @@ TrivialTypeFoldableAndLiftImpls! { } impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::mir::TerminatorKind::*; let kind = match self.kind { Goto { target } => Goto { target }, SwitchInt { discr, switch_ty, targets } => SwitchInt { - discr: discr.fold_with(folder)?, - switch_ty: switch_ty.fold_with(folder)?, + discr: discr.try_fold_with(folder)?, + switch_ty: switch_ty.try_fold_with(folder)?, targets, }, Drop { place, target, unwind } => { - Drop { place: place.fold_with(folder)?, target, unwind } + Drop { place: place.try_fold_with(folder)?, target, unwind } } DropAndReplace { place, value, target, unwind } => DropAndReplace { - place: place.fold_with(folder)?, - value: value.fold_with(folder)?, + place: place.try_fold_with(folder)?, + value: value.try_fold_with(folder)?, target, unwind, }, Yield { value, resume, resume_arg, drop } => Yield { - value: value.fold_with(folder)?, + value: value.try_fold_with(folder)?, resume, - resume_arg: resume_arg.fold_with(folder)?, + resume_arg: resume_arg.try_fold_with(folder)?, drop, }, Call { func, args, destination, cleanup, from_hir_call, fn_span } => { let dest = destination - .map(|(loc, dest)| (loc.fold_with(folder).map(|loc| (loc, dest)))) + .map(|(loc, dest)| (loc.try_fold_with(folder).map(|loc| (loc, dest)))) .transpose()?; Call { - func: func.fold_with(folder)?, - args: args.fold_with(folder)?, + func: func.try_fold_with(folder)?, + args: args.try_fold_with(folder)?, destination: dest, cleanup, from_hir_call, @@ -58,16 +61,19 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { Assert { cond, expected, msg, target, cleanup } => { use AssertKind::*; let msg = match msg { - BoundsCheck { len, index } => { - BoundsCheck { len: len.fold_with(folder)?, index: index.fold_with(folder)? } + BoundsCheck { len, index } => BoundsCheck { + len: len.try_fold_with(folder)?, + index: index.try_fold_with(folder)?, + }, + Overflow(op, l, r) => { + Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?) } - Overflow(op, l, r) => Overflow(op, l.fold_with(folder)?, r.fold_with(folder)?), - OverflowNeg(op) => OverflowNeg(op.fold_with(folder)?), - DivisionByZero(op) => DivisionByZero(op.fold_with(folder)?), - RemainderByZero(op) => RemainderByZero(op.fold_with(folder)?), + OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?), + DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?), + RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?), ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg, }; - Assert { cond: cond.fold_with(folder)?, expected, msg, target, cleanup } + Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup } } GeneratorDrop => GeneratorDrop, Resume => Resume, @@ -80,7 +86,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind }, InlineAsm { template, operands, options, line_spans, destination } => InlineAsm { template, - operands: operands.fold_with(folder)?, + operands: operands.try_fold_with(folder)?, options, line_spans, destination, @@ -142,7 +148,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { - fn super_fold_with>(self, _: &mut F) -> Result { + fn try_super_fold_with>(self, _: &mut F) -> Result { Ok(self) } @@ -152,10 +158,13 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { } impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(Place { - local: self.local.fold_with(folder)?, - projection: self.projection.fold_with(folder)?, + local: self.local.try_fold_with(folder)?, + projection: self.projection.try_fold_with(folder)?, }) } @@ -166,7 +175,10 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } @@ -176,48 +188,56 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::mir::Rvalue::*; Ok(match self { - Use(op) => Use(op.fold_with(folder)?), - Repeat(op, len) => Repeat(op.fold_with(folder)?, len.fold_with(folder)?), - ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)?), - Ref(region, bk, place) => Ref(region.fold_with(folder)?, bk, place.fold_with(folder)?), - AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)?), - Len(place) => Len(place.fold_with(folder)?), - Cast(kind, op, ty) => Cast(kind, op.fold_with(folder)?, ty.fold_with(folder)?), - BinaryOp(op, box (rhs, lhs)) => { - BinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?))) + Use(op) => Use(op.try_fold_with(folder)?), + Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?), + ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?), + Ref(region, bk, place) => { + Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?) } - CheckedBinaryOp(op, box (rhs, lhs)) => { - CheckedBinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?))) + AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?), + Len(place) => Len(place.try_fold_with(folder)?), + Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?), + BinaryOp(op, box (rhs, lhs)) => { + BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?))) } - UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)?), - Discriminant(place) => Discriminant(place.fold_with(folder)?), - NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)?), + CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp( + op, + Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)), + ), + UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?), + Discriminant(place) => Discriminant(place.try_fold_with(folder)?), + NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?), Aggregate(kind, fields) => { let kind = kind.try_map_id(|kind| { Ok(match kind { - AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)?), + AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?), AggregateKind::Tuple => AggregateKind::Tuple, AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt( def, v, - substs.fold_with(folder)?, - user_ty.fold_with(folder)?, + substs.try_fold_with(folder)?, + user_ty.try_fold_with(folder)?, n, ), AggregateKind::Closure(id, substs) => { - AggregateKind::Closure(id, substs.fold_with(folder)?) + AggregateKind::Closure(id, substs.try_fold_with(folder)?) } AggregateKind::Generator(id, substs, movablity) => { - AggregateKind::Generator(id, substs.fold_with(folder)?, movablity) + AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity) } }) })?; - Aggregate(kind, fields.fold_with(folder)?) + Aggregate(kind, fields.try_fold_with(folder)?) + } + ShallowInitBox(op, ty) => { + ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?) } - ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder)?, ty.fold_with(folder)?), }) } @@ -272,11 +292,14 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(match self { - Operand::Copy(place) => Operand::Copy(place.fold_with(folder)?), - Operand::Move(place) => Operand::Move(place.fold_with(folder)?), - Operand::Constant(c) => Operand::Constant(c.fold_with(folder)?), + Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?), + Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?), + Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?), }) } @@ -289,13 +312,16 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::mir::ProjectionElem::*; Ok(match self { Deref => Deref, - Field(f, ty) => Field(f, ty.fold_with(folder)?), - Index(v) => Index(v.fold_with(folder)?), + Field(f, ty) => Field(f, ty.try_fold_with(folder)?), + Index(v) => Index(v.try_fold_with(folder)?), Downcast(symbol, variantidx) => Downcast(symbol, variantidx), ConstantIndex { offset, min_length, from_end } => { ConstantIndex { offset, min_length, from_end } @@ -319,7 +345,7 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Field { - fn super_fold_with>(self, _: &mut F) -> Result { + fn try_super_fold_with>(self, _: &mut F) -> Result { Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { @@ -328,7 +354,7 @@ impl<'tcx> TypeFoldable<'tcx> for Field { } impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { - fn super_fold_with>(self, _: &mut F) -> Result { + fn try_super_fold_with>(self, _: &mut F) -> Result { Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { @@ -337,7 +363,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { } impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { - fn super_fold_with>(self, _: &mut F) -> Result { + fn try_super_fold_with>(self, _: &mut F) -> Result { Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { @@ -346,11 +372,14 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { } impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(Constant { span: self.span, - user_ty: self.user_ty.fold_with(folder)?, - literal: self.literal.fold_with(folder)?, + user_ty: self.user_ty.try_fold_with(folder)?, + literal: self.literal.try_fold_with(folder)?, }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -361,14 +390,17 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { #[inline(always)] - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_mir_const(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_mir_const(self) } - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { match self { - ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.fold_with(folder)?)), - ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.fold_with(folder)?)), + ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), + ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), } } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 25b460cf16d3c..63eb55ed1a620 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -9,7 +9,7 @@ pub(super) fn provide(providers: &mut ty::query::Providers) { fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { // N.B., use `super_fold_with` here. If we used `fold_with`, it // could invoke the `erase_regions_ty` query recursively. - ty.super_fold_with(&mut RegionEraserVisitor { tcx }).into_ok() + ty.super_fold_with(&mut RegionEraserVisitor { tcx }) } impl<'tcx> TyCtxt<'tcx> { @@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> { return value; } debug!("erase_regions({:?})", value); - let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }).into_ok(); + let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); debug!("erase_regions = {:?}", value1); value1 } @@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) } + 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_binder(&mut self, t: ty::Binder<'tcx, T>) -> Result, Self::Error> + fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // because late-bound regions affect subtyping, we can't // erase the bound/free distinction, but we can replace // all free regions with 'erased. @@ -64,15 +64,12 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { // away. In codegen, they will always be erased to 'erased // whenever a substitution occurs. match *r { - ty::ReLateBound(..) => Ok(r), - _ => Ok(self.tcx.lifetimes.re_erased), + ty::ReLateBound(..) => r, + _ => self.tcx.lifetimes.re_erased, } } - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 31055c03a5d36..aff485a413226 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -46,9 +46,30 @@ use std::ops::ControlFlow; /// /// To implement this conveniently, use the derive macro located in `rustc_macros`. pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { - fn super_fold_with>(self, folder: &mut F) -> Result; - fn fold_with>(self, folder: &mut F) -> Result { - self.super_fold_with(folder) + /// Consumers may find this more convenient to use with infallible folders than + /// [`try_super_fold_with`][`TypeFoldable::try_super_fold_with`], to which the + /// provided default definition delegates. Implementors **should not** override + /// this provided default definition, to ensure that the two methods are coherent + /// (provide a definition of `try_super_fold_with` instead). + fn super_fold_with>(self, folder: &mut F) -> Self { + self.try_super_fold_with(folder).into_ok() + } + /// Consumers may find this more convenient to use with infallible folders than + /// [`try_fold_with`][`TypeFoldable::try_fold_with`], to which the provided + /// default definition delegates. Implementors **should not** override this + /// provided default definition, to ensure that the two methods are coherent + /// (provide a definition of `try_fold_with` instead). + fn fold_with>(self, folder: &mut F) -> Self { + self.try_fold_with(folder).into_ok() + } + + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result; + + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_super_fold_with(folder) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow; @@ -179,7 +200,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } impl TypeFoldable<'tcx> for hir::Constness { - fn super_fold_with>(self, _: &mut F) -> Result { + fn try_super_fold_with>(self, _: &mut F) -> Result { Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { @@ -192,41 +213,102 @@ impl TypeFoldable<'tcx> for hir::Constness { /// default implementation that does an "identity" fold. Within each /// identity fold, it should invoke `foo.fold_with(self)` to fold each /// sub-item. +/// +/// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`] +/// associated type is something other than the default, never), +/// [`FallibleTypeFolder`] should be implemented manually; otherwise, +/// a blanket implementation of [`FallibleTypeFolder`] will defer to +/// the infallible methods of this trait to ensure that the two APIs +/// are coherent. pub trait TypeFolder<'tcx>: Sized { type Error = !; fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; - fn fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, Self::Error> + fn fold_binder(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> where T: TypeFoldable<'tcx>, + Self: TypeFolder<'tcx, Error = !>, { t.super_fold_with(self) } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { t.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { r.super_fold_with(self) } - fn fold_const( + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + c.super_fold_with(self) + } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + p.super_fold_with(self) + } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + bug!("most type folders should not be folding MIR datastructures: {:?}", c) + } +} + +/// The `FallibleTypeFolder` trait defines the actual *folding*. There is a +/// method defined for every foldable type. Each of these has a +/// default implementation that does an "identity" fold. Within each +/// identity fold, it should invoke `foo.try_fold_with(self)` to fold each +/// sub-item. +/// +/// A blanket implementation of this trait (that defers to the relevant +/// method of [`TypeFolder`]) is provided for all infallible folders in +/// order to ensure the two APIs are coherent. +pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> { + fn try_fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, Self::Error> + where + T: TypeFoldable<'tcx>, + { + t.try_super_fold_with(self) + } + + fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + t.try_super_fold_with(self) + } + + fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + r.try_super_fold_with(self) + } + + fn try_fold_const( &mut self, c: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - c.super_fold_with(self) + c.try_super_fold_with(self) } - fn fold_predicate( + fn try_fold_predicate( &mut self, p: ty::Predicate<'tcx>, ) -> Result, Self::Error> { - p.super_fold_with(self) + p.try_super_fold_with(self) } - fn fold_mir_const( + fn try_fold_mir_const( &mut self, c: mir::ConstantKind<'tcx>, ) -> Result, Self::Error> { @@ -234,6 +316,49 @@ pub trait TypeFolder<'tcx>: Sized { } } +// Blanket implementation of fallible trait for infallible folders +// delegates to infallible methods to prevent incoherence +impl<'tcx, F> FallibleTypeFolder<'tcx> for F +where + F: TypeFolder<'tcx, Error = !>, +{ + fn try_fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, Self::Error> + where + T: TypeFoldable<'tcx>, + { + Ok(self.fold_binder(t)) + } + + fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + Ok(self.fold_ty(t)) + } + + fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + Ok(self.fold_region(r)) + } + + fn try_fold_const( + &mut self, + c: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + Ok(self.fold_const(c)) + } + + fn try_fold_predicate( + &mut self, + p: ty::Predicate<'tcx>, + ) -> Result, Self::Error> { + Ok(self.fold_predicate(p)) + } + + fn try_fold_mir_const( + &mut self, + c: mir::ConstantKind<'tcx>, + ) -> Result, Self::Error> { + Ok(self.fold_mir_const(c)) + } +} + pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; /// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs @@ -301,22 +426,19 @@ where self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - let t = ty.super_fold_with(self)?; - Ok((self.ty_op)(t)) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + let t = ty.super_fold_with(self); + (self.ty_op)(t) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { - let r = r.super_fold_with(self)?; - Ok((self.lt_op)(r)) + 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_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)) + 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) } } @@ -336,7 +458,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)).into_ok() + value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) } /// Invoke `callback` on every region appearing free in `value`. @@ -484,7 +606,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -492,16 +614,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, _) if debruijn < self.current_index => { debug!(?self.current_index, "skipped bound region"); *self.skipped_regions = true; - Ok(r) + r } _ => { debug!(?self.current_index, "folding free region"); - Ok((self.fold_region_fn)(r, self.current_index)) + (self.fold_region_fn)(r, self.current_index) } } } @@ -542,19 +664,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { 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 Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32())); + return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()); } } _ if t.has_vars_bound_at_or_above(self.current_index) => { @@ -562,10 +684,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, br) if debruijn == self.current_index => { if let Some(fld_r) = self.fld_r.as_mut() { @@ -576,28 +698,25 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { // debruijn index. Then we adjust it to the // correct depth. assert_eq!(debruijn1, ty::INNERMOST); - Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br))) + self.tcx.mk_region(ty::ReLateBound(debruijn, br)) } else { - Ok(region) + region }; } } _ => {} } - Ok(r) + r } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { 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 Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())); + return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()); } } _ if ct.has_vars_bound_at_or_above(self.current_index) => { @@ -605,7 +724,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - Ok(ct) + ct } } @@ -638,7 +757,7 @@ impl<'tcx> TyCtxt<'tcx> { value } else { let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None); - value.fold_with(&mut replacer).into_ok() + value.fold_with(&mut replacer) }; (value, region_map) } @@ -664,7 +783,7 @@ impl<'tcx> TyCtxt<'tcx> { } else { let mut replacer = BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c)); - value.fold_with(&mut replacer).into_ok() + value.fold_with(&mut replacer) } } @@ -955,36 +1074,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, br) => { if self.amount == 0 || debruijn < self.current_index { - Ok(r) + r } else { let debruijn = debruijn.shifted_in(self.amount); let shifted = ty::ReLateBound(debruijn, br); - Ok(self.tcx.mk_region(shifted)) + self.tcx.mk_region(shifted) } } - _ => Ok(r), + _ => r, } } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match *ty.kind() { ty::Bound(debruijn, bound_ty) => { if self.amount == 0 || debruijn < self.current_index { - Ok(ty) + ty } else { let debruijn = debruijn.shifted_in(self.amount); - Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))) + self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)) } } @@ -992,18 +1111,13 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct { if self.amount == 0 || debruijn < self.current_index { - Ok(ct) + ct } else { let debruijn = debruijn.shifted_in(self.amount); - Ok(self - .tcx - .mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })) + self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }) } } else { ct.super_fold_with(self) @@ -1030,7 +1144,7 @@ where { debug!("shift_vars(value={:?}, amount={})", value, amount); - value.fold_with(&mut Shifter::new(tcx, amount)).into_ok() + value.fold_with(&mut Shifter::new(tcx, amount)) } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -1293,7 +1407,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// FIXME(@lcnr): explain this function a bit more pub fn expose_default_const_substs>(self, v: T) -> T { - v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }).into_ok() + v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }) } } @@ -1306,22 +1420,19 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { ty.super_fold_with(self) } else { - Ok(ty) + ty } } - fn fold_predicate( - &mut self, - pred: ty::Predicate<'tcx>, - ) -> Result, Self::Error> { + fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { pred.super_fold_with(self) } else { - Ok(pred) + pred } } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 15931b8d2c86a..4b38105e44717 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { 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, ); - Ok(if substs == polymorphized_substs { + 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, ); - Ok(if substs == polymorphized_substs { + if substs == polymorphized_substs { ty } else { self.tcx.mk_generator(def_id, polymorphized_substs, movability) - }) + } } _ => ty.super_fold_with(self), } @@ -669,7 +669,7 @@ fn polymorphize<'tcx>( // ..and polymorphize any closures/generators captured as upvars. let upvars_ty = upvars_ty.unwrap(); let polymorphized_upvars_ty = upvars_ty.fold_with( - &mut PolymorphizationFolder { tcx }).into_ok(); + &mut PolymorphizationFolder { tcx }); debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty); ty::GenericArg::from(polymorphized_upvars_ty) }, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cd60519ac3424..584303413fb87 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -9,7 +9,7 @@ //! //! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html -pub use self::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -1269,14 +1269,14 @@ impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { - fn super_fold_with>( + fn try_super_fold_with>( self, folder: &mut F, ) -> Result { Ok(ParamEnv::new( - self.caller_bounds().fold_with(folder)?, - self.reveal().fold_with(folder)?, - self.constness().fold_with(folder)?, + self.caller_bounds().try_fold_with(folder)?, + self.reveal().try_fold_with(folder)?, + self.constness().try_fold_with(folder)?, )) } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index fce7cbfbb3d1e..c0e1360640fd2 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -9,7 +9,7 @@ use crate::mir; use crate::traits::query::NoSolution; -use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; @@ -55,9 +55,7 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_projections() { value } else { - value - .fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) - .into_ok() + value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) } } @@ -90,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> { Ok(value) } else { let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env); - value.fold_with(&mut folder) + value.try_fold_with(&mut folder) } } @@ -161,25 +159,19 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty() } - 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()) + 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() } #[inline] - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { // FIXME: This *probably* needs canonicalization too! let arg = self.param_env.and(c); - Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg)) + self.tcx.normalize_mir_const_after_erasing_regions(arg) } } @@ -211,15 +203,17 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } +} - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { +impl FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { + fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { match self.try_normalize_generic_arg_after_erasing_regions(ty.into()) { Ok(t) => Ok(t.expect_ty()), Err(_) => Err(NormalizationError::Type(ty)), } } - fn fold_const( + fn try_fold_const( &mut self, c: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { @@ -229,7 +223,7 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { } } - fn fold_mir_const( + fn try_fold_mir_const( &mut self, c: mir::ConstantKind<'tcx>, ) -> Result, Self::Error> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f454b95862bab..175295b3199e8 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>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => { return t.super_fold_with(self); } _ => {} } - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { 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 Ok(r), + _ => return r, }; if let ty::ReLateBound(debruijn1, br) = *region { assert_eq!(debruijn1, ty::INNERMOST); - Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br))) + self.tcx.mk_region(ty::ReLateBound(self.current_index, br)) } else { - Ok(region) + region } } } @@ -2193,7 +2193,7 @@ impl FmtPrinter<'_, 'tcx, F> { name: &mut name, region_map: BTreeMap::new(), }; - let new_value = value.clone().skip_binder().fold_with(&mut folder).into_ok(); + let new_value = value.clone().skip_binder().fold_with(&mut folder); let region_map = folder.region_map; start_or_continue(&mut self, "", "> "); (new_value, region_map) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index f637412a11744..30ed008a5deeb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -4,7 +4,7 @@ use crate::mir::interpret; use crate::mir::ProjectionKind; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::{self, InferConst, Lift, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; @@ -669,7 +669,10 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { /// AdtDefs are basically the same as a DefId. impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { - fn super_fold_with>(self, _folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } @@ -679,8 +682,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { } impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { - fn super_fold_with>(self, folder: &mut F) -> Result<(T, U), F::Error> { - Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result<(T, U), F::Error> { + Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -692,8 +698,15 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (A, B, C) { - fn super_fold_with>(self, folder: &mut F) -> Result<(A, B, C), F::Error> { - Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?, self.2.fold_with(folder)?)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result<(A, B, C), F::Error> { + Ok(( + self.0.try_fold_with(folder)?, + self.1.try_fold_with(folder)?, + self.2.try_fold_with(folder)?, + )) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -718,9 +731,12 @@ EnumTypeFoldableImpl! { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { // FIXME: Reuse the `Rc` here. - Ok(Rc::new((*self).clone().fold_with(folder)?)) + (*self).clone().try_fold_with(folder).map(Rc::new) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -729,9 +745,12 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { // FIXME: Reuse the `Arc` here. - Ok(Arc::new((*self).clone().fold_with(folder)?)) + (*self).clone().try_fold_with(folder).map(Arc::new) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -740,8 +759,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { - fn super_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|value| value.fold_with(folder)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_id(|value| value.try_fold_with(folder)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -750,8 +772,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { - fn super_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|t| t.fold_with(folder)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_id(|t| t.try_fold_with(folder)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -760,8 +785,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { - fn super_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|t| t.fold_with(folder)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_id(|t| t.try_fold_with(folder)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -770,12 +798,15 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { - fn super_fold_with>(self, folder: &mut F) -> Result { - self.try_map_bound(|ty| ty.fold_with(folder)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_bound(|ty| ty.try_fold_with(folder)) } - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_binder(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_binder(self) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -788,7 +819,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List>> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } @@ -798,7 +832,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List TypeFoldable<'tcx> for &'tcx ty::List> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)) } @@ -808,7 +845,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } @@ -818,22 +858,31 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { } impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::ty::InstanceDef::*; Ok(Self { - substs: self.substs.fold_with(folder)?, + substs: self.substs.try_fold_with(folder)?, def: match self.def { - Item(def) => Item(def.fold_with(folder)?), - VtableShim(did) => VtableShim(did.fold_with(folder)?), - ReifyShim(did) => ReifyShim(did.fold_with(folder)?), - Intrinsic(did) => Intrinsic(did.fold_with(folder)?), - FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder)?, ty.fold_with(folder)?), - Virtual(did, i) => Virtual(did.fold_with(folder)?, i), + Item(def) => Item(def.try_fold_with(folder)?), + VtableShim(did) => VtableShim(did.try_fold_with(folder)?), + ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?), + Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?), + FnPtrShim(did, ty) => { + FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i), ClosureOnceShim { call_once, track_caller } => { - ClosureOnceShim { call_once: call_once.fold_with(folder)?, track_caller } + ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller } + } + DropGlue(did, ty) => { + DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + CloneShim(did, ty) => { + CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) } - DropGlue(did, ty) => DropGlue(did.fold_with(folder)?, ty.fold_with(folder)?), - CloneShim(did, ty) => CloneShim(did.fold_with(folder)?, ty.fold_with(folder)?), }, }) } @@ -860,8 +909,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { - Ok(Self { instance: self.instance.fold_with(folder)?, promoted: self.promoted }) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -870,26 +922,31 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { let kind = match *self.kind() { - ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)?), - ty::Array(typ, sz) => ty::Array(typ.fold_with(folder)?, sz.fold_with(folder)?), - ty::Slice(typ) => ty::Slice(typ.fold_with(folder)?), - ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)?), + ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?), + ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?), + ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?), + ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?), ty::Dynamic(trait_ty, region) => { - ty::Dynamic(trait_ty.fold_with(folder)?, region.fold_with(folder)?) + ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?) + } + ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?), + ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?), + ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?), + ty::Ref(r, ty, mutbl) => { + ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) } - ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)?), - ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)?), - ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)?), - ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder)?, ty.fold_with(folder)?, mutbl), ty::Generator(did, substs, movability) => { - ty::Generator(did, substs.fold_with(folder)?, movability) + ty::Generator(did, substs.try_fold_with(folder)?, movability) } - ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)?), - ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)?), - ty::Projection(data) => ty::Projection(data.fold_with(folder)?), - ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)?), + ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?), + ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?), + ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?), + ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?), ty::Bool | ty::Char @@ -909,8 +966,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) } - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_ty(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_ty(self) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -961,12 +1018,15 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { - fn super_fold_with>(self, _folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_region(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_region(self) } fn super_visit_with>(&self, _visitor: &mut V) -> ControlFlow { @@ -979,12 +1039,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_predicate(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_predicate(self) } - fn super_fold_with>(self, folder: &mut F) -> Result { - let new = self.inner.kind.fold_with(folder)?; + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + let new = self.inner.kind.try_fold_with(folder)?; Ok(folder.tcx().reuse_or_mk_predicate(self, new)) } @@ -1006,7 +1069,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) } @@ -1016,8 +1082,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec { - fn super_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|x| x.fold_with(folder)) + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_id(|x| x.try_fold_with(folder)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -1026,9 +1095,12 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { - let ty = self.ty.fold_with(folder)?; - let val = self.val.fold_with(folder)?; + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + let ty = self.ty.try_fold_with(folder)?; + let val = self.val.try_fold_with(folder)?; if ty != self.ty || val != self.val { Ok(folder.tcx().mk_const(ty::Const { ty, val })) } else { @@ -1036,8 +1108,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { } } - fn fold_with>(self, folder: &mut F) -> Result { - folder.fold_const(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_const(self) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -1051,11 +1123,14 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(match self { - ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)?), - ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)?), - ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)?), + ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), + ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), + ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1077,7 +1152,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { - fn super_fold_with>(self, _folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } @@ -1087,10 +1165,13 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(ty::Unevaluated { def: self.def, - substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), + substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), promoted: self.promoted, }) } @@ -1112,10 +1193,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { Ok(ty::Unevaluated { def: self.def, - substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), + substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), promoted: self.promoted, }) } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index ffa495ce4803f..8fddafaf6206a 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -2,7 +2,7 @@ use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; @@ -153,11 +153,14 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { match self.unpack() { - GenericArgKind::Lifetime(lt) => lt.fold_with(folder).map(Into::into), - GenericArgKind::Type(ty) => ty.fold_with(folder).map(Into::into), - GenericArgKind::Const(ct) => ct.fold_with(folder).map(Into::into), + GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), + GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), + GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), } } @@ -372,7 +375,10 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Result { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // The match arms are in order of frequency. The 1, 2, and 0 cases are @@ -381,12 +387,12 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { // calling `intern_substs`. match self.len() { 1 => { - let param0 = self[0].fold_with(folder)?; + let param0 = self[0].try_fold_with(folder)?; if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) } } 2 => { - let param0 = self[0].fold_with(folder)?; - let param1 = self[1].fold_with(folder)?; + let param0 = self[0].try_fold_with(folder)?; + let param1 = self[1].try_fold_with(folder)?; if param0 == self[0] && param1 == self[1] { Ok(self) } else { @@ -396,7 +402,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { 0 => Ok(self), _ => { let params: SmallVec<[_; 8]> = - self.iter().map(|k| k.fold_with(folder)).collect::>()?; + self.iter().map(|k| k.try_fold_with(folder)).collect::>()?; if params[..] == self[..] { Ok(self) } else { @@ -439,7 +445,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { span: Option, ) -> T { let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 }; - self.fold_with(&mut folder).into_ok() + self.fold_with(&mut folder) } } @@ -465,14 +471,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.binders_passed += 1; - let t = t.super_fold_with(self)?; + let t = t.super_fold_with(self); self.binders_passed -= 1; - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // 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 +488,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)) => Ok(self.shift_region_through_binders(lt)), + Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), _ => { let span = self.span.unwrap_or(DUMMY_SP); let msg = format!( @@ -494,37 +500,31 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } } } - _ => Ok(r), + _ => r, } } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.potentially_needs_subst() { - return Ok(t); + return t; } match *t.kind() { - ty::Param(p) => Ok(self.ty_for_param(p, t)), + ty::Param(p) => self.ty_for_param(p, t), _ => t.super_fold_with(self), } } - fn fold_const( - &mut self, - c: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::ConstKind::Param(p) = c.val { - Ok(self.const_for_param(p, c)) + self.const_for_param(p, c) } else { c.super_fold_with(self) } } #[inline] - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 5137f9650633a..25eb56456e15f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1,7 +1,7 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::ty::fold::TypeFolder; +use crate::ty::fold::{FallibleTypeFolder, TypeFolder}; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; @@ -574,14 +574,14 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { if self.found_any_recursion { return None; } - let substs = substs.fold_with(self).into_ok(); + let substs = substs.fold_with(self); if !self.check_recursion || self.seen_opaque_tys.insert(def_id) { let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { Some(expanded_ty) => expanded_ty, None => { let generic_ty = self.tcx.type_of(def_id); let concrete_ty = generic_ty.subst(self.tcx, substs); - let expanded_ty = self.fold_ty(concrete_ty).into_ok(); + let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, substs), expanded_ty); expanded_ty } @@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { self.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Opaque(def_id, substs) = t.kind { - Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t)) + self.expand_opaque_ty(def_id, substs).unwrap_or(t) } else if t.has_opaque_types() { t.super_fold_with(self) } else { - Ok(t) + t } } } @@ -1048,12 +1048,12 @@ pub fn fold_list<'tcx, F, T>( intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List, ) -> Result<&'tcx ty::List, F::Error> where - F: TypeFolder<'tcx>, + F: FallibleTypeFolder<'tcx>, T: TypeFoldable<'tcx> + PartialEq + Copy, { let mut iter = list.iter(); // Look for the first element that changed - match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) { + match iter.by_ref().enumerate().find_map(|(i, t)| match t.try_fold_with(folder) { Ok(new_t) if new_t == t => None, new_t => Some((i, new_t)), }) { @@ -1063,7 +1063,7 @@ where new_list.extend_from_slice(&list[..i]); new_list.push(new_t); for t in iter { - new_list.push(t.fold_with(folder)?) + new_list.push(t.try_fold_with(folder)?) } Ok(intern(folder.tcx(), &new_list)) } @@ -1092,7 +1092,7 @@ pub fn normalize_opaque_types( check_recursion: false, tcx, }; - val.fold_with(&mut visitor).into_ok() + val.fold_with(&mut visitor) } pub fn provide(providers: &mut ty::query::Providers) { diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index ecc352c1a49b5..1820e33b19bf4 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -22,7 +22,6 @@ #![feature(never_type)] #![feature(crate_visibility_modifier)] #![feature(control_flow_enum)] -#![feature(unwrap_infallible)] #![recursion_limit = "512"] // For rustdoc #[macro_use] diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 9052dff0aaa83..75d57d78e3b02 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -65,16 +65,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = instantiated_ty - .fold_with(&mut ReverseMapper::new( - self.tcx, - self.is_tainted_by_errors(), - def_id, - map, - instantiated_ty, - span, - )) - .into_ok(); + let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new( + self.tcx, + self.is_tainted_by_errors(), + def_id, + map, + instantiated_ty, + span, + )); debug!(?definition_ty); definition_ty @@ -125,14 +123,14 @@ impl ReverseMapper<'tcx> { ) -> GenericArg<'tcx> { assert!(!self.map_missing_regions_to_empty); self.map_missing_regions_to_empty = true; - let kind = kind.fold_with(self).into_ok(); + let kind = kind.fold_with(self); self.map_missing_regions_to_empty = false; kind } fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> { assert!(!self.map_missing_regions_to_empty); - kind.fold_with(self).into_ok() + kind.fold_with(self) } } @@ -142,17 +140,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } #[instrument(skip(self), level = "debug")] - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { 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 Ok(r), + ty::ReLateBound(..) | ty::ReStatic => return r, // If regions have been erased (by writeback), don't try to unerase // them. - ty::ReErased => return Ok(r), + ty::ReErased => return r, // The regions that we expect from borrow checking. ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {} @@ -167,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)) => Ok(r1), + Some(GenericArgKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), None if self.map_missing_regions_to_empty || self.tainted_by_errors => { - Ok(self.tcx.lifetimes.re_root_empty) + self.tcx.lifetimes.re_root_empty } None if generics.parent.is_some() => { if let Some(hidden_ty) = self.hidden_ty.take() { @@ -182,7 +180,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); } - Ok(self.tcx.lifetimes.re_root_empty) + self.tcx.lifetimes.re_root_empty } None => { self.tcx @@ -198,12 +196,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - Ok(self.tcx().lifetimes.re_static) + self.tcx().lifetimes.re_static } } } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match *ty.kind() { ty::Closure(def_id, substs) => { // I am a horrible monster and I pray for death. When @@ -241,7 +239,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } })); - Ok(self.tcx.mk_closure(def_id, substs)) + self.tcx.mk_closure(def_id, substs) } ty::Generator(def_id, substs, movability) => { @@ -256,7 +254,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } })); - Ok(self.tcx.mk_generator(def_id, substs, movability)) + self.tcx.mk_generator(def_id, substs, movability) } ty::Param(param) => { @@ -264,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)) => Ok(t1), + Some(GenericArgKind::Type(t1)) => t1, Some(u) => panic!("type mapped to unexpected kind: {:?}", u), None => { debug!(?param, ?self.map); @@ -280,7 +278,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - Ok(self.tcx().ty_error()) + self.tcx().ty_error() } } } @@ -289,13 +287,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { trace!("checking const {:?}", ct); // Find a const parameter - Ok(match ct.val { + match ct.val { ty::ConstKind::Param(..) => { // Look it up in the substitution list. match self.map.get(&ct.into()).map(|k| k.unpack()) { @@ -322,7 +317,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 74de49e8fa4c3..3642aebaec2fb 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -865,11 +865,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { self.tcx } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { - Ok((match r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + (match r { ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(), _ => None, }) - .unwrap_or_else(|| r.super_fold_with(self).into_ok())) + .unwrap_or_else(|| r.super_fold_with(self)) } } 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 72bb9a55c6983..ed56d4c28273f 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() { let infcx = self.infcx; - Ok(self.var_map.entry(ty).or_insert_with(|| { + 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) } @@ -1916,9 +1916,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { self.probe(|_| { let mut selcx = SelectionContext::new(self); - let cleaned_pred = pred - .fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }) - .into_ok(); + let cleaned_pred = + pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); let cleaned_pred = super::project::normalize( &mut selcx, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 26398bfd81000..79ed665681951 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -339,7 +339,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { if !needs_normalization(&value, self.param_env.reveal()) { value } else { - value.fold_with(self).into_ok() + value.fold_with(self) } } } @@ -352,16 +352,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.universes.push(None); let t = t.super_fold_with(self); self.universes.pop(); t } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if !needs_normalization(&ty, self.param_env.reveal()) { - return Ok(ty); + return 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. - Ok(match *ty.kind() { + 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,18 +473,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { .ok() .flatten() .map(|normalized_ty| { - Ok({ - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - normalized_ty, - ) - }) + 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, @@ -496,19 +494,16 @@ 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>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if self.selcx.tcx().lazy_normalization() { - Ok(constant) + constant } else { - let constant = constant.super_fold_with(self)?; - Ok(constant.eval(self.selcx.tcx(), self.param_env)) + let constant = constant.super_fold_with(self); + constant.eval(self.selcx.tcx(), self.param_env) } } } @@ -555,7 +550,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { universe_indices, }; - let value = value.super_fold_with(&mut replacer).into_ok(); + let value = value.super_fold_with(&mut replacer); (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts) } @@ -582,14 +577,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, _) if debruijn.as_usize() + 1 @@ -601,13 +596,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); - Ok(self.infcx.tcx.mk_region(ty::RePlaceholder(p))) + self.infcx.tcx.mk_region(ty::RePlaceholder(p)) } - _ => Ok(r), + _ => r, } } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { ty::Bound(debruijn, _) if debruijn.as_usize() + 1 @@ -619,17 +614,14 @@ 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); - Ok(self.infcx.tcx.mk_ty(ty::Placeholder(p))) + self.infcx.tcx.mk_ty(ty::Placeholder(p)) } _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self), - _ => Ok(t), + _ => t, } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { match *ct { ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ } if debruijn.as_usize() + 1 @@ -646,10 +638,10 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { name: ty::BoundConst { var: bound_const, ty }, }; self.mapped_consts.insert(p, bound_const); - Ok(self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })) + 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), - _ => Ok(ct), + _ => ct, } } } @@ -681,7 +673,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { universe_indices, current_index: ty::INNERMOST, }; - value.super_fold_with(&mut replacer).into_ok() + value.super_fold_with(&mut replacer) } } @@ -693,9 +685,9 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { fn fold_binder>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result, Self::Error> { + ) -> ty::Binder<'tcx, T> { if !t.has_placeholders() && !t.has_infer_regions() { - return Ok(t); + return t; } self.current_index.shift_in(1); let t = t.super_fold_with(self); @@ -703,7 +695,7 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { t } - fn fold_region(&mut self, r0: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> { let r1 = match r0 { ty::ReVar(_) => self .infcx @@ -737,10 +729,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { debug!(?r0, ?r1, ?r2, "fold_region"); - Ok(r2) + r2 } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match *ty.kind() { ty::Placeholder(p) => { let replace_var = self.mapped_types.get(&p); @@ -754,21 +746,18 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - Ok(self.tcx().mk_ty(ty::Bound(db, *replace_var))) + self.tcx().mk_ty(ty::Bound(db, *replace_var)) } - None => Ok(ty), + None => ty, } } _ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self), - _ => Ok(ty), + _ => ty, } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct { let replace_var = self.mapped_consts.get(&p); match replace_var { @@ -781,11 +770,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - Ok(self - .tcx() - .mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })) + self.tcx() + .mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty }) } - None => Ok(ct), + None => ct, } } else { ct.super_fold_with(self) @@ -1546,8 +1534,7 @@ fn confirm_candidate<'cx, 'tcx>( // when possible for this to work. See `auto-trait-projection-recursion.rs` // for a case where this matters. if progress.ty.has_infer_regions() { - progress.ty = - OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty).into_ok(); + progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty); } progress } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index af507feffba5b..26bacf787e2eb 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; use rustc_middle::mir; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; +use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; @@ -87,7 +87,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { normalizer.universes.extend((0..max_visitor.escaping).map(|_| None)); } } - let result = value.fold_with(&mut normalizer); + let result = value.try_fold_with(&mut normalizer); info!( "normalize::<{}>: result={:?} with {} obligations", std::any::type_name::(), @@ -176,19 +176,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { self.infcx.tcx } +} - fn fold_binder>( +impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { + fn try_fold_binder>( &mut self, t: ty::Binder<'tcx, T>, ) -> Result, Self::Error> { self.universes.push(None); - let t = t.super_fold_with(self); + let t = t.try_super_fold_with(self); self.universes.pop(); t } #[instrument(level = "debug", skip(self))] - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { if !needs_normalization(&ty, self.param_env.reveal()) { return Ok(ty); } @@ -208,10 +210,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { 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.try_super_fold_with(self), Reveal::All => { - let substs = substs.super_fold_with(self)?; + let substs = substs.try_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( @@ -236,7 +238,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { ty ); } - let folded_ty = ensure_sufficient_stack(|| self.fold_ty(concrete_ty)); + let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty)); self.anon_depth -= 1; folded_ty } @@ -248,7 +250,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.try_super_fold_with(self)?; let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, @@ -287,7 +289,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { &mut self.universes, data, ); - let data = data.super_fold_with(self)?; + let data = data.try_super_fold_with(self)?; let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, @@ -322,24 +324,24 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { )) } - _ => ty.super_fold_with(self), + _ => ty.try_super_fold_with(self), })()?; self.cache.insert(ty, res); Ok(res) } - fn fold_const( + fn try_fold_const( &mut self, constant: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - let constant = constant.super_fold_with(self)?; + let constant = constant.try_super_fold_with(self)?; Ok(constant.eval(self.infcx.tcx, self.param_env)) } - fn fold_mir_const( + fn try_fold_mir_const( &mut self, constant: mir::ConstantKind<'tcx>, ) -> Result, Self::Error> { - constant.super_fold_with(self) + constant.try_super_fold_with(self) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index dd62411cb8e50..57f90d4827584 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2154,7 +2154,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &'o TraitObligation<'tcx>, ) -> TraitObligationStack<'o, 'tcx> { - let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener).into_ok(); + let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener); let dfn = previous_stack.cache.next_dfn(); let depth = previous_stack.depth() + 1; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index fdff07302c240..1d457d6761fd0 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -45,7 +45,7 @@ impl<'tcx> RustIrDatabase<'tcx> { predicates .iter() .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) - .map(|wc| wc.fold_with(&mut regions_substitutor).into_ok()) + .map(|wc| wc.fold_with(&mut regions_substitutor)) .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect() } @@ -287,7 +287,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); let mut regions_substitutor = lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); - let trait_ref = trait_ref.fold_with(&mut regions_substitutor).into_ok(); + let trait_ref = trait_ref.fold_with(&mut regions_substitutor); let where_clauses = self.where_clauses_for(def_id, bound_vars); @@ -335,7 +335,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let self_ty = self_ty.subst(self.interner.tcx, bound_vars); let mut regions_substitutor = lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); - let self_ty = self_ty.fold_with(&mut regions_substitutor).into_ok(); + let self_ty = self_ty.fold_with(&mut regions_substitutor); let lowered_ty = self_ty.lower_into(&self.interner); parameters[0].assert_ty_ref(&self.interner).could_match( @@ -501,24 +501,22 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .iter() .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) .map(|bound| { - bound - .fold_with(&mut ty::fold::BottomUpFolder { - tcx: self.interner.tcx, - ty_op: |ty| { - if let ty::Opaque(def_id, substs) = *ty.kind() { - if def_id == opaque_ty_id.0 && substs == identity_substs { - return self.interner.tcx.mk_ty(ty::Bound( - ty::INNERMOST, - ty::BoundTy::from(ty::BoundVar::from_u32(0)), - )); - } + bound.fold_with(&mut ty::fold::BottomUpFolder { + tcx: self.interner.tcx, + ty_op: |ty| { + if let ty::Opaque(def_id, substs) = *ty.kind() { + if def_id == opaque_ty_id.0 && substs == identity_substs { + return self.interner.tcx.mk_ty(ty::Bound( + ty::INNERMOST, + ty::BoundTy::from(ty::BoundVar::from_u32(0)), + )); } - ty - }, - lt_op: |lt| lt, - ct_op: |ct| ct, - }) - .into_ok() + } + ty + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }) }) .filter_map(|bound| { LowerInto::< diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 66073facf4b0c..e24f699adf6b3 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -817,7 +817,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( .collect(); let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters); - let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor).into_ok(); + let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor); for var in named_parameters.values() { parameters.insert(*var, chalk_ir::VariableKind::Lifetime); @@ -943,23 +943,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { self.tcx } - fn fold_binder>( - &mut self, - t: Binder<'tcx, T>, - ) -> Result, Self::Error> { + fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { 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 Ok(self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br))); + return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)); } None => panic!("Missing `BrNamed`."), }, @@ -1002,35 +999,32 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { self.tcx } - fn fold_binder>( - &mut self, - t: Binder<'tcx, T>, - ) -> Result, Self::Error> { + fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { 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) => Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + Some(idx) => 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); - Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), name: ty::BoundVar::from_usize(idx), - }))) + })) } }, @@ -1038,7 +1032,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { } } - fn fold_region(&mut self, r: Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { // FIXME(chalk) - jackh726 - this currently isn't hit in any tests. // This covers any region variables in a goal, right? @@ -1048,14 +1042,14 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { var: ty::BoundVar::from_u32(*idx), kind: ty::BrAnon(*idx), }; - Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))) + 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); - Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))) + self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) } }, @@ -1131,11 +1125,11 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> { self.tcx } - fn fold_region(&mut self, r: Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { ty::ReEmpty(ui) => { assert_eq!(ui.as_usize(), 0); - Ok(self.reempty_placeholder) + self.reempty_placeholder } _ => r.super_fold_with(self), diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index a6f7c4d7988f6..b7275bac19048 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -49,12 +49,12 @@ crate fn evaluate_goal<'tcx>( let mut params_substitutor = ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); - let obligation = obligation.fold_with(&mut params_substitutor).into_ok(); + let obligation = obligation.fold_with(&mut params_substitutor); // FIXME(chalk): we really should be substituting these back in the solution let _params: FxHashMap = params_substitutor.params; let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder); - let obligation = obligation.fold_with(&mut regions_substitutor).into_ok(); + let obligation = obligation.fold_with(&mut regions_substitutor); let max_universe = obligation.max_universe.index(); diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index ea70a8d9e3a0d..8612499623be6 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -4,7 +4,6 @@ #![feature(crate_visibility_modifier)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(unwrap_infallible)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 1c4e0522bef8f..f83209f57a897 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -442,8 +442,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut eraser = TypeParamEraser(self, expr.span); let needs_bound = self .lookup_op_method( - eraser.fold_ty(lhs_ty).into_ok(), - &[eraser.fold_ty(rhs_ty).into_ok()], + eraser.fold_ty(lhs_ty), + &[eraser.fold_ty(rhs_ty)], Op::Binary(op, is_assign), ) .is_ok(); @@ -1015,12 +1015,12 @@ impl TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> { self.0.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match ty.kind() { - ty::Param(_) => Ok(self.0.next_ty_var(TypeVariableOrigin { + ty::Param(_) => 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 a5965411020a4..fdc8b6b5e6451 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -658,7 +658,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { T: TypeFoldable<'tcx>, { let mut resolver = Resolver::new(self.fcx, span, self.body); - let x = x.fold_with(&mut resolver).into_ok(); + let x = x.fold_with(&mut resolver); if cfg!(debug_assertions) && x.needs_infer() { span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x); } @@ -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>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) { ty.super_fold_with(self) } else { - Ok(ty) + ty } } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { - Ok(if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased }) + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match self.infcx.fully_resolve(t) { Ok(t) => { // Do not anonymize late-bound regions @@ -779,21 +779,18 @@ 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; - Ok(self.tcx().ty_error()) + self.tcx().ty_error() } } } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { debug_assert!(!r.is_late_bound(), "Should not be resolving bound region."); - Ok(self.tcx.lifetimes.re_erased) + self.tcx.lifetimes.re_erased } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - Ok(match self.infcx.fully_resolve(ct) { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + 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); @@ -801,7 +798,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 1ea379c57389a..04a68250ced0c 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>) -> Result, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if !self.success { - return Ok(ty); + return ty; } match ty.kind() { - ty::FnDef(def_id, _) => Ok(self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id))), + ty::FnDef(def_id, _) => 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; - Ok(ty) + ty } _ => ty.super_fold_with(self), } @@ -761,7 +761,7 @@ fn infer_placeholder_type<'a>( // Suggesting unnameable types won't help. let mut mk_nameable = MakeNameable::new(tcx); - let ty = mk_nameable.fold_ty(ty).into_ok(); + let ty = mk_nameable.fold_ty(ty); let sugg_ty = if mk_nameable.success { Some(ty) } else { None }; if let Some(sugg_ty) = sugg_ty { err.span_suggestion( @@ -785,7 +785,7 @@ fn infer_placeholder_type<'a>( if !ty.references_error() { let mut mk_nameable = MakeNameable::new(tcx); - let ty = mk_nameable.fold_ty(ty).into_ok(); + let ty = mk_nameable.fold_ty(ty); let sugg_ty = if mk_nameable.success { Some(ty) } else { None }; if let Some(sugg_ty) = sugg_ty { diag.span_suggestion( diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs index f9de6376b0ff5..a49eda6572de2 100644 --- a/compiler/rustc_typeck/src/hir_wf_check.rs +++ b/compiler/rustc_typeck/src/hir_wf_check.rs @@ -71,11 +71,8 @@ fn diagnostic_hir_wf_check<'tcx>( fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { self.tcx.infer_ctxt().enter(|infcx| { let mut fulfill = traits::FulfillmentContext::new(); - let tcx_ty = self - .icx - .to_ty(ty) - .fold_with(&mut EraseAllBoundRegions { tcx: self.tcx }) - .into_ok(); + let tcx_ty = + self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx }); let cause = traits::ObligationCause::new( ty.span, self.hir_id, @@ -186,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>) -> Result, Self::Error> { - if let ty::ReLateBound(..) = r { Ok(&ty::ReErased) } else { Ok(r) } + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + if let ty::ReLateBound(..) = r { &ty::ReErased } else { r } } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index f87cbb7f41755..41e06f43c4616 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -70,7 +70,6 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(control_flow_enum)] #![feature(hash_drain_filter)] -#![feature(unwrap_infallible)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 04fe1dccce44b..2ccf17387d1c7 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -449,7 +449,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { _ => false, } }) - .map(|p| p.fold_with(&mut replacer).into_ok()); + .map(|p| p.fold_with(&mut replacer)); let mut generic_params = (tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id)) @@ -714,11 +714,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { self.tcx } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { - Ok((match *r { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + (match *r { ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), _ => None, }) - .unwrap_or_else(|| r.super_fold_with(self).into_ok())) + .unwrap_or_else(|| r.super_fold_with(self)) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6ba56fe01a935..b6311abb5c3e8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -18,7 +18,6 @@ #![feature(type_ascription)] #![feature(iter_intersperse)] #![recursion_limit = "256"] -#![feature(unwrap_infallible)] #![warn(rustc::internal)] #[macro_use]