Skip to content

Commit 01c4e8e

Browse files
Continue folding if deep normalizer fails
1 parent e00fed4 commit 01c4e8e

File tree

4 files changed

+55
-30
lines changed

4 files changed

+55
-30
lines changed

compiler/rustc_trait_selection/src/solve/normalize.rs

+40-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
1010
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
1111
use rustc_middle::traits::{ObligationCause, Reveal};
1212
use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
13-
use rustc_middle::ty::{FallibleTypeFolder, TypeSuperFoldable};
13+
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
1414
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
1515

1616
use super::FulfillmentCtxt;
@@ -42,19 +42,6 @@ pub(crate) fn deeply_normalize_with_skipped_universes<'tcx, T: TypeFoldable<TyCt
4242
value.try_fold_with(&mut folder)
4343
}
4444

45-
// Deeply normalize a value and return it
46-
pub(crate) fn deeply_normalize_for_diagnostics<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
47-
infcx: &InferCtxt<'tcx>,
48-
param_env: ty::ParamEnv<'tcx>,
49-
t: T,
50-
) -> T {
51-
infcx
52-
.commit_if_ok(|_| {
53-
deeply_normalize(infcx.at(&ObligationCause::dummy(), param_env), t.clone())
54-
})
55-
.unwrap_or(t)
56-
}
57-
5845
struct NormalizationFolder<'me, 'tcx> {
5946
at: At<'me, 'tcx>,
6047
fulfill_cx: FulfillmentCtxt<'tcx>,
@@ -244,3 +231,42 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
244231
}
245232
}
246233
}
234+
235+
// Deeply normalize a value and return it
236+
pub(crate) fn deeply_normalize_for_diagnostics<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
237+
infcx: &InferCtxt<'tcx>,
238+
param_env: ty::ParamEnv<'tcx>,
239+
t: T,
240+
) -> T {
241+
t.clone().fold_with(&mut DeeplyNormalizeForDiagnosticsFolder {
242+
at: infcx.at(&ObligationCause::dummy(), param_env),
243+
})
244+
}
245+
246+
struct DeeplyNormalizeForDiagnosticsFolder<'a, 'tcx> {
247+
at: At<'a, 'tcx>,
248+
}
249+
250+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, 'tcx> {
251+
fn interner(&self) -> TyCtxt<'tcx> {
252+
self.at.infcx.tcx
253+
}
254+
255+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
256+
deeply_normalize_with_skipped_universes(
257+
self.at,
258+
ty,
259+
vec![None; ty.outer_exclusive_binder().as_usize()],
260+
)
261+
.unwrap_or_else(|_| ty.super_fold_with(self))
262+
}
263+
264+
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
265+
deeply_normalize_with_skipped_universes(
266+
self.at,
267+
ct,
268+
vec![None; ct.outer_exclusive_binder().as_usize()],
269+
)
270+
.unwrap_or_else(|_| ct.super_fold_with(self))
271+
}
272+
}

tests/ui/coherence/normalize-for-errors.current.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0119]: conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
1+
error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, _)`
22
--> $DIR/normalize-for-errors.rs:17:1
33
|
4-
LL | impl<T: Copy> MyTrait for T {}
5-
| --------------------------- first implementation here
4+
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
5+
| ------------------------------------------------------ first implementation here
66
LL |
7-
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
7+
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)`
99
|
1010
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
1111

tests/ui/coherence/normalize-for-errors.next.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0119]: conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
1+
error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)`
22
--> $DIR/normalize-for-errors.rs:17:1
33
|
4-
LL | impl<T: Copy> MyTrait for T {}
5-
| --------------------------- first implementation here
4+
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
5+
| ------------------------------------------------------ first implementation here
66
LL |
7-
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
7+
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)`
99
|
1010
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
1111

tests/ui/coherence/normalize-for-errors.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
//[next] compile-flags: -Ztrait-solver=next
33

44
struct MyType;
5-
trait MyTrait {
6-
}
5+
trait MyTrait<S> {}
76

87
trait Mirror {
98
type Assoc;
@@ -12,11 +11,11 @@ impl<T> Mirror for T {
1211
type Assoc = T;
1312
}
1413

15-
impl<T: Copy> MyTrait for T {}
14+
impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
1615
//~^ NOTE first implementation here
17-
impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
18-
//~^ ERROR conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
19-
//~| NOTE conflicting implementation for `Box<(MyType,)>
16+
impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
17+
//~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
18+
//~| NOTE conflicting implementation for `(Box<(MyType,)>,
2019
//~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
2120

2221
fn main() {}

0 commit comments

Comments
 (0)