Continue folding if deep normalizer fails
This commit is contained in:
parent
334577f091
commit
3448284f8d
4 changed files with 57 additions and 32 deletions
|
@ -10,7 +10,7 @@ use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||||
use rustc_middle::traits::{ObligationCause, Reveal};
|
use rustc_middle::traits::{ObligationCause, Reveal};
|
||||||
use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
|
use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
|
||||||
use rustc_middle::ty::{FallibleTypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
||||||
|
|
||||||
use super::FulfillmentCtxt;
|
use super::FulfillmentCtxt;
|
||||||
|
@ -42,19 +42,6 @@ pub(crate) fn deeply_normalize_with_skipped_universes<'tcx, T: TypeFoldable<TyCt
|
||||||
value.try_fold_with(&mut folder)
|
value.try_fold_with(&mut folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deeply normalize a value and return it
|
|
||||||
pub(crate) fn deeply_normalize_for_diagnostics<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
|
||||||
infcx: &InferCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
t: T,
|
|
||||||
) -> T {
|
|
||||||
infcx
|
|
||||||
.commit_if_ok(|_| {
|
|
||||||
deeply_normalize(infcx.at(&ObligationCause::dummy(), param_env), t.clone())
|
|
||||||
})
|
|
||||||
.unwrap_or(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NormalizationFolder<'me, 'tcx> {
|
struct NormalizationFolder<'me, 'tcx> {
|
||||||
at: At<'me, 'tcx>,
|
at: At<'me, 'tcx>,
|
||||||
fulfill_cx: FulfillmentCtxt<'tcx>,
|
fulfill_cx: FulfillmentCtxt<'tcx>,
|
||||||
|
@ -244,3 +231,42 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deeply normalize a value and return it
|
||||||
|
pub(crate) fn deeply_normalize_for_diagnostics<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
t: T,
|
||||||
|
) -> T {
|
||||||
|
t.fold_with(&mut DeeplyNormalizeForDiagnosticsFolder {
|
||||||
|
at: infcx.at(&ObligationCause::dummy(), param_env),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeeplyNormalizeForDiagnosticsFolder<'a, 'tcx> {
|
||||||
|
at: At<'a, 'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, 'tcx> {
|
||||||
|
fn interner(&self) -> TyCtxt<'tcx> {
|
||||||
|
self.at.infcx.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
|
deeply_normalize_with_skipped_universes(
|
||||||
|
self.at,
|
||||||
|
ty,
|
||||||
|
vec![None; ty.outer_exclusive_binder().as_usize()],
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|_| ty.super_fold_with(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
|
deeply_normalize_with_skipped_universes(
|
||||||
|
self.at,
|
||||||
|
ct,
|
||||||
|
vec![None; ct.outer_exclusive_binder().as_usize()],
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|_| ct.super_fold_with(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0119]: conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
|
error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, _)`
|
||||||
--> $DIR/normalize-for-errors.rs:17:1
|
--> $DIR/normalize-for-errors.rs:16:1
|
||||||
|
|
|
|
||||||
LL | impl<T: Copy> MyTrait for T {}
|
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
|
||||||
| --------------------------- first implementation here
|
| ------------------------------------------------------ first implementation here
|
||||||
LL |
|
LL |
|
||||||
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
|
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)`
|
||||||
|
|
|
|
||||||
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0119]: conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
|
error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)`
|
||||||
--> $DIR/normalize-for-errors.rs:17:1
|
--> $DIR/normalize-for-errors.rs:16:1
|
||||||
|
|
|
|
||||||
LL | impl<T: Copy> MyTrait for T {}
|
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
|
||||||
| --------------------------- first implementation here
|
| ------------------------------------------------------ first implementation here
|
||||||
LL |
|
LL |
|
||||||
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
|
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)`
|
||||||
|
|
|
|
||||||
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
//[next] compile-flags: -Ztrait-solver=next
|
//[next] compile-flags: -Ztrait-solver=next
|
||||||
|
|
||||||
struct MyType;
|
struct MyType;
|
||||||
trait MyTrait {
|
trait MyTrait<S> {}
|
||||||
}
|
|
||||||
|
|
||||||
trait Mirror {
|
trait Mirror {
|
||||||
type Assoc;
|
type Assoc;
|
||||||
|
@ -12,11 +11,11 @@ impl<T> Mirror for T {
|
||||||
type Assoc = T;
|
type Assoc = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy> MyTrait for T {}
|
impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
|
||||||
//~^ NOTE first implementation here
|
//~^ NOTE first implementation here
|
||||||
impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
|
impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
|
||||||
//~^ ERROR conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
|
//~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
|
||||||
//~| NOTE conflicting implementation for `Box<(MyType,)>
|
//~| NOTE conflicting implementation for `(Box<(MyType,)>,
|
||||||
//~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
//~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue