Skip to content

Commit af58fc8

Browse files
committed
Auto merge of #101947 - aliemjay:astconv-normalize, r=lcnr
Don't normalize in AstConv See individual commits. Fixes #101350 Fixes #54940
2 parents 89e0576 + bf228ac commit af58fc8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1182
-503
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

+74-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::fmt;
22

3-
use rustc_infer::infer::canonical::Canonical;
4-
use rustc_infer::traits::query::NoSolution;
3+
use rustc_infer::infer::{canonical::Canonical, InferOk};
54
use rustc_middle::mir::ConstraintCategory;
6-
use rustc_middle::ty::{self, ToPredicate, TypeFoldable};
5+
use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable};
76
use rustc_span::def_id::DefId;
87
use rustc_span::Span;
98
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
10-
use rustc_trait_selection::traits::query::Fallible;
9+
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
10+
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
1111

1212
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
1313

@@ -177,4 +177,74 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
177177
value
178178
})
179179
}
180+
181+
#[instrument(skip(self), level = "debug")]
182+
pub(super) fn ascribe_user_type(
183+
&mut self,
184+
mir_ty: Ty<'tcx>,
185+
user_ty: ty::UserType<'tcx>,
186+
span: Span,
187+
) {
188+
// FIXME: Ideally MIR types are normalized, but this is not always true.
189+
let mir_ty = self.normalize(mir_ty, Locations::All(span));
190+
191+
self.fully_perform_op(
192+
Locations::All(span),
193+
ConstraintCategory::Boring,
194+
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(mir_ty, user_ty)),
195+
)
196+
.unwrap_or_else(|err| {
197+
span_mirbug!(
198+
self,
199+
span,
200+
"ascribe_user_type `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
201+
);
202+
});
203+
}
204+
205+
/// *Incorrectly* skips the WF checks we normally do in `ascribe_user_type`.
206+
///
207+
/// FIXME(#104478, #104477): This is a hack for backward-compatibility.
208+
#[instrument(skip(self), level = "debug")]
209+
pub(super) fn ascribe_user_type_skip_wf(
210+
&mut self,
211+
mir_ty: Ty<'tcx>,
212+
user_ty: ty::UserType<'tcx>,
213+
span: Span,
214+
) {
215+
let ty::UserType::Ty(user_ty) = user_ty else { bug!() };
216+
217+
// A fast path for a common case with closure input/output types.
218+
if let ty::Infer(_) = user_ty.kind() {
219+
self.eq_types(user_ty, mir_ty, Locations::All(span), ConstraintCategory::Boring)
220+
.unwrap();
221+
return;
222+
}
223+
224+
let mir_ty = self.normalize(mir_ty, Locations::All(span));
225+
let cause = ObligationCause::dummy_with_span(span);
226+
let param_env = self.param_env;
227+
let op = |infcx: &'_ _| {
228+
let ocx = ObligationCtxt::new_in_snapshot(infcx);
229+
let user_ty = ocx.normalize(&cause, param_env, user_ty);
230+
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
231+
if !ocx.select_all_or_error().is_empty() {
232+
return Err(NoSolution);
233+
}
234+
Ok(InferOk { value: (), obligations: vec![] })
235+
};
236+
237+
self.fully_perform_op(
238+
Locations::All(span),
239+
ConstraintCategory::Boring,
240+
type_op::custom::CustomTypeOp::new(op, || "ascribe_user_type_skip_wf".to_string()),
241+
)
242+
.unwrap_or_else(|err| {
243+
span_mirbug!(
244+
self,
245+
span,
246+
"ascribe_user_type_skip_wf `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
247+
);
248+
});
249+
}
180250
}

compiler/rustc_borrowck/src/type_check/input_output.rs

+47-79
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,60 @@
1010
use rustc_index::vec::Idx;
1111
use rustc_infer::infer::LateBoundRegionConversionTime;
1212
use rustc_middle::mir::*;
13-
use rustc_middle::ty::Ty;
13+
use rustc_middle::ty::{self, Ty};
1414
use rustc_span::Span;
1515

1616
use crate::universal_regions::UniversalRegions;
1717

1818
use super::{Locations, TypeChecker};
1919

2020
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21+
/// Check explicit closure signature annotation,
22+
/// e.g., `|x: FxHashMap<_, &'static u32>| ...`.
23+
#[instrument(skip(self, body), level = "debug")]
24+
pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) {
25+
let mir_def_id = body.source.def_id().expect_local();
26+
if !self.tcx().is_closure(mir_def_id.to_def_id()) {
27+
return;
28+
}
29+
let Some(user_provided_poly_sig) =
30+
self.tcx().typeck(mir_def_id).user_provided_sigs.get(&mir_def_id)
31+
else {
32+
return;
33+
};
34+
35+
// Instantiate the canonicalized variables from user-provided signature
36+
// (e.g., the `_` in the code above) with fresh variables.
37+
// Then replace the bound items in the fn sig with fresh variables,
38+
// so that they represent the view from "inside" the closure.
39+
let user_provided_sig = self
40+
.instantiate_canonical_with_fresh_inference_vars(body.span, &user_provided_poly_sig);
41+
let user_provided_sig = self.infcx.replace_bound_vars_with_fresh_vars(
42+
body.span,
43+
LateBoundRegionConversionTime::FnCall,
44+
user_provided_sig,
45+
);
46+
47+
for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip(
48+
// In MIR, closure args begin with an implicit `self`. Skip it!
49+
body.args_iter().skip(1).map(|local| &body.local_decls[local]),
50+
) {
51+
self.ascribe_user_type_skip_wf(
52+
arg_decl.ty,
53+
ty::UserType::Ty(user_ty),
54+
arg_decl.source_info.span,
55+
);
56+
}
57+
58+
// If the user explicitly annotated the output type, enforce it.
59+
let output_decl = &body.local_decls[RETURN_PLACE];
60+
self.ascribe_user_type_skip_wf(
61+
output_decl.ty,
62+
ty::UserType::Ty(user_provided_sig.output()),
63+
output_decl.source_info.span,
64+
);
65+
}
66+
2167
#[instrument(skip(self, body, universal_regions), level = "debug")]
2268
pub(super) fn equate_inputs_and_outputs(
2369
&mut self,
@@ -31,39 +77,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
3177
debug!(?normalized_output_ty);
3278
debug!(?normalized_input_tys);
3379

34-
let mir_def_id = body.source.def_id().expect_local();
35-
36-
// If the user explicitly annotated the input types, extract
37-
// those.
38-
//
39-
// e.g., `|x: FxHashMap<_, &'static u32>| ...`
40-
let user_provided_sig = if !self.tcx().is_closure(mir_def_id.to_def_id()) {
41-
None
42-
} else {
43-
let typeck_results = self.tcx().typeck(mir_def_id);
44-
45-
typeck_results.user_provided_sigs.get(&mir_def_id).map(|user_provided_poly_sig| {
46-
// Instantiate the canonicalized variables from
47-
// user-provided signature (e.g., the `_` in the code
48-
// above) with fresh variables.
49-
let poly_sig = self.instantiate_canonical_with_fresh_inference_vars(
50-
body.span,
51-
&user_provided_poly_sig,
52-
);
53-
54-
// Replace the bound items in the fn sig with fresh
55-
// variables, so that they represent the view from
56-
// "inside" the closure.
57-
self.infcx.replace_bound_vars_with_fresh_vars(
58-
body.span,
59-
LateBoundRegionConversionTime::FnCall,
60-
poly_sig,
61-
)
62-
})
63-
};
64-
65-
debug!(?normalized_input_tys, ?body.local_decls);
66-
6780
// Equate expected input tys with those in the MIR.
6881
for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() {
6982
if argument_index + 1 >= body.local_decls.len() {
@@ -86,28 +99,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8699
);
87100
}
88101

89-
if let Some(user_provided_sig) = user_provided_sig {
90-
for (argument_index, &user_provided_input_ty) in
91-
user_provided_sig.inputs().iter().enumerate()
92-
{
93-
// In MIR, closures begin an implicit `self`, so
94-
// argument N is stored in local N+2.
95-
let local = Local::new(argument_index + 2);
96-
let mir_input_ty = body.local_decls[local].ty;
97-
let mir_input_span = body.local_decls[local].source_info.span;
98-
99-
// If the user explicitly annotated the input types, enforce those.
100-
let user_provided_input_ty =
101-
self.normalize(user_provided_input_ty, Locations::All(mir_input_span));
102-
103-
self.equate_normalized_input_or_output(
104-
user_provided_input_ty,
105-
mir_input_ty,
106-
mir_input_span,
107-
);
108-
}
109-
}
110-
111102
debug!(
112103
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
113104
body.yield_ty(),
@@ -153,29 +144,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
153144
terr
154145
);
155146
};
156-
157-
// If the user explicitly annotated the output types, enforce those.
158-
// Note that this only happens for closures.
159-
if let Some(user_provided_sig) = user_provided_sig {
160-
let user_provided_output_ty = user_provided_sig.output();
161-
let user_provided_output_ty =
162-
self.normalize(user_provided_output_ty, Locations::All(output_span));
163-
if let Err(err) = self.eq_types(
164-
user_provided_output_ty,
165-
mir_output_ty,
166-
Locations::All(output_span),
167-
ConstraintCategory::BoringNoLocation,
168-
) {
169-
span_mirbug!(
170-
self,
171-
Location::START,
172-
"equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
173-
mir_output_ty,
174-
user_provided_output_ty,
175-
err
176-
);
177-
}
178-
}
179147
}
180148

181149
#[instrument(skip(self), level = "debug")]

compiler/rustc_borrowck/src/type_check/mod.rs

+9-67
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use rustc_middle::ty::{
3838
use rustc_span::def_id::CRATE_DEF_ID;
3939
use rustc_span::{Span, DUMMY_SP};
4040
use rustc_target::abi::VariantIdx;
41-
use rustc_trait_selection::traits::query::type_op;
4241
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
4342
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
4443
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@@ -197,6 +196,8 @@ pub(crate) fn type_check<'mir, 'tcx>(
197196
}
198197

199198
checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
199+
checker.check_signature_annotation(&body);
200+
200201
liveness::generate(
201202
&mut checker,
202203
body,
@@ -391,23 +392,14 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
391392
check_err(self, promoted_body, ty, promoted_ty);
392393
}
393394
} else {
394-
if let Err(terr) = self.cx.fully_perform_op(
395-
locations,
396-
ConstraintCategory::Boring,
397-
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
398-
constant.literal.ty(),
395+
self.cx.ascribe_user_type(
396+
constant.literal.ty(),
397+
UserType::TypeOf(
399398
uv.def.did,
400399
UserSubsts { substs: uv.substs, user_self_ty: None },
401-
)),
402-
) {
403-
span_mirbug!(
404-
self,
405-
constant,
406-
"bad constant type {:?} ({:?})",
407-
constant,
408-
terr
409-
);
410-
}
400+
),
401+
locations.span(&self.cx.body),
402+
);
411403
}
412404
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
413405
let unnormalized_ty = tcx.type_of(static_def_id);
@@ -1041,58 +1033,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10411033
debug!(?self.user_type_annotations);
10421034
for user_annotation in self.user_type_annotations {
10431035
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
1044-
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
10451036
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
1046-
debug!(?annotation);
1047-
match annotation {
1048-
UserType::Ty(mut ty) => {
1049-
ty = self.normalize(ty, Locations::All(span));
1050-
1051-
if let Err(terr) = self.eq_types(
1052-
ty,
1053-
inferred_ty,
1054-
Locations::All(span),
1055-
ConstraintCategory::BoringNoLocation,
1056-
) {
1057-
span_mirbug!(
1058-
self,
1059-
user_annotation,
1060-
"bad user type ({:?} = {:?}): {:?}",
1061-
ty,
1062-
inferred_ty,
1063-
terr
1064-
);
1065-
}
1066-
1067-
self.prove_predicate(
1068-
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())),
1069-
Locations::All(span),
1070-
ConstraintCategory::TypeAnnotation,
1071-
);
1072-
}
1073-
UserType::TypeOf(def_id, user_substs) => {
1074-
if let Err(terr) = self.fully_perform_op(
1075-
Locations::All(span),
1076-
ConstraintCategory::BoringNoLocation,
1077-
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
1078-
inferred_ty,
1079-
def_id,
1080-
user_substs,
1081-
)),
1082-
) {
1083-
span_mirbug!(
1084-
self,
1085-
user_annotation,
1086-
"bad user type AscribeUserType({:?}, {:?} {:?}, type_of={:?}): {:?}",
1087-
inferred_ty,
1088-
def_id,
1089-
user_substs,
1090-
self.tcx().type_of(def_id),
1091-
terr,
1092-
);
1093-
}
1094-
}
1095-
}
1037+
self.ascribe_user_type(inferred_ty, annotation, span);
10961038
}
10971039
}
10981040

0 commit comments

Comments
 (0)