Skip to content

Commit f00f3a9

Browse files
Structurally resolve before applying projection in borrowck
1 parent 0c19547 commit f00f3a9

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

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,

compiler/rustc_borrowck/src/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10751075
proj,
10761076
|this, field, ()| {
10771077
let ty = this.field_ty(tcx, field);
1078-
self.normalize(ty, locations)
1078+
self.structurally_resolve(ty, locations)
10791079
},
10801080
|_, _| unreachable!(),
10811081
);
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+
pub 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)