Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 46c3c01

Browse files
Rollup merge of rust-lang#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
2 parents 174e73a + 68c2f11 commit 46c3c01

19 files changed

+158
-96
lines changed

compiler/rustc_hir_analysis/src/autoderef.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
7474
// we have some type like `&<Ty as Trait>::Assoc`, since users of
7575
// autoderef expect this type to have been structurally normalized.
7676
if self.infcx.next_trait_solver()
77-
&& let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = ty.kind()
77+
&& let ty::Alias(..) = ty.kind()
7878
{
7979
let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
8080
self.state.obligations.extend(obligations);

compiler/rustc_trait_selection/src/solve/normalize.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_infer::infer::InferCtxt;
88
use rustc_infer::traits::TraitEngineExt;
99
use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
1010
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
11-
use rustc_middle::traits::{ObligationCause, Reveal};
11+
use rustc_middle::traits::ObligationCause;
1212
use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
1313
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
1414
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
@@ -52,14 +52,16 @@ struct NormalizationFolder<'me, 'tcx> {
5252
impl<'tcx> NormalizationFolder<'_, 'tcx> {
5353
fn normalize_alias_ty(
5454
&mut self,
55-
alias: AliasTy<'tcx>,
55+
alias_ty: Ty<'tcx>,
5656
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
57+
assert!(matches!(alias_ty.kind(), ty::Alias(..)));
58+
5759
let infcx = self.at.infcx;
5860
let tcx = infcx.tcx;
5961
let recursion_limit = tcx.recursion_limit();
6062
if !recursion_limit.value_within_limit(self.depth) {
6163
self.at.infcx.err_ctxt().report_overflow_error(
62-
&alias.to_ty(tcx),
64+
&alias_ty,
6365
self.at.cause.span,
6466
true,
6567
|_| {},
@@ -76,7 +78,11 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
7678
tcx,
7779
self.at.cause.clone(),
7880
self.at.param_env,
79-
ty::NormalizesTo { alias, term: new_infer_ty.into() },
81+
ty::PredicateKind::AliasRelate(
82+
alias_ty.into(),
83+
new_infer_ty.into(),
84+
ty::AliasRelationDirection::Equate,
85+
),
8086
);
8187

8288
// Do not emit an error if normalization is known to fail but instead
@@ -90,9 +96,12 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
9096
return Err(errors);
9197
}
9298
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
93-
ty.try_fold_with(self)?
99+
100+
// Alias is guaranteed to be fully structurally resolved,
101+
// so we can super fold here.
102+
ty.try_super_fold_with(self)?
94103
} else {
95-
alias.to_ty(tcx).try_super_fold_with(self)?
104+
alias_ty.try_super_fold_with(self)?
96105
};
97106

98107
self.depth -= 1;
@@ -170,24 +179,18 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
170179
}
171180

172181
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
173-
let reveal = self.at.param_env.reveal();
174182
let infcx = self.at.infcx;
175183
debug_assert_eq!(ty, infcx.shallow_resolve(ty));
176-
if !needs_normalization(&ty, reveal) {
184+
if !ty.has_projections() {
177185
return Ok(ty);
178186
}
179187

180-
// We don't normalize opaque types unless we have
181-
// `Reveal::All`, even if we're in the defining scope.
182-
let data = match *ty.kind() {
183-
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
184-
_ => return ty.try_super_fold_with(self),
185-
};
188+
let ty::Alias(..) = *ty.kind() else { return ty.try_super_fold_with(self) };
186189

187-
if data.has_escaping_bound_vars() {
188-
let (data, mapped_regions, mapped_types, mapped_consts) =
189-
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
190-
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(data))?;
190+
if ty.has_escaping_bound_vars() {
191+
let (ty, mapped_regions, mapped_types, mapped_consts) =
192+
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
193+
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
191194
Ok(PlaceholderReplacer::replace_placeholders(
192195
infcx,
193196
mapped_regions,
@@ -197,7 +200,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
197200
result,
198201
))
199202
} else {
200-
ensure_sufficient_stack(|| self.normalize_alias_ty(data))
203+
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
201204
}
202205
}
203206

compiler/rustc_trait_selection/src/traits/structural_normalize.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
2222
assert!(!ty.is_ty_var(), "should have resolved vars before calling");
2323

2424
if self.infcx.next_trait_solver() {
25-
// FIXME(-Znext-solver): Should we resolve opaques here?
26-
let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) = *ty.kind() else {
25+
let ty::Alias(..) = *ty.kind() else {
2726
return Ok(ty);
2827
};
2928

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
error[E0391]: cycle detected when type-checking `foo`
2+
--> $DIR/clone-rpit.rs:12:1
3+
|
4+
LL | pub fn foo<'a, 'b>() -> impl Clone {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires coroutine witness types for `foo::{closure#0}`...
8+
--> $DIR/clone-rpit.rs:13:5
9+
|
10+
LL | move |_: ()| {
11+
| ^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `foo::{closure#0}`...
13+
--> $DIR/clone-rpit.rs:13:5
14+
|
15+
LL | move |_: ()| {
16+
| ^^^^^^^^^^^^
17+
note: ...which requires preparing `foo::{closure#0}` for borrow checking...
18+
--> $DIR/clone-rpit.rs:13:5
19+
|
20+
LL | move |_: ()| {
21+
| ^^^^^^^^^^^^
22+
note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls...
23+
--> $DIR/clone-rpit.rs:13:5
24+
|
25+
LL | move |_: ()| {
26+
| ^^^^^^^^^^^^
27+
note: ...which requires building MIR for `foo::{closure#0}`...
28+
--> $DIR/clone-rpit.rs:13:5
29+
|
30+
LL | move |_: ()| {
31+
| ^^^^^^^^^^^^
32+
note: ...which requires match-checking `foo::{closure#0}`...
33+
--> $DIR/clone-rpit.rs:13:5
34+
|
35+
LL | move |_: ()| {
36+
| ^^^^^^^^^^^^
37+
note: ...which requires type-checking `foo::{closure#0}`...
38+
--> $DIR/clone-rpit.rs:13:5
39+
|
40+
LL | move |_: ()| {
41+
| ^^^^^^^^^^^^
42+
= note: ...which again requires type-checking `foo`, completing the cycle
43+
note: cycle used when computing type of opaque `foo::{opaque#0}`
44+
--> $DIR/clone-rpit.rs:12:25
45+
|
46+
LL | pub fn foo<'a, 'b>() -> impl Clone {
47+
| ^^^^^^^^^^
48+
= 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
49+
50+
error: aborting due to 1 previous error
51+
52+
For more information about this error, try `rustc --explain E0391`.

tests/ui/coroutine/clone-rpit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// revisions: current next
22
//[next] compile-flags: -Znext-solver
3-
// check-pass
3+
//[current] check-pass
4+
//[next] known-bug: trait-system-refactor-initiative#82
45

56
#![feature(coroutines, coroutine_trait, coroutine_clone)]
67

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// check-pass
2+
// compile-flags: -Znext-solver
3+
4+
#![feature(type_alias_impl_trait)]
5+
6+
fn main() {
7+
type Tait = impl Sized;
8+
struct S {
9+
i: i32,
10+
}
11+
let x: Tait = S { i: 0 };
12+
println!("{}", x.i);
13+
}

tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0733]: recursion in a coroutine requires boxing
2-
--> $DIR/recursive-coroutine-indirect.rs:6:5
2+
--> $DIR/recursive-coroutine-indirect.rs:10:5
33
|
44
LL | move || {
55
| ^^^^^^^

tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0733]: recursion in a coroutine requires boxing
2-
--> $DIR/recursive-coroutine-indirect.rs:6:5
2+
--> $DIR/recursive-coroutine-indirect.rs:10:5
33
|
44
LL | move || {
55
| ^^^^^^^

tests/ui/impl-trait/recursive-coroutine-indirect.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// revisions: current next
22
//[next] compile-flags: -Znext-solver
3+
4+
//[next] build-fail
5+
// Deeply normalizing writeback results of opaques makes this into a post-mono error :(
6+
37
#![feature(coroutines)]
48
#![allow(unconditional_recursion)]
59
fn coroutine_hold() -> impl Sized {

tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ fn main() {
1313
}
1414

1515
fn weird0() -> impl Sized + !Sized {}
16-
//~^ ERROR mismatched types
17-
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
16+
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
1817
fn weird1() -> impl !Sized + Sized {}
19-
//~^ ERROR mismatched types
20-
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
18+
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
2119
fn weird2() -> impl !Sized {}
22-
//~^ ERROR mismatched types
23-
//~| ERROR type mismatch resolving `() == impl !Sized`
20+
//~^ ERROR type mismatch resolving `() == impl !Sized`

0 commit comments

Comments
 (0)