From 6db9605d85dafd6759b82a934ac833baf0cd9214 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Wed, 19 May 2021 23:08:32 +0200 Subject: [PATCH] Use `TypeFolder::Error` for `FullTypeResolver` and `QueryNormalizer` Co-authored-by: Alan Egerton --- compiler/rustc_infer/src/infer/resolve.rs | 28 ++--- .../src/traits/query/normalize.rs | 117 ++++++------------ 2 files changed, 48 insertions(+), 97 deletions(-) diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 554c5b162f7..cccdfb7452a 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -181,22 +181,18 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu where T: TypeFoldable<'tcx>, { - let mut full_resolver = FullTypeResolver { infcx, err: None }; - let result = value.fold_with(&mut full_resolver).into_ok(); - match full_resolver.err { - None => Ok(result), - Some(e) => Err(e), - } + value.fold_with(&mut FullTypeResolver { infcx }) } // N.B. This type is not public because the protocol around checking the // `err` field is not enforceable otherwise. struct FullTypeResolver<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, - err: Option>, } impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { + type Error = FixupError<'tcx>; + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -207,18 +203,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { } else { let t = self.infcx.shallow_resolve(t); match *t.kind() { - ty::Infer(ty::TyVar(vid)) => { - self.err = Some(FixupError::UnresolvedTy(vid)); - Ok(self.tcx().ty_error()) - } - ty::Infer(ty::IntVar(vid)) => { - self.err = Some(FixupError::UnresolvedIntTy(vid)); - Ok(self.tcx().ty_error()) - } - ty::Infer(ty::FloatVar(vid)) => { - self.err = Some(FixupError::UnresolvedFloatTy(vid)); - Ok(self.tcx().ty_error()) - } + ty::Infer(ty::TyVar(vid)) => Err(FixupError::UnresolvedTy(vid)), + ty::Infer(ty::IntVar(vid)) => Err(FixupError::UnresolvedIntTy(vid)), + ty::Infer(ty::FloatVar(vid)) => Err(FixupError::UnresolvedFloatTy(vid)), ty::Infer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); } @@ -250,8 +237,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { let c = self.infcx.shallow_resolve(c); match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { - self.err = Some(FixupError::UnresolvedConst(vid)); - return Ok(self.tcx().const_error(c.ty)); + return Err(FixupError::UnresolvedConst(vid)); } ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index dd9cd51936e..af507feffba 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -61,7 +61,6 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { cause: self.cause, param_env: self.param_env, obligations: vec![], - error: false, cache: SsoHashMap::new(), anon_depth: 0, universes: vec![], @@ -88,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).into_ok(); + let result = value.fold_with(&mut normalizer); info!( "normalize::<{}>: result={:?} with {} obligations", std::any::type_name::(), @@ -100,11 +99,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { std::any::type_name::(), normalizer.obligations, ); - if normalizer.error { - Err(NoSolution) - } else { - Ok(Normalized { value: result, obligations: normalizer.obligations }) - } + result.map(|value| Normalized { value, obligations: normalizer.obligations }) } } @@ -171,12 +166,13 @@ struct QueryNormalizer<'cx, 'tcx> { param_env: ty::ParamEnv<'tcx>, obligations: Vec>, cache: SsoHashMap, Ty<'tcx>>, - error: bool, anon_depth: usize, universes: Vec>, } impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { + type Error = NoSolution; + fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -262,39 +258,22 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); - match tcx.normalize_projection_ty(c_data) { - Ok(result) => { - // We don't expect ambiguity. - if result.is_ambiguous() { - self.error = true; - return ty.super_fold_with(self); - } - - match self.infcx.instantiate_query_response_and_region_obligations( - self.cause, - self.param_env, - &orig_values, - result, - ) { - Ok(InferOk { value: result, obligations }) => { - debug!("QueryNormalizer: result = {:#?}", result); - debug!("QueryNormalizer: obligations = {:#?}", obligations); - self.obligations.extend(obligations); - Ok(result.normalized_ty) - } - - Err(_) => { - self.error = true; - ty.super_fold_with(self) - } - } - } - - Err(NoSolution) => { - self.error = true; - ty.super_fold_with(self) - } + let result = tcx.normalize_projection_ty(c_data)?; + // We don't expect ambiguity. + if result.is_ambiguous() { + return Err(NoSolution); } + let InferOk { value: result, obligations } = + self.infcx.instantiate_query_response_and_region_obligations( + self.cause, + self.param_env, + &orig_values, + result, + )?; + debug!("QueryNormalizer: result = {:#?}", result); + debug!("QueryNormalizer: obligations = {:#?}", obligations); + self.obligations.extend(obligations); + Ok(result.normalized_ty) } ty::Projection(data) => { @@ -318,43 +297,29 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); - match tcx.normalize_projection_ty(c_data) { - Ok(result) => { - // We don't expect ambiguity. - if result.is_ambiguous() { - self.error = true; - return ty.super_fold_with(self); - } - match self.infcx.instantiate_query_response_and_region_obligations( - self.cause, - self.param_env, - &orig_values, - result, - ) { - Ok(InferOk { value: result, obligations }) => { - debug!("QueryNormalizer: result = {:#?}", result); - debug!("QueryNormalizer: obligations = {:#?}", obligations); - self.obligations.extend(obligations); - Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - result.normalized_ty, - )) - } - Err(_) => { - self.error = true; - ty.super_fold_with(self) - } - } - } - Err(NoSolution) => { - self.error = true; - ty.super_fold_with(self) - } + let result = tcx.normalize_projection_ty(c_data)?; + // We don't expect ambiguity. + if result.is_ambiguous() { + return Err(NoSolution); } + let InferOk { value: result, obligations } = + self.infcx.instantiate_query_response_and_region_obligations( + self.cause, + self.param_env, + &orig_values, + result, + )?; + debug!("QueryNormalizer: result = {:#?}", result); + debug!("QueryNormalizer: obligations = {:#?}", obligations); + self.obligations.extend(obligations); + Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + result.normalized_ty, + )) } _ => ty.super_fold_with(self),