Skip to content

Commit

Permalink
Thread pattern types through the HIR
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 22, 2024
1 parent 2577285 commit 31dbd68
Show file tree
Hide file tree
Showing 14 changed files with 51 additions and 5 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
hir::TyKind::Err(guar)
}
TyKind::Pat(..) => span_bug!(t.span, "pattern types are unimplemented"),
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
};

hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2621,6 +2621,8 @@ pub enum TyKind<'hir> {
Infer,
/// Placeholder for a type that has failed to be defined.
Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`u32 as 1..`)
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
}
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
TyKind::Infer | TyKind::InferDelegation(..) | TyKind::Err(_) => {}
TyKind::Pat(ty, pat) => {
visitor.visit_ty(ty);
visitor.visit_pat(pat)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// handled specially and will not descend into this routine.
self.ty_infer(None, ast_ty.span)
}
hir::TyKind::Pat(..) => span_bug!(ast_ty.span, "{ast_ty:#?}"),
hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
};

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ impl<'a> State<'a> {
hir::TyKind::Infer | hir::TyKind::InferDelegation(..) => {
self.word("_");
}
hir::TyKind::Pat(ty, pat) => {
self.print_type(ty);
self.word(" is ");
self.print_pat(pat);
}
}
self.end()
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/hir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
TraitObject,
Typeof,
Infer,
Pat,
Err
]
);
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
}
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()),
TyKind::Array(ty, ref length) => {
let length = match length {
hir::ArrayLen::Infer(_, _) => "_".to_string(),
Expand Down
14 changes: 12 additions & 2 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,9 @@ pub(crate) enum Type {
///
/// This is mostly Rustdoc's version of [`hir::Path`].
/// It has to be different because Rustdoc's [`PathSegment`] can contain cleaned generics.
Path { path: Path },
Path {
path: Path,
},
/// A `dyn Trait` object: `dyn for<'a> Trait<'a> + Send + 'static`
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
/// A type parameter.
Expand All @@ -1498,10 +1500,15 @@ pub(crate) enum Type {
///
/// The `String` field is a stringified version of the array's length parameter.
Array(Box<Type>, Box<str>),
Pat(Box<Type>, Box<str>),
/// A raw pointer type: `*const i32`, `*mut i32`
RawPointer(Mutability, Box<Type>),
/// A reference type: `&i32`, `&'a mut Foo`
BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },
BorrowedRef {
lifetime: Option<Lifetime>,
mutability: Mutability,
type_: Box<Type>,
},

/// A qualified path to an associated item: `<Type as Trait>::Name`
QPath(Box<QPathData>),
Expand Down Expand Up @@ -1698,6 +1705,7 @@ impl Type {
BareFunction(..) => PrimitiveType::Fn,
Slice(..) => PrimitiveType::Slice,
Array(..) => PrimitiveType::Array,
Type::Pat(..) => PrimitiveType::Pat,
RawPointer(..) => PrimitiveType::RawPointer,
QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache),
Generic(_) | Infer | ImplTrait(_) => return None,
Expand Down Expand Up @@ -1749,6 +1757,7 @@ pub(crate) enum PrimitiveType {
Str,
Slice,
Array,
Pat,
Tuple,
Unit,
RawPointer,
Expand Down Expand Up @@ -1895,6 +1904,7 @@ impl PrimitiveType {
Bool => sym::bool,
Char => sym::char,
Array => sym::array,
Pat => sym::pat,
Slice => sym::slice,
Tuple => sym::tuple,
Unit => sym::unit,
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,10 @@ fn fmt_type<'cx>(
write!(f, "]")
}
},
clean::Type::Pat(ref t, ref pat) => {
fmt::Display::fmt(&t.print(cx), f)?;
write!(f, " is {pat}")
}
clean::Array(ref t, ref n) => match **t {
clean::Generic(name) if !f.alternate() => primitive_link(
f,
Expand Down
6 changes: 5 additions & 1 deletion src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,11 @@ fn get_index_type_id(
}
}
// Not supported yet
clean::BareFunction(_) | clean::Generic(_) | clean::ImplTrait(_) | clean::Infer => None,
clean::Type::Pat(..)
| clean::BareFunction(_)
| clean::Generic(_)
| clean::ImplTrait(_)
| clean::Infer => None,
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@ impl FromWithTcx<clean::Type> for Type {
Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))),
Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s.to_string() },
clean::Type::Pat(t, p) => {
Type::Pat { type_: Box::new((*t).into_tcx(tcx)), pat: p.to_string() }
}
ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)),
Infer => Type::Infer,
RawPointer(mutability, type_) => Type::RawPointer {
Expand Down
8 changes: 7 additions & 1 deletion src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 28;
pub const FORMAT_VERSION: u32 = 29;

/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
Expand Down Expand Up @@ -562,6 +562,12 @@ pub enum Type {
type_: Box<Type>,
len: String,
},
/// `u32 is 1..`
Pat {
#[serde(rename = "type")]
type_: Box<Type>,
pat: String,
},
/// `impl TraitA + TraitB + ...`
ImplTrait(Vec<GenericBound>),
/// `_`
Expand Down
1 change: 1 addition & 0 deletions src/tools/clippy/clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ impl TyCoercionStability {
| TyKind::Array(..)
| TyKind::Ptr(_)
| TyKind::BareFn(_)
| TyKind::Pat(..)
| TyKind::Never
| TyKind::Tup(_)
| TyKind::Path(_) => Self::Deref,
Expand Down
4 changes: 4 additions & 0 deletions src/tools/clippy/clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
self.hash_ty(ty);
self.hash_array_length(len);
},
TyKind::Pat(ty, pat) => {
self.hash_ty(ty);
self.hash_pat(pat);
},
TyKind::Ptr(ref mut_ty) => {
self.hash_ty(mut_ty.ty);
mut_ty.mutbl.hash(&mut self.s);
Expand Down

0 comments on commit 31dbd68

Please sign in to comment.