Unwrap the results of type folders

Co-authored-by: Alan Egerton <eggyal@gmail.com>
This commit is contained in:
LeSeulArtichaut 2021-05-19 15:03:43 +02:00 committed by Alan Egerton
parent 6dc3dae46f
commit 30bf20a692
No known key found for this signature in database
GPG key ID: 07CAC3CCA7E0643F
34 changed files with 191 additions and 167 deletions

View file

@ -23,6 +23,7 @@
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(trusted_step)] #![feature(trusted_step)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(unwrap_infallible)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#[macro_use] #[macro_use]

View file

@ -95,7 +95,8 @@ pub fn equal_up_to_regions(
// Leave consts and types unchanged. // Leave consts and types unchanged.
ct_op: |ct| ct, ct_op: |ct| ct,
ty_op: |ty| ty, ty_op: |ty| ty,
}), })
.into_ok(),
) )
}; };
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok()) tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())

View file

@ -503,7 +503,7 @@ fn canonicalize<V>(
indices: FxHashMap::default(), indices: FxHashMap::default(),
binder_index: ty::INNERMOST, binder_index: ty::INNERMOST,
}; };
let out_value = value.fold_with(&mut canonicalizer); let out_value = value.fold_with(&mut canonicalizer).into_ok();
// Once we have canonicalized `out_value`, it should not // Once we have canonicalized `out_value`, it should not
// contain anything that ties it to this inference context // contain anything that ties it to this inference context
@ -621,7 +621,7 @@ fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>
let infcx = self.infcx; let infcx = self.infcx;
let bound_to = infcx.shallow_resolve(ty_var); let bound_to = infcx.shallow_resolve(ty_var);
if bound_to != ty_var { if bound_to != ty_var {
self.fold_ty(bound_to) self.fold_ty(bound_to).into_ok()
} else { } else {
let var = self.canonical_var(info, ty_var.into()); let var = self.canonical_var(info, ty_var.into());
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into())) self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))
@ -640,12 +640,12 @@ fn canonicalize_const_var(
let infcx = self.infcx; let infcx = self.infcx;
let bound_to = infcx.shallow_resolve(const_var); let bound_to = infcx.shallow_resolve(const_var);
if bound_to != const_var { if bound_to != const_var {
self.fold_const(bound_to) self.fold_const(bound_to).into_ok()
} else { } else {
let var = self.canonical_var(info, const_var.into()); let var = self.canonical_var(info, const_var.into());
self.tcx().mk_const(ty::Const { self.tcx().mk_const(ty::Const {
val: ty::ConstKind::Bound(self.binder_index, var), val: ty::ConstKind::Bound(self.binder_index, var),
ty: self.fold_ty(const_var.ty), ty: self.fold_ty(const_var.ty).into_ok(),
}) })
} }
} }

View file

@ -72,7 +72,7 @@ fn freshen_ty<F>(
F: FnOnce(u32) -> ty::InferTy, F: FnOnce(u32) -> ty::InferTy,
{ {
if let Some(ty) = opt_ty { if let Some(ty) = opt_ty {
return ty.fold_with(self); return ty.fold_with(self).into_ok();
} }
match self.ty_freshen_map.entry(key) { match self.ty_freshen_map.entry(key) {
@ -98,7 +98,7 @@ fn freshen_const<F>(
F: FnOnce(u32) -> ty::InferConst<'tcx>, F: FnOnce(u32) -> ty::InferConst<'tcx>,
{ {
if let Some(ct) = opt_ct { if let Some(ct) = opt_ct {
return ct.fold_with(self); return ct.fold_with(self).into_ok();
} }
match self.const_freshen_map.entry(key) { match self.const_freshen_map.entry(key) {

View file

@ -161,7 +161,7 @@ pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
{ {
Ok(value) Ok(value)
} else { } else {
Ok(value.fold_with(&mut fudger)) Ok(value.fold_with(&mut fudger).into_ok())
} }
} }
} }

View file

@ -681,7 +681,7 @@ pub fn is_in_snapshot(&self) -> bool {
} }
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T { pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
t.fold_with(&mut self.freshener()) t.fold_with(&mut self.freshener()).into_ok()
} }
/// Returns the origin of the type variable identified by `vid`, or `None` /// Returns the origin of the type variable identified by `vid`, or `None`
@ -1381,7 +1381,7 @@ pub fn shallow_resolve<T>(&self, value: T) -> T
where where
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
value.fold_with(&mut ShallowResolver { infcx: self }) value.fold_with(&mut ShallowResolver { infcx: self }).into_ok()
} }
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
@ -1402,7 +1402,7 @@ pub fn resolve_vars_if_possible<T>(&self, value: T) -> T
return value; // Avoid duplicated subst-folding. return value; // Avoid duplicated subst-folding.
} }
let mut r = resolve::OpportunisticVarResolver::new(self); let mut r = resolve::OpportunisticVarResolver::new(self);
value.fold_with(&mut r) value.fold_with(&mut r).into_ok()
} }
/// Returns the first unresolved variable contained in `T`. In the /// Returns the first unresolved variable contained in `T`. In the

View file

@ -418,92 +418,94 @@ struct Instantiator<'a, 'tcx> {
impl<'a, 'tcx> Instantiator<'a, 'tcx> { impl<'a, 'tcx> Instantiator<'a, 'tcx> {
fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T { fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
value.fold_with(&mut BottomUpFolder { value
tcx, .fold_with(&mut BottomUpFolder {
ty_op: |ty| { tcx,
if ty.references_error() { ty_op: |ty| {
return tcx.ty_error(); if ty.references_error() {
} else if let ty::Opaque(def_id, substs) = ty.kind() { return tcx.ty_error();
// Check that this is `impl Trait` type is } else if let ty::Opaque(def_id, substs) = ty.kind() {
// declared by `parent_def_id` -- i.e., one whose // Check that this is `impl Trait` type is
// value we are inferring. At present, this is // declared by `parent_def_id` -- i.e., one whose
// always true during the first phase of // value we are inferring. At present, this is
// type-check, but not always true later on during // always true during the first phase of
// NLL. Once we support named opaque types more fully, // type-check, but not always true later on during
// this same scenario will be able to arise during all phases. // 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: // Here is an example using type alias `impl Trait`
// // that indicates the distinction we are checking for:
// ```rust //
// mod a { // ```rust
// pub type Foo = impl Iterator; // mod a {
// pub fn make_foo() -> Foo { .. } // pub type Foo = impl Iterator;
// } // pub fn make_foo() -> Foo { .. }
// // }
// mod b { //
// fn foo() -> a::Foo { a::make_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 // Here, the return type of `foo` references an
// presently being inferred. You can get into a // `Opaque` indeed, but not one whose value is
// similar situation with closure return types // presently being inferred. You can get into a
// today: // similar situation with closure return types
// // today:
// ```rust //
// fn foo() -> impl Iterator { .. } // ```rust
// fn bar() { // fn foo() -> impl Iterator { .. }
// let x = || foo(); // returns the Opaque assoc with `foo` // 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); if let Some(def_id) = def_id.as_local() {
let parent_def_id = self.infcx.defining_use_anchor; let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let def_scope_default = || { let parent_def_id = self.infcx.defining_use_anchor;
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); let def_scope_default = || {
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id) 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(opaque_hir_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 (in_definition_scope, origin) =
let opaque_type_key = match tcx.hir().expect_item(opaque_hir_id).kind {
OpaqueTypeKey { def_id: def_id.to_def_id(), substs }; // Anonymous `impl Trait`
return self.fold_opaque_ty(ty, opaque_type_key, origin); 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!( debug!(
"instantiate_opaque_types_in_map: \ "instantiate_opaque_types_in_map: \
encountered opaque outside its definition scope \ encountered opaque outside its definition scope \
def_id={:?}", def_id={:?}",
def_id, def_id,
); );
}
} }
}
ty ty
}, },
lt_op: |lt| lt, lt_op: |lt| lt,
ct_op: |ct| ct, ct_op: |ct| ct,
}) })
.into_ok()
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
@ -556,21 +558,23 @@ fn fold_opaque_ty(
debug!(?predicate); debug!(?predicate);
// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them. // 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 { let predicate = predicate
tcx, .fold_with(&mut BottomUpFolder {
ty_op: |ty| match ty.kind() { tcx,
ty::Projection(projection_ty) => infcx.infer_projection( ty_op: |ty| match ty.kind() {
self.param_env, ty::Projection(projection_ty) => infcx.infer_projection(
*projection_ty, self.param_env,
traits::ObligationCause::misc(self.value_span, self.body_id), *projection_ty,
0, traits::ObligationCause::misc(self.value_span, self.body_id),
&mut self.obligations, 0,
), &mut self.obligations,
_ => ty, ),
}, _ => ty,
lt_op: |lt| lt, },
ct_op: |ct| ct, lt_op: |lt| lt,
}); ct_op: |ct| ct,
})
.into_ok();
debug!(?predicate); debug!(?predicate);
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() { if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {

View file

@ -182,7 +182,7 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
let mut full_resolver = FullTypeResolver { infcx, err: None }; let mut full_resolver = FullTypeResolver { infcx, err: None };
let result = value.fold_with(&mut full_resolver); let result = value.fold_with(&mut full_resolver).into_ok();
match full_resolver.err { match full_resolver.err {
None => Ok(result), None => Ok(result),
Some(e) => Err(e), Some(e) => Err(e),

View file

@ -24,6 +24,7 @@
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(label_break_value)] #![feature(label_break_value)]
#![feature(unwrap_infallible)]
#![recursion_limit = "512"] // For rustdoc #![recursion_limit = "512"] // For rustdoc
#[macro_use] #[macro_use]

View file

@ -56,6 +56,7 @@
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(try_reserve_kind)] #![feature(try_reserve_kind)]
#![feature(nonzero_ops)] #![feature(nonzero_ops)]
#![feature(unwrap_infallible)]
#![recursion_limit = "512"] #![recursion_limit = "512"]
#[macro_use] #[macro_use]

View file

@ -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> { 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 // N.B., use `super_fold_with` here. If we used `fold_with`, it
// could invoke the `erase_regions_ty` query recursively. // could invoke the `erase_regions_ty` query recursively.
ty.super_fold_with(&mut RegionEraserVisitor { tcx }) ty.super_fold_with(&mut RegionEraserVisitor { tcx }).into_ok()
} }
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
@ -27,7 +27,7 @@ pub fn erase_regions<T>(self, value: T) -> T
return value; return value;
} }
debug!("erase_regions({:?})", value); debug!("erase_regions({:?})", value);
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }).into_ok();
debug!("erase_regions = {:?}", value1); debug!("erase_regions = {:?}", value1);
value1 value1
} }

View file

@ -336,7 +336,7 @@ pub fn fold_regions<T>(
where where
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)).into_ok()
} }
/// Invoke `callback` on every region appearing free in `value`. /// Invoke `callback` on every region appearing free in `value`.
@ -638,7 +638,7 @@ pub fn replace_late_bound_regions<T, F>(
value value
} else { } else {
let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None); let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None);
value.fold_with(&mut replacer) value.fold_with(&mut replacer).into_ok()
}; };
(value, region_map) (value, region_map)
} }
@ -664,7 +664,7 @@ pub fn replace_escaping_bound_vars<T, F, G, H>(
} else { } else {
let mut replacer = let mut replacer =
BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c)); BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c));
value.fold_with(&mut replacer) value.fold_with(&mut replacer).into_ok()
} }
} }
@ -1030,7 +1030,7 @@ pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T
{ {
debug!("shift_vars(value={:?}, amount={})", value, amount); debug!("shift_vars(value={:?}, amount={})", value, amount);
value.fold_with(&mut Shifter::new(tcx, amount)) value.fold_with(&mut Shifter::new(tcx, amount)).into_ok()
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
@ -1293,7 +1293,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// ///
/// FIXME(@lcnr): explain this function a bit more /// FIXME(@lcnr): explain this function a bit more
pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T { pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T {
v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }) v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }).into_ok()
} }
} }

View file

@ -669,7 +669,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
// ..and polymorphize any closures/generators captured as upvars. // ..and polymorphize any closures/generators captured as upvars.
let upvars_ty = upvars_ty.unwrap(); let upvars_ty = upvars_ty.unwrap();
let polymorphized_upvars_ty = upvars_ty.fold_with( let polymorphized_upvars_ty = upvars_ty.fold_with(
&mut PolymorphizationFolder { tcx }); &mut PolymorphizationFolder { tcx }).into_ok();
debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty); debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);
ty::GenericArg::from(polymorphized_upvars_ty) ty::GenericArg::from(polymorphized_upvars_ty)
}, },

View file

@ -35,7 +35,9 @@ pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value:
if !value.has_projections() { if !value.has_projections() {
value value
} else { } else {
value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) value
.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
.into_ok()
} }
} }

View file

@ -2193,7 +2193,7 @@ fn name_by_region_index(index: usize) -> Symbol {
name: &mut name, name: &mut name,
region_map: BTreeMap::new(), region_map: BTreeMap::new(),
}; };
let new_value = value.clone().skip_binder().fold_with(&mut folder); let new_value = value.clone().skip_binder().fold_with(&mut folder).into_ok();
let region_map = folder.region_map; let region_map = folder.region_map;
start_or_continue(&mut self, "", "> "); start_or_continue(&mut self, "", "> ");
(new_value, region_map) (new_value, region_map)

View file

@ -439,7 +439,7 @@ fn subst_spanned(
span: Option<Span>, span: Option<Span>,
) -> T { ) -> T {
let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 }; let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
self.fold_with(&mut folder) self.fold_with(&mut folder).into_ok()
} }
} }

View file

@ -574,14 +574,14 @@ fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option
if self.found_any_recursion { if self.found_any_recursion {
return None; return None;
} }
let substs = substs.fold_with(self); let substs = substs.fold_with(self).into_ok();
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) { if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
Some(expanded_ty) => expanded_ty, Some(expanded_ty) => expanded_ty,
None => { None => {
let generic_ty = self.tcx.type_of(def_id); let generic_ty = self.tcx.type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx, substs); let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty); let expanded_ty = self.fold_ty(concrete_ty).into_ok();
self.expanded_cache.insert((def_id, substs), expanded_ty); self.expanded_cache.insert((def_id, substs), expanded_ty);
expanded_ty expanded_ty
} }
@ -1092,7 +1092,7 @@ pub fn normalize_opaque_types(
check_recursion: false, check_recursion: false,
tcx, tcx,
}; };
val.fold_with(&mut visitor) val.fold_with(&mut visitor).into_ok()
} }
pub fn provide(providers: &mut ty::query::Providers) { pub fn provide(providers: &mut ty::query::Providers) {

View file

@ -22,6 +22,7 @@
#![feature(never_type)] #![feature(never_type)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(unwrap_infallible)]
#![recursion_limit = "512"] // For rustdoc #![recursion_limit = "512"] // For rustdoc
#[macro_use] #[macro_use]

View file

@ -65,14 +65,16 @@ fn infer_opaque_definition_from_instantiation(
// Convert the type from the function into a type valid outside // Convert the type from the function into a type valid outside
// the function, by replacing invalid regions with 'static, // the function, by replacing invalid regions with 'static,
// after producing an error for each of them. // after producing an error for each of them.
let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new( let definition_ty = instantiated_ty
self.tcx, .fold_with(&mut ReverseMapper::new(
self.is_tainted_by_errors(), self.tcx,
def_id, self.is_tainted_by_errors(),
map, def_id,
instantiated_ty, map,
span, instantiated_ty,
)); span,
))
.into_ok();
debug!(?definition_ty); debug!(?definition_ty);
definition_ty definition_ty
@ -123,14 +125,14 @@ fn fold_kind_mapping_missing_regions_to_empty(
) -> GenericArg<'tcx> { ) -> GenericArg<'tcx> {
assert!(!self.map_missing_regions_to_empty); assert!(!self.map_missing_regions_to_empty);
self.map_missing_regions_to_empty = true; self.map_missing_regions_to_empty = true;
let kind = kind.fold_with(self); let kind = kind.fold_with(self).into_ok();
self.map_missing_regions_to_empty = false; self.map_missing_regions_to_empty = false;
kind kind
} }
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> { fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
assert!(!self.map_missing_regions_to_empty); assert!(!self.map_missing_regions_to_empty);
kind.fold_with(self) kind.fold_with(self).into_ok()
} }
} }

View file

@ -1916,8 +1916,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
self.probe(|_| { self.probe(|_| {
let mut selcx = SelectionContext::new(self); let mut selcx = SelectionContext::new(self);
let cleaned_pred = let cleaned_pred = pred
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); .fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() })
.into_ok();
let cleaned_pred = super::project::normalize( let cleaned_pred = super::project::normalize(
&mut selcx, &mut selcx,

View file

@ -339,7 +339,7 @@ fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
if !needs_normalization(&value, self.param_env.reveal()) { if !needs_normalization(&value, self.param_env.reveal()) {
value value
} else { } else {
value.fold_with(self) value.fold_with(self).into_ok()
} }
} }
} }
@ -555,7 +555,7 @@ pub fn replace_bound_vars<T: TypeFoldable<'tcx>>(
universe_indices, universe_indices,
}; };
let value = value.super_fold_with(&mut replacer); let value = value.super_fold_with(&mut replacer).into_ok();
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts) (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
} }
@ -681,7 +681,7 @@ pub fn replace_placeholders<T: TypeFoldable<'tcx>>(
universe_indices, universe_indices,
current_index: ty::INNERMOST, current_index: ty::INNERMOST,
}; };
value.super_fold_with(&mut replacer) value.super_fold_with(&mut replacer).into_ok()
} }
} }
@ -1546,7 +1546,8 @@ fn confirm_candidate<'cx, 'tcx>(
// when possible for this to work. See `auto-trait-projection-recursion.rs` // when possible for this to work. See `auto-trait-projection-recursion.rs`
// for a case where this matters. // for a case where this matters.
if progress.ty.has_infer_regions() { if progress.ty.has_infer_regions() {
progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty); progress.ty =
OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty).into_ok();
} }
progress progress
} }

View file

@ -88,7 +88,7 @@ fn normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None)); normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
} }
} }
let result = value.fold_with(&mut normalizer); let result = value.fold_with(&mut normalizer).into_ok();
info!( info!(
"normalize::<{}>: result={:?} with {} obligations", "normalize::<{}>: result={:?} with {} obligations",
std::any::type_name::<T>(), std::any::type_name::<T>(),

View file

@ -2222,6 +2222,7 @@ fn push_stack<'o>(
.predicate .predicate
.to_poly_trait_ref() .to_poly_trait_ref()
.fold_with(&mut self.freshener) .fold_with(&mut self.freshener)
.into_ok()
.with_constness(obligation.predicate.skip_binder().constness); .with_constness(obligation.predicate.skip_binder().constness);
let dfn = previous_stack.cache.next_dfn(); let dfn = previous_stack.cache.next_dfn();

View file

@ -45,7 +45,7 @@ fn where_clauses_for(
predicates predicates
.iter() .iter()
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
.map(|wc| wc.fold_with(&mut regions_substitutor)) .map(|wc| wc.fold_with(&mut regions_substitutor).into_ok())
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect() .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect()
} }
@ -287,7 +287,7 @@ fn impl_datum(
let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars);
let mut regions_substitutor = let mut regions_substitutor =
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
let trait_ref = trait_ref.fold_with(&mut regions_substitutor); let trait_ref = trait_ref.fold_with(&mut regions_substitutor).into_ok();
let where_clauses = self.where_clauses_for(def_id, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars);
@ -335,7 +335,7 @@ fn impls_for_trait(
let self_ty = self_ty.subst(self.interner.tcx, bound_vars); let self_ty = self_ty.subst(self.interner.tcx, bound_vars);
let mut regions_substitutor = let mut regions_substitutor =
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
let self_ty = self_ty.fold_with(&mut regions_substitutor); let self_ty = self_ty.fold_with(&mut regions_substitutor).into_ok();
let lowered_ty = self_ty.lower_into(&self.interner); let lowered_ty = self_ty.lower_into(&self.interner);
parameters[0].assert_ty_ref(&self.interner).could_match( parameters[0].assert_ty_ref(&self.interner).could_match(
@ -501,22 +501,24 @@ fn opaque_ty_data(
.iter() .iter()
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
.map(|bound| { .map(|bound| {
bound.fold_with(&mut ty::fold::BottomUpFolder { bound
tcx: self.interner.tcx, .fold_with(&mut ty::fold::BottomUpFolder {
ty_op: |ty| { tcx: self.interner.tcx,
if let ty::Opaque(def_id, substs) = *ty.kind() { ty_op: |ty| {
if def_id == opaque_ty_id.0 && substs == identity_substs { if let ty::Opaque(def_id, substs) = *ty.kind() {
return self.interner.tcx.mk_ty(ty::Bound( if def_id == opaque_ty_id.0 && substs == identity_substs {
ty::INNERMOST, return self.interner.tcx.mk_ty(ty::Bound(
ty::BoundTy::from(ty::BoundVar::from_u32(0)), ty::INNERMOST,
)); ty::BoundTy::from(ty::BoundVar::from_u32(0)),
));
}
} }
} ty
ty },
}, lt_op: |lt| lt,
lt_op: |lt| lt, ct_op: |ct| ct,
ct_op: |ct| ct, })
}) .into_ok()
}) })
.filter_map(|bound| { .filter_map(|bound| {
LowerInto::< LowerInto::<

View file

@ -817,7 +817,7 @@ fn lower_into(
.collect(); .collect();
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters); let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor); let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor).into_ok();
for var in named_parameters.values() { for var in named_parameters.values() {
parameters.insert(*var, chalk_ir::VariableKind::Lifetime); parameters.insert(*var, chalk_ir::VariableKind::Lifetime);

View file

@ -49,12 +49,12 @@
let mut params_substitutor = let mut params_substitutor =
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
let obligation = obligation.fold_with(&mut params_substitutor); let obligation = obligation.fold_with(&mut params_substitutor).into_ok();
// FIXME(chalk): we really should be substituting these back in the solution // FIXME(chalk): we really should be substituting these back in the solution
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params; let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder); let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
let obligation = obligation.fold_with(&mut regions_substitutor); let obligation = obligation.fold_with(&mut regions_substitutor).into_ok();
let max_universe = obligation.max_universe.index(); let max_universe = obligation.max_universe.index();

View file

@ -4,6 +4,7 @@
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]
#![feature(nll)] #![feature(nll)]
#![feature(unwrap_infallible)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#[macro_use] #[macro_use]

View file

@ -442,8 +442,8 @@ fn check_overloaded_binop(
let mut eraser = TypeParamEraser(self, expr.span); let mut eraser = TypeParamEraser(self, expr.span);
let needs_bound = self let needs_bound = self
.lookup_op_method( .lookup_op_method(
eraser.fold_ty(lhs_ty), eraser.fold_ty(lhs_ty).into_ok(),
&[eraser.fold_ty(rhs_ty)], &[eraser.fold_ty(rhs_ty).into_ok()],
Op::Binary(op, is_assign), Op::Binary(op, is_assign),
) )
.is_ok(); .is_ok();

View file

@ -658,7 +658,7 @@ fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
let mut resolver = Resolver::new(self.fcx, span, self.body); let mut resolver = Resolver::new(self.fcx, span, self.body);
let x = x.fold_with(&mut resolver); let x = x.fold_with(&mut resolver).into_ok();
if cfg!(debug_assertions) && x.needs_infer() { if cfg!(debug_assertions) && x.needs_infer() {
span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x); span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
} }

View file

@ -761,7 +761,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
// Suggesting unnameable types won't help. // Suggesting unnameable types won't help.
let mut mk_nameable = MakeNameable::new(tcx); let mut mk_nameable = MakeNameable::new(tcx);
let ty = mk_nameable.fold_ty(ty); let ty = mk_nameable.fold_ty(ty).into_ok();
let sugg_ty = if mk_nameable.success { Some(ty) } else { None }; let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
if let Some(sugg_ty) = sugg_ty { if let Some(sugg_ty) = sugg_ty {
err.span_suggestion( err.span_suggestion(
@ -785,7 +785,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if !ty.references_error() { if !ty.references_error() {
let mut mk_nameable = MakeNameable::new(tcx); let mut mk_nameable = MakeNameable::new(tcx);
let ty = mk_nameable.fold_ty(ty); let ty = mk_nameable.fold_ty(ty).into_ok();
let sugg_ty = if mk_nameable.success { Some(ty) } else { None }; let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
if let Some(sugg_ty) = sugg_ty { if let Some(sugg_ty) = sugg_ty {
diag.span_suggestion( diag.span_suggestion(

View file

@ -71,8 +71,11 @@ fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| { self.tcx.infer_ctxt().enter(|infcx| {
let mut fulfill = traits::FulfillmentContext::new(); let mut fulfill = traits::FulfillmentContext::new();
let tcx_ty = let tcx_ty = self
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx }); .icx
.to_ty(ty)
.fold_with(&mut EraseAllBoundRegions { tcx: self.tcx })
.into_ok();
let cause = traits::ObligationCause::new( let cause = traits::ObligationCause::new(
ty.span, ty.span,
self.hir_id, self.hir_id,

View file

@ -71,6 +71,7 @@
#![feature(slice_partition_dedup)] #![feature(slice_partition_dedup)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(hash_drain_filter)] #![feature(hash_drain_filter)]
#![feature(unwrap_infallible)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#[macro_use] #[macro_use]

View file

@ -449,7 +449,7 @@ fn param_env_to_generics(
_ => false, _ => false,
} }
}) })
.map(|p| p.fold_with(&mut replacer)); .map(|p| p.fold_with(&mut replacer).into_ok());
let mut generic_params = let mut generic_params =
(tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id)) (tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id))

View file

@ -18,6 +18,7 @@
#![feature(type_ascription)] #![feature(type_ascription)]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![feature(unwrap_infallible)]
#![warn(rustc::internal)] #![warn(rustc::internal)]
#[macro_use] #[macro_use]