Use TypeFolder::Error
for FullTypeResolver
and QueryNormalizer
Co-authored-by: Alan Egerton <eggyal@gmail.com>
This commit is contained in:
parent
30bf20a692
commit
6db9605d85
2 changed files with 48 additions and 97 deletions
|
@ -181,22 +181,18 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let mut full_resolver = FullTypeResolver { infcx, err: None };
|
value.fold_with(&mut FullTypeResolver { infcx })
|
||||||
let result = value.fold_with(&mut full_resolver).into_ok();
|
|
||||||
match full_resolver.err {
|
|
||||||
None => Ok(result),
|
|
||||||
Some(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// N.B. This type is not public because the protocol around checking the
|
// N.B. This type is not public because the protocol around checking the
|
||||||
// `err` field is not enforceable otherwise.
|
// `err` field is not enforceable otherwise.
|
||||||
struct FullTypeResolver<'a, 'tcx> {
|
struct FullTypeResolver<'a, 'tcx> {
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
err: Option<FixupError<'tcx>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
|
type Error = FixupError<'tcx>;
|
||||||
|
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
@ -207,18 +203,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
let t = self.infcx.shallow_resolve(t);
|
let t = self.infcx.shallow_resolve(t);
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Infer(ty::TyVar(vid)) => {
|
ty::Infer(ty::TyVar(vid)) => Err(FixupError::UnresolvedTy(vid)),
|
||||||
self.err = Some(FixupError::UnresolvedTy(vid));
|
ty::Infer(ty::IntVar(vid)) => Err(FixupError::UnresolvedIntTy(vid)),
|
||||||
Ok(self.tcx().ty_error())
|
ty::Infer(ty::FloatVar(vid)) => Err(FixupError::UnresolvedFloatTy(vid)),
|
||||||
}
|
|
||||||
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::Infer(_) => {
|
||||||
bug!("Unexpected type in full type resolver: {:?}", t);
|
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);
|
let c = self.infcx.shallow_resolve(c);
|
||||||
match c.val {
|
match c.val {
|
||||||
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||||
self.err = Some(FixupError::UnresolvedConst(vid));
|
return Err(FixupError::UnresolvedConst(vid));
|
||||||
return Ok(self.tcx().const_error(c.ty));
|
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
||||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||||
|
|
|
@ -61,7 +61,6 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||||
cause: self.cause,
|
cause: self.cause,
|
||||||
param_env: self.param_env,
|
param_env: self.param_env,
|
||||||
obligations: vec![],
|
obligations: vec![],
|
||||||
error: false,
|
|
||||||
cache: SsoHashMap::new(),
|
cache: SsoHashMap::new(),
|
||||||
anon_depth: 0,
|
anon_depth: 0,
|
||||||
universes: vec![],
|
universes: vec![],
|
||||||
|
@ -88,7 +87,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||||
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).into_ok();
|
let result = value.fold_with(&mut normalizer);
|
||||||
info!(
|
info!(
|
||||||
"normalize::<{}>: result={:?} with {} obligations",
|
"normalize::<{}>: result={:?} with {} obligations",
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
|
@ -100,11 +99,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
normalizer.obligations,
|
normalizer.obligations,
|
||||||
);
|
);
|
||||||
if normalizer.error {
|
result.map(|value| Normalized { value, obligations: normalizer.obligations })
|
||||||
Err(NoSolution)
|
|
||||||
} else {
|
|
||||||
Ok(Normalized { value: result, obligations: normalizer.obligations })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,12 +166,13 @@ struct QueryNormalizer<'cx, 'tcx> {
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
obligations: Vec<PredicateObligation<'tcx>>,
|
obligations: Vec<PredicateObligation<'tcx>>,
|
||||||
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
|
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
|
||||||
error: bool,
|
|
||||||
anon_depth: usize,
|
anon_depth: usize,
|
||||||
universes: Vec<Option<ty::UniverseIndex>>,
|
universes: Vec<Option<ty::UniverseIndex>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
|
type Error = NoSolution;
|
||||||
|
|
||||||
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
@ -262,41 +258,24 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
||||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||||
match tcx.normalize_projection_ty(c_data) {
|
let result = tcx.normalize_projection_ty(c_data)?;
|
||||||
Ok(result) => {
|
|
||||||
// We don't expect ambiguity.
|
// We don't expect ambiguity.
|
||||||
if result.is_ambiguous() {
|
if result.is_ambiguous() {
|
||||||
self.error = true;
|
return Err(NoSolution);
|
||||||
return ty.super_fold_with(self);
|
|
||||||
}
|
}
|
||||||
|
let InferOk { value: result, obligations } =
|
||||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
self.infcx.instantiate_query_response_and_region_obligations(
|
||||||
self.cause,
|
self.cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
&orig_values,
|
&orig_values,
|
||||||
result,
|
result,
|
||||||
) {
|
)?;
|
||||||
Ok(InferOk { value: result, obligations }) => {
|
|
||||||
debug!("QueryNormalizer: result = {:#?}", result);
|
debug!("QueryNormalizer: result = {:#?}", result);
|
||||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||||
self.obligations.extend(obligations);
|
self.obligations.extend(obligations);
|
||||||
Ok(result.normalized_ty)
|
Ok(result.normalized_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(_) => {
|
|
||||||
self.error = true;
|
|
||||||
ty.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(NoSolution) => {
|
|
||||||
self.error = true;
|
|
||||||
ty.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Projection(data) => {
|
ty::Projection(data) => {
|
||||||
// See note in `rustc_trait_selection::traits::project`
|
// See note in `rustc_trait_selection::traits::project`
|
||||||
|
|
||||||
|
@ -318,20 +297,18 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
||||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||||
match tcx.normalize_projection_ty(c_data) {
|
let result = tcx.normalize_projection_ty(c_data)?;
|
||||||
Ok(result) => {
|
|
||||||
// We don't expect ambiguity.
|
// We don't expect ambiguity.
|
||||||
if result.is_ambiguous() {
|
if result.is_ambiguous() {
|
||||||
self.error = true;
|
return Err(NoSolution);
|
||||||
return ty.super_fold_with(self);
|
|
||||||
}
|
}
|
||||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
let InferOk { value: result, obligations } =
|
||||||
|
self.infcx.instantiate_query_response_and_region_obligations(
|
||||||
self.cause,
|
self.cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
&orig_values,
|
&orig_values,
|
||||||
result,
|
result,
|
||||||
) {
|
)?;
|
||||||
Ok(InferOk { value: result, obligations }) => {
|
|
||||||
debug!("QueryNormalizer: result = {:#?}", result);
|
debug!("QueryNormalizer: result = {:#?}", result);
|
||||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||||
self.obligations.extend(obligations);
|
self.obligations.extend(obligations);
|
||||||
|
@ -344,18 +321,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
result.normalized_ty,
|
result.normalized_ty,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Err(_) => {
|
|
||||||
self.error = true;
|
|
||||||
ty.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoSolution) => {
|
|
||||||
self.error = true;
|
|
||||||
ty.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.super_fold_with(self),
|
||||||
})()?;
|
})()?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue