diff options
| author | bors <bors@rust-lang.org> | 2024-04-08 16:25:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-08 16:25:23 +0000 |
| commit | 537aab7a2e7fe9cdf50b5ff18485e0793cd8db62 (patch) | |
| tree | b6f3591f2040fa12ede5b801a219d63f53b41f64 /src | |
| parent | ab3dba92db355b8d97db915a2dca161a117e959c (diff) | |
| parent | 18ff131c4e06d6e1ebfc19092fe1d6c3535eb78b (diff) | |
Auto merge of #120131 - oli-obk:pattern_types_syntax, r=compiler-errors
Implement minimal, internal-only pattern types in the type system rebase of https://github.com/rust-lang/rust/pull/107606 You can create pattern types with `std::pat::pattern_type!(ty is pat)`. The feature is incomplete and will panic on you if you use any pattern other than integral range patterns. The only way to create or deconstruct a pattern type is via `transmute`. This PR's implementation differs from the MCP's text. Specifically > This means you could implement different traits for different pattern types with the same base type. Thus, we just forbid implementing any traits for pattern types. is violated in this PR. The reason is that we do need impls after all in order to make them usable as fields. constants of type `std::time::Nanoseconds` struct are used in patterns, so the type must be structural-eq, which it only can be if you derive several traits on it. It doesn't need to be structural-eq recursively, so we can just manually implement the relevant traits on the pattern type and use the pattern type as a private field. Waiting on: * [x] move all unrelated commits into their own PRs. * [x] fix niche computation (see 2db07f94f44f078daffe5823680d07d4fded883f) * [x] add lots more tests * [x] T-types MCP https://github.com/rust-lang/types-team/issues/126 to finish * [x] some commit cleanup * [x] full self-review * [x] remove 61bd325da19a918cc3e02bbbdce97281a389c648, it's not necessary anymore I think. * [ ] ~~make sure we never accidentally leak pattern types to user code (add stability checks or feature gate checks and appopriate tests)~~ we don't even do this for the new float primitives * [x] get approval that [the scope expansion to trait impls](https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/Pattern.20types.20types-team.23126/near/427670099) is ok r? `@BoxyUwU`
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustdoc/clean/types.rs | 14 | ||||
| -rw-r--r-- | src/librustdoc/html/format.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/search_index.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/json/conversions.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 1 | ||||
| -rw-r--r-- | src/rustdoc-json-types/lib.rs | 9 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/dereference.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_utils/src/hir_utils.rs | 4 | ||||
| -rw-r--r-- | src/tools/jsondoclint/src/validator.rs | 1 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/types.rs | 5 |
11 files changed, 47 insertions, 4 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a25a506d9c5..bbdfbbd0852 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1782,6 +1782,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(), @@ -2008,6 +2009,10 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::Float(float_ty) => Primitive(float_ty.into()), ty::Str => Primitive(PrimitiveType::Str), ty::Slice(ty) => Slice(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None))), + ty::Pat(ty, pat) => Type::Pat( + Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), + format!("{pat:?}").into_boxed_str(), + ), ty::Array(ty, mut n) => { n = n.normalize(cx.tcx, ty::ParamEnv::reveal_all()); let n = print_const(cx, n); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 393996cc770..b592bd76e4c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1483,7 +1483,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. @@ -1500,10 +1502,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>), @@ -1700,6 +1707,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, @@ -1753,6 +1761,7 @@ pub(crate) enum PrimitiveType { Str, Slice, Array, + Pat, Tuple, Unit, RawPointer, @@ -1907,6 +1916,7 @@ impl PrimitiveType { Bool => sym::bool, Char => sym::char, Array => sym::array, + Pat => sym::pat, Slice => sym::slice, Tuple => sym::tuple, Unit => sym::unit, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 312765d3e6d..f82b89fdd5f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1071,6 +1071,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, diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 51f90e45500..7083999de68 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -668,7 +668,7 @@ fn get_index_type_id( } } // Not supported yet - clean::Generic(_) | clean::ImplTrait(_) | clean::Infer => None, + clean::Type::Pat(..) | clean::Generic(_) | clean::ImplTrait(_) | clean::Infer => None, } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index cb50a27326f..35b99ab46f0 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -573,6 +573,10 @@ 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_unstable_do_not_use: p.to_string(), + }, ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)), Infer => Type::Infer, RawPointer(mutability, type_) => Type::RawPointer { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a9fb0b56df9..1ba4e6cbdf0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -491,6 +491,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::Str => Res::Primitive(Str), ty::Tuple(tys) if tys.is_empty() => Res::Primitive(Unit), ty::Tuple(_) => Res::Primitive(Tuple), + ty::Pat(..) => Res::Primitive(Pat), ty::Array(..) => Res::Primitive(Array), ty::Slice(_) => Res::Primitive(Slice), ty::RawPtr(_, _) => Res::Primitive(RawPointer), diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 164f88faa31..89d6f8d67f1 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -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 @@ -562,6 +562,13 @@ pub enum Type { type_: Box<Type>, len: String, }, + /// `u32 is 1..` + Pat { + #[serde(rename = "type")] + type_: Box<Type>, + #[doc(hidden)] + __pat_unstable_do_not_use: String, + }, /// `impl TraitA + TraitB + ...` ImplTrait(Vec<GenericBound>), /// `_` diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 560b2acc1c7..f83fb1b9019 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -821,6 +821,7 @@ impl TyCoercionStability { | TyKind::Array(..) | TyKind::Ptr(_) | TyKind::BareFn(_) + | TyKind::Pat(..) | TyKind::Never | TyKind::Tup(_) | TyKind::Path(_) => Self::Deref, @@ -869,6 +870,7 @@ impl TyCoercionStability { | ty::Int(_) | ty::Uint(_) | ty::Array(..) + | ty::Pat(..) | ty::Float(_) | ty::RawPtr(..) | ty::FnPtr(_) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index f8bbe997774..6c3d9329932 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -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); diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 592e97310a4..9e08f7e5f9b 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -262,6 +262,7 @@ impl<'a> Validator<'a> { Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait), Type::Generic(_) => {} Type::Primitive(_) => {} + Type::Pat { type_, __pat_unstable_do_not_use: _ } => self.check_type(type_), Type::FunctionPointer(fp) => self.check_function_pointer(&**fp), Type::Tuple(tys) => tys.iter().for_each(|ty| self.check_type(ty)), Type::Slice(inner) => self.check_type(&**inner), diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 7f220a456a8..10a87f6e698 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -867,6 +867,11 @@ impl Rewrite for ast::Ty { self.span, shape, ), + ast::TyKind::Pat(ref ty, ref pat) => { + let ty = ty.rewrite(context, shape)?; + let pat = pat.rewrite(context, shape)?; + Some(format!("{ty} is {pat}")) + } } } } |
