Skip to content

Commit d7d439c

Browse files
committed
Misc cleanups to borrowck crate
1 parent fffc4fc commit d7d439c

File tree

10 files changed

+99
-38
lines changed

10 files changed

+99
-38
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
343343
return;
344344
}
345345

346-
// FIXME: Ideally MIR types are normalized, but this is not always true.
347-
let mir_ty = self.normalize(mir_ty, Locations::All(span));
346+
// This is a hack. `body.local_decls` are not necessarily normalized in the old
347+
// solver due to not deeply normalizing in writeback. So we must re-normalize here.
348+
//
349+
// I am not sure of a test case where this actually matters. There is a similar
350+
// hack in `equate_inputs_and_outputs` which does have associated test cases.
351+
let mir_ty = match self.infcx.next_trait_solver() {
352+
true => mir_ty,
353+
false => self.normalize(mir_ty, Locations::All(span)),
354+
};
348355

349356
let cause = ObligationCause::dummy_with_span(span);
350357
let param_env = self.infcx.param_env;
@@ -353,6 +360,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
353360
ConstraintCategory::Boring,
354361
type_op::custom::CustomTypeOp::new(
355362
|ocx| {
363+
// The `AscribeUserType` query would normally emit a wf
364+
// obligation for the unnormalized user_ty here. This is
365+
// where the "incorrectly skips the WF checks we normally do"
366+
// happens
356367
let user_ty = ocx.normalize(&cause, param_env, user_ty);
357368
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
358369
Ok(())

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
126126
);
127127
}
128128

129+
// FIXME(BoxyUwU): This should probably be part of a larger borrowck dev-guide chapter
130+
//
131+
/// Enforce that the types of the locals corresponding to the inputs and output of
132+
/// the body are equal to those of the (normalized) signature.
133+
///
134+
/// This is necessary for two reasons:
135+
/// - Locals in the MIR all start out with `'erased` regions and then are replaced
136+
/// with unconstrained nll vars. If we have a function returning `&'a u32` then
137+
/// the local `_0: &'?10 u32` needs to have its region var equated with the nll
138+
/// var representing `'a`. i.e. borrow check must uphold that `'?10 = 'a`.
139+
/// - When computing the normalized signature we may introduce new unconstrained nll
140+
/// vars due to higher ranked where clauses ([#136547]). We then wind up with implied
141+
/// bounds involving these vars.
142+
///
143+
/// For this reason it is important that we equate with the *normalized* signature
144+
/// which was produced when computing implied bounds. If we do not do so then we will
145+
/// wind up with implied bounds on nll vars which cannot actually be used as the nll
146+
/// var never gets related to anything.
147+
///
148+
/// For 'closure-like' bodies this function effectively relates the *inferred* signature
149+
/// of the closure against the locals corresponding to the closure's inputs/output. It *does
150+
/// not* relate the user provided types for the signature to the locals, this is handled
151+
/// separately by: [`TypeChecker::check_signature_annotation`].
152+
///
153+
/// [#136547]: <https://www.github.com/rust-lang/rust/issues/136547>
129154
#[instrument(skip(self), level = "debug")]
130155
pub(super) fn equate_inputs_and_outputs(&mut self, normalized_inputs_and_output: &[Ty<'tcx>]) {
131156
let (&normalized_output_ty, normalized_input_tys) =
@@ -173,38 +198,43 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
173198
);
174199
}
175200

176-
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
177-
let mir_output_ty = self.body.local_decls[RETURN_PLACE].ty;
201+
// Equate expected output ty with the type of the RETURN_PLACE in MIR
202+
let mir_output_ty = self.body.return_ty();
178203
let output_span = self.body.local_decls[RETURN_PLACE].source_info.span;
179204
self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span);
180205
}
181206

182207
#[instrument(skip(self), level = "debug")]
183208
fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) {
209+
if self.infcx.next_trait_solver() {
210+
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
211+
.unwrap_or_else(|terr| {
212+
span_mirbug!(
213+
self,
214+
Location::START,
215+
"equate_normalized_input_or_output: `{a:?}=={b:?}` failed with `{terr:?}`",
216+
);
217+
});
218+
}
219+
220+
// This is a hack. `body.local_decls` are not necessarily normalized in the old
221+
// solver due to not deeply normalizing in writeback. So we must re-normalize here.
222+
//
223+
// However, in most cases normalizing is unnecessary so we only do so if it may be
224+
// necessary for type equality to hold. This leads to some (very minor) performance
225+
// wins.
184226
if let Err(_) =
185227
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
186228
{
187-
// FIXME(jackh726): This is a hack. It's somewhat like
188-
// `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
189-
// like to normalize *before* inserting into `local_decls`, but
190-
// doing so ends up causing some other trouble.
191229
let b = self.normalize(b, Locations::All(span));
192-
193-
// Note: if we have to introduce new placeholders during normalization above, then we
194-
// won't have added those universes to the universe info, which we would want in
195-
// `relate_tys`.
196-
if let Err(terr) =
197-
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
198-
{
199-
span_mirbug!(
200-
self,
201-
Location::START,
202-
"equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`",
203-
a,
204-
b,
205-
terr
206-
);
207-
}
208-
}
230+
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
231+
.unwrap_or_else(|terr| {
232+
span_mirbug!(
233+
self,
234+
Location::START,
235+
"equate_normalized_input_or_output: `{a:?}=={b:?}` failed with `{terr:?}`",
236+
);
237+
});
238+
};
209239
}
210240
}

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,19 @@ pub(crate) fn type_check<'tcx>(
123123
known_type_outlives_obligations,
124124
} = free_region_relations::create(infcx, universal_regions, &mut constraints);
125125

126-
let pre_obligations = infcx.take_registered_region_obligations();
127-
assert!(
128-
pre_obligations.is_empty(),
129-
"there should be no incoming region obligations = {pre_obligations:#?}",
130-
);
131-
let pre_assumptions = infcx.take_registered_region_assumptions();
132-
assert!(
133-
pre_assumptions.is_empty(),
134-
"there should be no incoming region assumptions = {pre_assumptions:#?}",
135-
);
126+
{
127+
// Scope these variables so it's clear they're not used later
128+
let pre_obligations = infcx.take_registered_region_obligations();
129+
assert!(
130+
pre_obligations.is_empty(),
131+
"there should be no incoming region obligations = {pre_obligations:#?}",
132+
);
133+
let pre_assumptions = infcx.take_registered_region_assumptions();
134+
assert!(
135+
pre_assumptions.is_empty(),
136+
"there should be no incoming region assumptions = {pre_assumptions:#?}",
137+
);
138+
}
136139

137140
debug!(?normalized_inputs_and_output);
138141

compiler/rustc_middle/src/ty/util.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,8 @@ impl<'tcx> TyCtxt<'tcx> {
609609
/// have the same `DefKind`.
610610
///
611611
/// Note that closures have a `DefId`, but the closure *expression* also has a
612-
/// `HirId` that is located within the context where the closure appears (and, sadly,
613-
/// a corresponding `NodeId`, since those are not yet phased out). The parent of
614-
/// the closure's `DefId` will also be the context where it appears.
612+
/// `HirId` that is located within the context where the closure appears. The
613+
/// parent of the closure's `DefId` will also be the context where it appears.
615614
pub fn is_closure_like(self, def_id: DefId) -> bool {
616615
matches!(self.def_kind(def_id), DefKind::Closure)
617616
}

tests/ui/associated-types/normalization-generality-2.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@ build-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
// Ensures that we don't regress on "implementation is not general enough" when
47
// normalizating under binders. Unlike `normalization-generality.rs`, this also produces

tests/ui/associated-types/normalization-generality.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@ build-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
// Ensures that we don't regress on "implementation is not general enough" when
47
// normalizating under binders.

tests/ui/higher-ranked/trait-bounds/issue-88446.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
trait Yokeable<'a> {
47
type Output: 'a;

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
#![allow(unused)]
47

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
trait Yokeable<'a>: 'static {
47
type Output: 'a;

tests/ui/nll/issue-112604-closure-output-normalize.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
25

36
use higher_kinded_types::*;
47
mod higher_kinded_types {

0 commit comments

Comments
 (0)