Skip to content

Commit c1a89fc

Browse files
committed
Select user type annotations instead of cloning them.
1 parent 6fc8881 commit c1a89fc

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+2-23
Original file line numberDiff line numberDiff line change
@@ -948,16 +948,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
948948
/// Equate the inferred type and the annotated type for user type annotations
949949
#[instrument(skip(self), level = "debug")]
950950
fn check_user_type_annotations(&mut self) {
951-
// Promoted clone the `user_type_annotations` from their original body, because some
952-
// statements may refer to them. However, we don't want to apply the other type annotations
953-
// while checking the promoted: that would create spurious constraints that we won't be
954-
// able to verify. Instead, the annotations are checked on-demand before relating to the
955-
// actual type in MIR.
956-
if let DefKind::Promoted = self.tcx().def_kind(self.body.source.def_id()) {
957-
debug!("promoted: skipping user type annotations");
958-
return;
959-
}
960-
961951
debug!(?self.user_type_annotations);
962952
for user_annotation in self.user_type_annotations {
963953
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
@@ -1022,23 +1012,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10221012
locations: Locations,
10231013
category: ConstraintCategory<'tcx>,
10241014
) -> Fallible<()> {
1025-
let CanonicalUserTypeAnnotation {
1026-
span,
1027-
user_ty: ref canonical_user_ty,
1028-
inferred_ty: annotated_type,
1029-
} = self.user_type_annotations[user_ty.base];
1015+
let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
10301016
trace!(?annotated_type);
1031-
1032-
// We may have skipped checking the canonical annotation earlier, so do it now.
1033-
if let DefKind::Promoted = self.tcx().def_kind(self.body.source.def_id()) {
1034-
let annotation =
1035-
self.instantiate_canonical_with_fresh_inference_vars(span, canonical_user_ty);
1036-
self.ascribe_user_type(annotated_type, annotation, span);
1037-
}
1017+
let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
10381018

10391019
let tcx = self.infcx.tcx;
10401020

1041-
let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
10421021
for proj in &user_ty.projs {
10431022
if let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() {
10441023
// There is nothing that we can compare here if we go through an opaque type.

compiler/rustc_const_eval/src/transform/promote_consts.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
//! initialization and can otherwise silence errors, if
1313
//! move analysis runs after promotion on broken MIR.
1414
15+
use rustc_data_structures::fx::FxIndexSet;
1516
use rustc_hir as hir;
1617
use rustc_index::{IndexSlice, IndexVec};
1718
use rustc_middle::mir::traversal::ReversePostorderIter;
1819
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
1920
use rustc_middle::mir::*;
2021
use rustc_middle::ty::subst::InternalSubsts;
21-
use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt};
22+
use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt, UserTypeAnnotationIndex};
2223
use rustc_span::def_id::LocalDefId;
2324
use rustc_span::Span;
2425

@@ -881,6 +882,22 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
881882
let span = self.promoted.span;
882883
self.assign(RETURN_PLACE, rvalue, span);
883884

885+
// Copy user type annotations from the original body to the promoted.
886+
// We don't want to keep all the original annotations, as they may create
887+
// constants that borrowck will not be able to verify. However, we still
888+
// need some of them to borrow-check the promoted itself.
889+
//
890+
// We don't remove the cloned annotations from the original body, as they
891+
// are harmless there.
892+
let mut annotation_renumber =
893+
RenumberUserTypeAnnotations { tcx, mapping: FxIndexSet::default() };
894+
annotation_renumber.visit_body_preserves_cfg(&mut self.promoted);
895+
self.promoted.user_type_annotations = annotation_renumber
896+
.mapping
897+
.iter()
898+
.map(|&original_index| self.source.user_type_annotations[original_index].clone())
899+
.collect();
900+
884901
let source_def_id = self.source.source.def_id().expect_local();
885902
let feeder =
886903
tcx.at(span).create_def(source_def_id, hir::definitions::DefPathData::Promoted);
@@ -935,6 +952,23 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
935952
}
936953
}
937954

955+
/// Replaces type annotation indices.
956+
struct RenumberUserTypeAnnotations<'tcx> {
957+
tcx: TyCtxt<'tcx>,
958+
mapping: FxIndexSet<UserTypeAnnotationIndex>,
959+
}
960+
961+
impl<'tcx> MutVisitor<'tcx> for RenumberUserTypeAnnotations<'tcx> {
962+
fn tcx(&self) -> TyCtxt<'tcx> {
963+
self.tcx
964+
}
965+
966+
fn visit_user_type_annotation_index(&mut self, annotation: &mut UserTypeAnnotationIndex) {
967+
let (new_index, _) = self.mapping.insert_full(*annotation);
968+
*annotation = UserTypeAnnotationIndex::from_usize(new_index);
969+
}
970+
}
971+
938972
pub fn promote_candidates<'tcx>(
939973
body: &mut Body<'tcx>,
940974
tcx: TyCtxt<'tcx>,
@@ -970,7 +1004,7 @@ pub fn promote_candidates<'tcx>(
9701004
IndexVec::new(),
9711005
IndexVec::from_elem_n(scope, 1),
9721006
initial_locals,
973-
body.user_type_annotations.clone(),
1007+
IndexVec::new(),
9741008
0,
9751009
vec![],
9761010
body.span,

compiler/rustc_middle/src/mir/visit.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ macro_rules! make_mir_visitor {
156156
self.super_ascribe_user_ty(place, variance, user_ty, location);
157157
}
158158

159+
fn visit_user_type_annotation_index(
160+
&mut self,
161+
_index: $(& $mutability)? UserTypeAnnotationIndex,
162+
) {
163+
}
164+
159165
fn visit_coverage(
160166
&mut self,
161167
coverage: & $($mutability)? Coverage,
@@ -724,10 +730,13 @@ macro_rules! make_mir_visitor {
724730
_adt_def,
725731
_variant_index,
726732
substs,
727-
_user_substs,
733+
user_substs,
728734
_active_field_index
729735
) => {
730736
self.visit_substs(substs, location);
737+
if let Some(user_substs) = user_substs {
738+
self.visit_user_type_annotation_index($(& $mutability)? *user_substs);
739+
}
731740
}
732741
AggregateKind::Closure(
733742
_,
@@ -881,11 +890,14 @@ macro_rules! make_mir_visitor {
881890
) {
882891
let Constant {
883892
span,
884-
user_ty: _, // no visit method for this
893+
user_ty,
885894
literal,
886895
} = constant;
887896

888897
self.visit_span($(& $mutability)? *span);
898+
if let Some(user_ty) = user_ty {
899+
self.visit_user_type_annotation_index($(& $mutability)? *user_ty);
900+
}
889901
match literal {
890902
ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
891903
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
@@ -916,8 +928,9 @@ macro_rules! make_mir_visitor {
916928

917929
fn super_user_type_projection(
918930
&mut self,
919-
_ty: & $($mutability)? UserTypeProjection,
931+
ty: & $($mutability)? UserTypeProjection,
920932
) {
933+
self.visit_user_type_annotation_index($(&$mutability)? ty.base);
921934
}
922935

923936
fn super_user_type_annotation(

0 commit comments

Comments
 (0)