Skip to content

Commit

Permalink
Use TypeFolder::Error for FullTypeResolver and QueryNormalizer
Browse files Browse the repository at this point in the history
Co-authored-by: Alan Egerton <eggyal@gmail.com>
  • Loading branch information
LeSeulArtichaut and eggyal committed Nov 26, 2021
1 parent 30bf20a commit 6db9605
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 97 deletions.
28 changes: 7 additions & 21 deletions compiler/rustc_infer/src/infer/resolve.rs
Expand Up @@ -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<FixupError<'tcx>>,
}

impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
type Error = FixupError<'tcx>;

fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
117 changes: 41 additions & 76 deletions compiler/rustc_trait_selection/src/traits/query/normalize.rs
Expand Up @@ -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![],
Expand All @@ -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::<T>(),
Expand All @@ -100,11 +99,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
std::any::type_name::<T>(),
normalizer.obligations,
);
if normalizer.error {
Err(NoSolution)
} else {
Ok(Normalized { value: result, obligations: normalizer.obligations })
}
result.map(|value| Normalized { value, obligations: normalizer.obligations })
}
}

Expand Down Expand Up @@ -171,12 +166,13 @@ struct QueryNormalizer<'cx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
obligations: Vec<PredicateObligation<'tcx>>,
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
error: bool,
anon_depth: usize,
universes: Vec<Option<ty::UniverseIndex>>,
}

impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
type Error = NoSolution;

fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
Expand Down Expand Up @@ -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) => {
Expand All @@ -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),
Expand Down

0 comments on commit 6db9605

Please sign in to comment.