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.
This commit is contained in:
commit
28b83ee596
4 changed files with 40 additions and 53 deletions
|
@ -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;
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
|
||||
self.contents.iter()
|
||||
}
|
||||
|
||||
pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
|
||||
self.contents.iter().map(|&(ref user_type, _span)| user_type)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue