Skip to content

Commit

Permalink
Continue folding if deep normalizer fails
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Nov 28, 2023
1 parent e00fed4 commit 01c4e8e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 30 deletions.
54 changes: 40 additions & 14 deletions compiler/rustc_trait_selection/src/solve/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::{ObligationCause, Reveal};
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 super::FulfillmentCtxt;
Expand Down Expand Up @@ -42,19 +42,6 @@ pub(crate) fn deeply_normalize_with_skipped_universes<'tcx, T: TypeFoldable<TyCt
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> {
at: At<'me, 'tcx>,
fulfill_cx: FulfillmentCtxt<'tcx>,
Expand Down Expand Up @@ -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.clone().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))
}
}
10 changes: 5 additions & 5 deletions tests/ui/coherence/normalize-for-errors.current.stderr
Original file line number Diff line number Diff line change
@@ -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
|
LL | impl<T: Copy> MyTrait for T {}
| --------------------------- first implementation here
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
| ------------------------------------------------------ first implementation here
LL |
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/coherence/normalize-for-errors.next.stderr
Original file line number Diff line number Diff line change
@@ -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
|
LL | impl<T: Copy> MyTrait for T {}
| --------------------------- first implementation here
LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
| ------------------------------------------------------ first implementation here
LL |
LL | impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<(MyType,)>`
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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

Expand Down
11 changes: 5 additions & 6 deletions tests/ui/coherence/normalize-for-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
//[next] compile-flags: -Ztrait-solver=next

struct MyType;
trait MyTrait {
}
trait MyTrait<S> {}

trait Mirror {
type Assoc;
Expand All @@ -12,11 +11,11 @@ impl<T> Mirror for 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
impl MyTrait for Box<<(MyType,) as Mirror>::Assoc> {}
//~^ ERROR conflicting implementations of trait `MyTrait` for type `Box<(MyType,)>`
//~| NOTE conflicting implementation for `Box<(MyType,)>
impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
//~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(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

fn main() {}

0 comments on commit 01c4e8e

Please sign in to comment.