Skip to content

Commit e459e82

Browse files
authored
Unrolled build for rust-lang#133520
Rollup merge of rust-lang#133520 - compiler-errors:structurally-resolve-mir-borrowck, r=lcnr Structurally resolve before applying projection in borrowck As far as I can tell, all other `.normalize` calls in borrowck are noops and can remain that way. This is the only one that actually requires structurally resolving the type. r? lcnr
2 parents eddb717 + 26c7774 commit e459e82

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

Diff for: compiler/rustc_borrowck/src/type_check/canonical.rs

+36
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory;
77
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
88
use rustc_span::Span;
99
use rustc_span::def_id::DefId;
10+
use rustc_trait_selection::solve::NoSolution;
1011
use rustc_trait_selection::traits::ObligationCause;
1112
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1213
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
@@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
177178
if self.infcx.next_trait_solver() {
178179
let body = self.body;
179180
let param_env = self.infcx.param_env;
181+
// FIXME: Make this into a real type op?
180182
self.fully_perform_op(
181183
location.to_locations(),
182184
ConstraintCategory::Boring,
@@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
213215
}
214216
}
215217

218+
#[instrument(skip(self), level = "debug")]
219+
pub(super) fn structurally_resolve(
220+
&mut self,
221+
ty: Ty<'tcx>,
222+
location: impl NormalizeLocation,
223+
) -> Ty<'tcx> {
224+
if self.infcx.next_trait_solver() {
225+
let body = self.body;
226+
let param_env = self.infcx.param_env;
227+
// FIXME: Make this into a real type op?
228+
self.fully_perform_op(
229+
location.to_locations(),
230+
ConstraintCategory::Boring,
231+
CustomTypeOp::new(
232+
|ocx| {
233+
ocx.structurally_normalize(
234+
&ObligationCause::misc(
235+
location.to_locations().span(body),
236+
body.source.def_id().expect_local(),
237+
),
238+
param_env,
239+
ty,
240+
)
241+
.map_err(|_| NoSolution)
242+
},
243+
"normalizing struct tail",
244+
),
245+
)
246+
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar))
247+
} else {
248+
self.normalize(ty, location)
249+
}
250+
}
251+
216252
#[instrument(skip(self), level = "debug")]
217253
pub(super) fn ascribe_user_type(
218254
&mut self,

Diff for: compiler/rustc_borrowck/src/type_check/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10641064
let tcx = self.infcx.tcx;
10651065

10661066
for proj in &user_ty.projs {
1067-
if let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() {
1067+
if !self.infcx.next_trait_solver()
1068+
&& let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind()
1069+
{
10681070
// There is nothing that we can compare here if we go through an opaque type.
10691071
// We're always in its defining scope as we can otherwise not project through
10701072
// it, so we're constraining it anyways.
@@ -1075,7 +1077,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10751077
proj,
10761078
|this, field, ()| {
10771079
let ty = this.field_ty(tcx, field);
1078-
self.normalize(ty, locations)
1080+
self.structurally_resolve(ty, locations)
10791081
},
10801082
|_, _| unreachable!(),
10811083
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
trait Interner: Sized {
5+
type Value;
6+
}
7+
8+
enum Kind<I: Interner> {
9+
Value(I::Value),
10+
}
11+
12+
struct Intern;
13+
14+
impl Interner for Intern {
15+
type Value = Wrap<u32>;
16+
}
17+
18+
struct Wrap<T>(T);
19+
20+
type KindAlias = Kind<Intern>;
21+
22+
trait PrettyPrinter: Sized {
23+
fn hello(c: KindAlias) {
24+
match c {
25+
KindAlias::Value(Wrap(v)) => {
26+
println!("{v:?}");
27+
}
28+
}
29+
}
30+
}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)