diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/adjustment.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/adt.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/assoc.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/typeck_results.rs | 25 |
5 files changed, 49 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 3425da48559..a61a6c571a2 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -214,3 +214,25 @@ pub enum CustomCoerceUnsized { /// Records the index of the field being coerced. Struct(FieldIdx), } + +/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern +/// against it. Currently, this is used only for implicit dereferences. +#[derive(Clone, Copy, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +pub struct PatAdjustment<'tcx> { + pub kind: PatAdjust, + /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the + /// pattern. + pub source: Ty<'tcx>, +} + +/// Represents implicit coercions of patterns' types, rather than values' types. +#[derive(Clone, Copy, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum PatAdjust { + /// An implicit dereference before matching, such as when matching the pattern `0` against a + /// scrutinee of type `&u8` or `&mut u8`. + BuiltinDeref, + /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the + /// pattern `[..]` against a scrutinee of type `Vec<T>`. + OverloadedDeref, +} diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 66517c97a68..d92b4f9c06b 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -55,8 +55,6 @@ bitflags::bitflags! { const IS_UNSAFE_CELL = 1 << 9; /// Indicates whether the type is `UnsafePinned`. const IS_UNSAFE_PINNED = 1 << 10; - /// Indicates whether the type is anonymous. - const IS_ANONYMOUS = 1 << 11; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 0c44fd2758d..78b2e265b48 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -246,6 +246,8 @@ impl AssocItems { } /// Returns an iterator over all associated items with the given name, ignoring hygiene. + /// + /// Panics if `name.is_empty()` returns `true`. pub fn filter_by_name_unhygienic( &self, name: Symbol, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 40eef541423..26861666c1d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -60,6 +60,12 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { } } +impl<'tcx> fmt::Debug for ty::adjustment::PatAdjustment<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} -> {:?}", self.source, self.kind) + } +} + impl fmt::Debug for ty::BoundRegionKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 90c6ef67fb8..4c5c669771f 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -77,8 +77,8 @@ pub struct TypeckResults<'tcx> { /// to a form valid in all Editions, either as a lint diagnostic or hard error. rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>, - /// Stores the types which were implicitly dereferenced in pattern binding modes - /// for later usage in THIR lowering. For example, + /// Stores the types which were implicitly dereferenced in pattern binding modes or deref + /// patterns for later usage in THIR lowering. For example, /// /// ``` /// match &&Some(5i32) { @@ -86,11 +86,20 @@ pub struct TypeckResults<'tcx> { /// _ => {}, /// } /// ``` - /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored. + /// leads to a `vec![&&Option<i32>, &Option<i32>]` and + /// + /// ``` + /// #![feature(deref_patterns)] + /// match &Box::new(Some(5i32)) { + /// Some(n) => {}, + /// _ => {}, + /// } + /// ``` + /// leads to a `vec![&Box<Option<i32>>, Box<Option<i32>>]`. Empty vectors are not stored. /// /// See: /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions> - pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>, + pat_adjustments: ItemLocalMap<Vec<ty::adjustment::PatAdjustment<'tcx>>>, /// Set of reference patterns that match against a match-ergonomics inserted reference /// (as opposed to against a reference in the scrutinee type). @@ -403,11 +412,15 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes } } - pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> { + pub fn pat_adjustments( + &self, + ) -> LocalTableInContext<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> { LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments } } - pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> { + pub fn pat_adjustments_mut( + &mut self, + ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } |
