about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-02-20 12:19:14 +0000
committerbors <bors@rust-lang.org>2025-02-20 12:19:14 +0000
commit28b83ee59698ae069f5355b8e03f976406f410f5 (patch)
treed477a7efba087d5cf53d6f34132dac0e6fb29735
parentc62239aeb3ba7781a6d7f7055523c1e8c22b409c (diff)
parent8bb574fdd301dbb6ff18bd2500ccf463ce8a19d4 (diff)
downloadrust-28b83ee59698ae069f5355b8e03f976406f410f5.tar.gz
rust-28b83ee59698ae069f5355b8e03f976406f410f5.zip
Auto merge of #137123 - Zalathar:user-type-span, r=oli-obk
Don't store a redundant span in user-type projections

While experimenting with some larger changes, I noticed that storing this span here is unnecessary, because it is also present in the corresponding `CanonicalUserTypeAnnotation` and can be retrieved via the annotation's ID.
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs62
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs21
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs8
4 files changed, 40 insertions, 53 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 84759a0ae04..bd0d98028ae 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -456,38 +456,38 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
     fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
         self.super_local_decl(local, local_decl);
 
-        if let Some(user_ty) = &local_decl.user_ty {
-            for (user_ty, span) in user_ty.projections_and_spans() {
-                let ty = if !local_decl.is_nonref_binding() {
-                    // If we have a binding of the form `let ref x: T = ..`
-                    // then remove the outermost reference so we can check the
-                    // type annotation for the remaining type.
-                    if let ty::Ref(_, rty, _) = local_decl.ty.kind() {
-                        *rty
-                    } else {
-                        bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
-                    }
-                } else {
-                    local_decl.ty
-                };
+        for user_ty in
+            local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections)
+        {
+            let span = self.typeck.user_type_annotations[user_ty.base].span;
+
+            let ty = if local_decl.is_nonref_binding() {
+                local_decl.ty
+            } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() {
+                // If we have a binding of the form `let ref x: T = ..`
+                // then remove the outermost reference so we can check the
+                // type annotation for the remaining type.
+                rty
+            } else {
+                bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
+            };
 
-                if let Err(terr) = self.typeck.relate_type_and_user_type(
-                    ty,
-                    ty::Invariant,
-                    user_ty,
-                    Locations::All(*span),
-                    ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
-                ) {
-                    span_mirbug!(
-                        self,
-                        local,
-                        "bad user type on variable {:?}: {:?} != {:?} ({:?})",
-                        local,
-                        local_decl.ty,
-                        local_decl.user_ty,
-                        terr,
-                    );
-                }
+            if let Err(terr) = self.typeck.relate_type_and_user_type(
+                ty,
+                ty::Invariant,
+                user_ty,
+                Locations::All(span),
+                ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
+            ) {
+                span_mirbug!(
+                    self,
+                    local,
+                    "bad user type on variable {:?}: {:?} != {:?} ({:?})",
+                    local,
+                    local_decl.ty,
+                    local_decl.user_ty,
+                    terr,
+                );
             }
         }
     }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index ff493fa65a6..71fed4b3e1e 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1494,7 +1494,7 @@ pub struct SourceScopeLocalData {
 /// &'static str`.
 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
 pub struct UserTypeProjections {
-    pub contents: Vec<(UserTypeProjection, Span)>,
+    pub contents: Vec<UserTypeProjection>,
 }
 
 impl<'tcx> UserTypeProjections {
@@ -1506,26 +1506,17 @@ impl<'tcx> UserTypeProjections {
         self.contents.is_empty()
     }
 
-    pub fn projections_and_spans(
-        &self,
-    ) -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator {
-        self.contents.iter()
-    }
-
     pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
-        self.contents.iter().map(|&(ref user_type, _span)| user_type)
+        self.contents.iter()
     }
 
-    pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self {
-        self.contents.push((user_ty.clone(), span));
+    pub fn push_user_type(mut self, base_user_type: UserTypeAnnotationIndex) -> Self {
+        self.contents.push(UserTypeProjection { base: base_user_type, projs: vec![] });
         self
     }
 
-    fn map_projections(
-        mut self,
-        mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection,
-    ) -> Self {
-        self.contents = self.contents.into_iter().map(|(proj, span)| (f(proj), span)).collect();
+    fn map_projections(mut self, f: impl FnMut(UserTypeProjection) -> UserTypeProjection) -> Self {
+        self.contents = self.contents.into_iter().map(f).collect();
         self
     }
 
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 193806f238b..98e8f269c57 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -857,7 +857,7 @@ macro_rules! make_mir_visitor {
                     source_info: *source_info,
                 });
                 if let Some(user_ty) = user_ty {
-                    for (user_ty, _) in & $($mutability)? user_ty.contents {
+                    for user_ty in & $($mutability)? user_ty.contents {
                         self.visit_user_type_projection(user_ty);
                     }
                 }
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index ed577f7adeb..6334612eced 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -926,12 +926,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // Note that the variance doesn't apply here, as we are tracking the effect
                 // of `user_ty` on any bindings contained with subpattern.
 
-                let projection = UserTypeProjection {
-                    base: self.canonical_user_type_annotations.push(annotation.clone()),
-                    projs: Vec::new(),
-                };
-                let subpattern_user_ty =
-                    pattern_user_ty.push_projection(&projection, annotation.span);
+                let base_user_ty = self.canonical_user_type_annotations.push(annotation.clone());
+                let subpattern_user_ty = pattern_user_ty.push_user_type(base_user_ty);
                 self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
             }