Rollup merge of #119817 - compiler-errors:normalize-opaques, r=lcnr
Remove special-casing around `AliasKind::Opaque` when structurally resolving in new solver This fixes a few inconsistencies around where we don't eagerly resolve opaques to their (locally-defined) hidden types in the new solver. It essentially allows this code to work: ```rust fn main() { type Tait = impl Sized; struct S { i: i32, } let x: Tait = S { i: 0 }; println!("{}", x.i); } ``` Since `Tait` is defined in `main`, we are able to poke through the type of `x` with deref. r? lcnr
This commit is contained in:
commit
46c3c014eb
@ -74,7 +74,7 @@ fn next(&mut self) -> Option<Self::Item> {
|
||||
// we have some type like `&<Ty as Trait>::Assoc`, since users of
|
||||
// autoderef expect this type to have been structurally normalized.
|
||||
if self.infcx.next_trait_solver()
|
||||
&& let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = ty.kind()
|
||||
&& let ty::Alias(..) = ty.kind()
|
||||
{
|
||||
let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
|
||||
self.state.obligations.extend(obligations);
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_infer::traits::TraitEngineExt;
|
||||
use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_middle::traits::{ObligationCause, Reveal};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
|
||||
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
||||
@ -52,14 +52,16 @@ struct NormalizationFolder<'me, 'tcx> {
|
||||
impl<'tcx> NormalizationFolder<'_, 'tcx> {
|
||||
fn normalize_alias_ty(
|
||||
&mut self,
|
||||
alias: AliasTy<'tcx>,
|
||||
alias_ty: Ty<'tcx>,
|
||||
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
|
||||
assert!(matches!(alias_ty.kind(), ty::Alias(..)));
|
||||
|
||||
let infcx = self.at.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
let recursion_limit = tcx.recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.at.infcx.err_ctxt().report_overflow_error(
|
||||
&alias.to_ty(tcx),
|
||||
&alias_ty,
|
||||
self.at.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
@ -76,7 +78,11 @@ fn normalize_alias_ty(
|
||||
tcx,
|
||||
self.at.cause.clone(),
|
||||
self.at.param_env,
|
||||
ty::NormalizesTo { alias, term: new_infer_ty.into() },
|
||||
ty::PredicateKind::AliasRelate(
|
||||
alias_ty.into(),
|
||||
new_infer_ty.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
);
|
||||
|
||||
// Do not emit an error if normalization is known to fail but instead
|
||||
@ -90,9 +96,12 @@ fn normalize_alias_ty(
|
||||
return Err(errors);
|
||||
}
|
||||
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
|
||||
ty.try_fold_with(self)?
|
||||
|
||||
// Alias is guaranteed to be fully structurally resolved,
|
||||
// so we can super fold here.
|
||||
ty.try_super_fold_with(self)?
|
||||
} else {
|
||||
alias.to_ty(tcx).try_super_fold_with(self)?
|
||||
alias_ty.try_super_fold_with(self)?
|
||||
};
|
||||
|
||||
self.depth -= 1;
|
||||
@ -170,24 +179,18 @@ fn try_fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
}
|
||||
|
||||
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
let reveal = self.at.param_env.reveal();
|
||||
let infcx = self.at.infcx;
|
||||
debug_assert_eq!(ty, infcx.shallow_resolve(ty));
|
||||
if !needs_normalization(&ty, reveal) {
|
||||
if !ty.has_projections() {
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
// We don't normalize opaque types unless we have
|
||||
// `Reveal::All`, even if we're in the defining scope.
|
||||
let data = match *ty.kind() {
|
||||
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
|
||||
_ => return ty.try_super_fold_with(self),
|
||||
};
|
||||
let ty::Alias(..) = *ty.kind() else { return ty.try_super_fold_with(self) };
|
||||
|
||||
if data.has_escaping_bound_vars() {
|
||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
||||
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(data))?;
|
||||
if ty.has_escaping_bound_vars() {
|
||||
let (ty, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
|
||||
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
|
||||
Ok(PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
@ -197,7 +200,7 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
result,
|
||||
))
|
||||
} else {
|
||||
ensure_sufficient_stack(|| self.normalize_alias_ty(data))
|
||||
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,7 @@ fn structurally_normalize(
|
||||
assert!(!ty.is_ty_var(), "should have resolved vars before calling");
|
||||
|
||||
if self.infcx.next_trait_solver() {
|
||||
// FIXME(-Znext-solver): Should we resolve opaques here?
|
||||
let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = *ty.kind() else {
|
||||
let ty::Alias(..) = *ty.kind() else {
|
||||
return Ok(ty);
|
||||
};
|
||||
|
||||
|
52
tests/ui/coroutine/clone-rpit.next.stderr
Normal file
52
tests/ui/coroutine/clone-rpit.next.stderr
Normal file
@ -0,0 +1,52 @@
|
||||
error[E0391]: cycle detected when type-checking `foo`
|
||||
--> $DIR/clone-rpit.rs:12:1
|
||||
|
|
||||
LL | pub fn foo<'a, 'b>() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires coroutine witness types for `foo::{closure#0}`...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires promoting constants in MIR for `foo::{closure#0}`...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires preparing `foo::{closure#0}` for borrow checking...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires building MIR for `foo::{closure#0}`...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires match-checking `foo::{closure#0}`...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
note: ...which requires type-checking `foo::{closure#0}`...
|
||||
--> $DIR/clone-rpit.rs:13:5
|
||||
|
|
||||
LL | move |_: ()| {
|
||||
| ^^^^^^^^^^^^
|
||||
= note: ...which again requires type-checking `foo`, completing the cycle
|
||||
note: cycle used when computing type of opaque `foo::{opaque#0}`
|
||||
--> $DIR/clone-rpit.rs:12:25
|
||||
|
|
||||
LL | pub fn foo<'a, 'b>() -> impl Clone {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
@ -1,6 +1,7 @@
|
||||
// revisions: current next
|
||||
//[next] compile-flags: -Znext-solver
|
||||
// check-pass
|
||||
//[current] check-pass
|
||||
//[next] known-bug: trait-system-refactor-initiative#82
|
||||
|
||||
#![feature(coroutines, coroutine_trait, coroutine_clone)]
|
||||
|
||||
|
13
tests/ui/impl-trait/eagerly-reveal-in-local-body.rs
Normal file
13
tests/ui/impl-trait/eagerly-reveal-in-local-body.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
// compile-flags: -Znext-solver
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn main() {
|
||||
type Tait = impl Sized;
|
||||
struct S {
|
||||
i: i32,
|
||||
}
|
||||
let x: Tait = S { i: 0 };
|
||||
println!("{}", x.i);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
error[E0733]: recursion in a coroutine requires boxing
|
||||
--> $DIR/recursive-coroutine-indirect.rs:6:5
|
||||
--> $DIR/recursive-coroutine-indirect.rs:10:5
|
||||
|
|
||||
LL | move || {
|
||||
| ^^^^^^^
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0733]: recursion in a coroutine requires boxing
|
||||
--> $DIR/recursive-coroutine-indirect.rs:6:5
|
||||
--> $DIR/recursive-coroutine-indirect.rs:10:5
|
||||
|
|
||||
LL | move || {
|
||||
| ^^^^^^^
|
||||
|
@ -1,5 +1,9 @@
|
||||
// revisions: current next
|
||||
//[next] compile-flags: -Znext-solver
|
||||
|
||||
//[next] build-fail
|
||||
// Deeply normalizing writeback results of opaques makes this into a post-mono error :(
|
||||
|
||||
#![feature(coroutines)]
|
||||
#![allow(unconditional_recursion)]
|
||||
fn coroutine_hold() -> impl Sized {
|
||||
|
@ -13,11 +13,8 @@ fn main() {
|
||||
}
|
||||
|
||||
fn weird0() -> impl Sized + !Sized {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||
fn weird1() -> impl !Sized + Sized {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||
fn weird2() -> impl !Sized {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR type mismatch resolving `() == impl !Sized`
|
||||
//~^ ERROR type mismatch resolving `() == impl !Sized`
|
||||
|
@ -1,50 +1,17 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:36
|
||||
|
|
||||
LL | fn weird0() -> impl Sized + !Sized {}
|
||||
| ------------------- ^^ types differ
|
||||
| |
|
||||
| the expected opaque type
|
||||
|
|
||||
= note: expected opaque type `impl !Sized + Sized`
|
||||
found unit type `()`
|
||||
|
||||
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
||||
|
|
||||
LL | fn weird0() -> impl Sized + !Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:18:36
|
||||
|
|
||||
LL | fn weird1() -> impl !Sized + Sized {}
|
||||
| ------------------- ^^ types differ
|
||||
| |
|
||||
| the expected opaque type
|
||||
|
|
||||
= note: expected opaque type `impl !Sized + Sized`
|
||||
found unit type `()`
|
||||
|
||||
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:18:16
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
||||
|
|
||||
LL | fn weird1() -> impl !Sized + Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:21:28
|
||||
|
|
||||
LL | fn weird2() -> impl !Sized {}
|
||||
| ----------- ^^ types differ
|
||||
| |
|
||||
| the expected opaque type
|
||||
|
|
||||
= note: expected opaque type `impl !Sized`
|
||||
found unit type `()`
|
||||
|
||||
error[E0271]: type mismatch resolving `() == impl !Sized`
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:21:16
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||
|
|
||||
LL | fn weird2() -> impl !Sized {}
|
||||
| ^^^^^^^^^^^ types differ
|
||||
@ -63,7 +30,7 @@ note: required by a bound in `consume`
|
||||
LL | fn consume(_: impl Trait) {}
|
||||
| ^^^^^ required by this bound in `consume`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277, E0308.
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
|
@ -3,7 +3,6 @@
|
||||
#![feature(negative_bounds, unboxed_closures)]
|
||||
|
||||
fn produce() -> impl !Fn<(u32,)> {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
|
||||
//~^ ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,21 +1,9 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
|
||||
|
|
||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||
| ---------------- ^^ types differ
|
||||
| |
|
||||
| the expected opaque type
|
||||
|
|
||||
= note: expected opaque type `impl !Fn<(u32,)>`
|
||||
found unit type `()`
|
||||
|
||||
error[E0271]: type mismatch resolving `() == impl !Fn<(u32,)>`
|
||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
||||
|
|
||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||
| ^^^^^^^^^^^^^^^^ types differ
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Some errors have detailed explanations: E0271, E0308.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
|
@ -23,10 +23,10 @@ fn main() {
|
||||
let x = String::from("hello, world");
|
||||
drop(<() as Foo>::copy_me(&x));
|
||||
//~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Sized`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item normalizes-to _`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
println!("{x}");
|
||||
}
|
||||
|
@ -52,13 +52,14 @@ LL | drop(<() as Foo>::copy_me(&x));
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item normalizes-to _`
|
||||
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
--> $DIR/alias-bound-unsound.rs:24:10
|
||||
|
|
||||
LL | drop(<() as Foo>::copy_me(&x));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -13,8 +13,10 @@ fn needs_bar<S: Bar>() {}
|
||||
|
||||
fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() {
|
||||
needs_bar::<T::Assoc1>();
|
||||
//~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo2>::Assoc2`
|
||||
//~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `needs_bar`
|
||||
LL | fn needs_bar<S: Bar>() {}
|
||||
| ^^^ required by this bound in `needs_bar`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo2>::Assoc2`
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
--> $DIR/recursive-self-normalization-2.rs:15:5
|
||||
|
|
||||
LL | needs_bar::<T::Assoc1>();
|
||||
@ -19,6 +19,23 @@ LL | needs_bar::<T::Assoc1>();
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
--> $DIR/recursive-self-normalization-2.rs:15:5
|
||||
|
|
||||
LL | needs_bar::<T::Assoc1>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
|
||||
--> $DIR/recursive-self-normalization-2.rs:15:17
|
||||
|
|
||||
LL | needs_bar::<T::Assoc1>();
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
@ -9,8 +9,10 @@ fn needs_bar<S: Bar>() {}
|
||||
|
||||
fn test<T: Foo<Assoc = <T as Foo>::Assoc>>() {
|
||||
needs_bar::<T::Assoc>();
|
||||
//~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc` [E0275]
|
||||
//~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
//~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `needs_bar`
|
||||
LL | fn needs_bar<S: Bar>() {}
|
||||
| ^^^ required by this bound in `needs_bar`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc`
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
--> $DIR/recursive-self-normalization.rs:11:5
|
||||
|
|
||||
LL | needs_bar::<T::Assoc>();
|
||||
@ -19,6 +19,23 @@ LL | needs_bar::<T::Assoc>();
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
--> $DIR/recursive-self-normalization.rs:11:5
|
||||
|
|
||||
LL | needs_bar::<T::Assoc>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
|
||||
--> $DIR/recursive-self-normalization.rs:11:17
|
||||
|
|
||||
LL | needs_bar::<T::Assoc>();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
Loading…
Reference in New Issue
Block a user