Auto merge of #150158 - Zalathar:rollup-dqazzrn, r=Zalathar

Rollup of 3 pull requests

Successful merges:

 - rust-lang/rust#150121 (mir_build: Don't use a mixture of THIR pattern kinds for pin-patterns)
 - rust-lang/rust#150148 (mir_build: Remove unnecessary lifetime from THIR `PatCtxt`)
 - rust-lang/rust#150150 (move eii tests)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-12-19 14:57:07 +00:00
21 changed files with 62 additions and 66 deletions
@@ -21,6 +21,7 @@
// Export these here so that Clippy can use them.
pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::thir::DerefPatBorrowMode;
use rustc_middle::ty::{
self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
};
@@ -890,7 +891,7 @@ fn walk_pat(
// Deref patterns on boxes don't borrow, so we ignore them here.
// HACK: this could be a fake pattern corresponding to a deref inserted by match
// ergonomics, in which case `pat.hir_id` will be the id of the subpattern.
if let hir::ByRef::Yes(_, mutability) =
if let DerefPatBorrowMode::Borrow(mutability) =
self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern)
{
let bk = ty::BorrowKind::from_mutbl(mutability);
@@ -1837,9 +1838,9 @@ fn pat_deref_place(
) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
match self.cx.typeck_results().deref_pat_borrow_mode(base_place.place.ty(), inner) {
// Deref patterns on boxes are lowered using a built-in deref.
hir::ByRef::No => self.cat_deref(hir_id, base_place),
DerefPatBorrowMode::Box => self.cat_deref(hir_id, base_place),
// For other types, we create a temporary to match on.
hir::ByRef::Yes(_, mutability) => {
DerefPatBorrowMode::Borrow(mutability) => {
let re_erased = self.cx.tcx().lifetimes.re_erased;
let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability);
// A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ...
+9 -3
View File
@@ -14,7 +14,7 @@
use std::sync::Arc;
use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece, Mutability};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@@ -811,11 +811,11 @@ pub enum PatKind<'tcx> {
DerefPattern {
subpattern: Box<Pat<'tcx>>,
/// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or
/// `DerefMut::deref_mut`, and if so, which. This is `ByRef::No` for deref patterns on
/// `DerefMut::deref_mut`, and if so, which. This is `DerefPatBorrowMode::Box` for deref patterns on
/// boxes; they are lowered using a built-in deref rather than a method call, thus they
/// don't borrow the scrutinee.
#[type_visitable(ignore)]
borrow: ByRef,
borrow: DerefPatBorrowMode,
},
/// One of the following:
@@ -879,6 +879,12 @@ pub enum PatKind<'tcx> {
Error(ErrorGuaranteed),
}
#[derive(Copy, Clone, Debug, HashStable)]
pub enum DerefPatBorrowMode {
Borrow(Mutability),
Box,
}
/// A range pattern.
/// The boundaries must be of the same type and that type must be numeric.
#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
+11 -6
View File
@@ -11,7 +11,6 @@
use rustc_hir::hir_id::OwnerId;
use rustc_hir::{
self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
Pinnedness,
};
use rustc_index::IndexVec;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -21,6 +20,7 @@
use crate::hir::place::Place as HirPlace;
use crate::infer::canonical::Canonical;
use crate::mir::FakeReadCause;
use crate::thir::DerefPatBorrowMode;
use crate::traits::ObligationCause;
use crate::ty::{
self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs,
@@ -491,13 +491,18 @@ pub fn pat_has_ref_mut_binding(&self, pat: &hir::Pat<'_>) -> bool {
/// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner
/// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.
/// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;
/// in this case, we return `ByRef::No`.
pub fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: &hir::Pat<'_>) -> ByRef {
/// in this case, we return `DerefPatBorrowMode::Box`.
pub fn deref_pat_borrow_mode(
&self,
pointer_ty: Ty<'_>,
inner: &hir::Pat<'_>,
) -> DerefPatBorrowMode {
if pointer_ty.is_box() {
ByRef::No
DerefPatBorrowMode::Box
} else {
let mutable = self.pat_has_ref_mut_binding(inner);
ByRef::Yes(Pinnedness::Not, if mutable { Mutability::Mut } else { Mutability::Not })
let mutability =
if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
DerefPatBorrowMode::Borrow(mutability)
}
}
@@ -1,10 +1,9 @@
use std::sync::Arc;
use rustc_abi::FieldIdx;
use rustc_hir::ByRef;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use crate::builder::Builder;
use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder};
@@ -287,8 +286,9 @@ pub(super) fn for_pattern(
None
}
// FIXME: Pin-patterns should probably have their own pattern kind,
// instead of overloading `PatKind::Deref` via the pattern type.
PatKind::Deref { ref subpattern }
| PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) }
if let Some(ref_ty) = pattern.ty.pinned_ty()
&& ref_ty.is_ref() =>
{
@@ -302,12 +302,8 @@ pub(super) fn for_pattern(
None
}
PatKind::DerefPattern { borrow: ByRef::Yes(Pinnedness::Pinned, _), .. } => {
rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty)
}
PatKind::Deref { ref subpattern }
| PatKind::DerefPattern { ref subpattern, borrow: ByRef::No } => {
| PatKind::DerefPattern { ref subpattern, borrow: DerefPatBorrowMode::Box } => {
MatchPairTree::for_pattern(
place_builder.deref(),
subpattern,
@@ -320,7 +316,7 @@ pub(super) fn for_pattern(
PatKind::DerefPattern {
ref subpattern,
borrow: ByRef::Yes(Pinnedness::Not, mutability),
borrow: DerefPatBorrowMode::Borrow(mutability),
} => {
// Create a new temporary for each deref pattern.
// FIXME(deref_patterns): dedup temporaries to avoid multiple `deref()` calls?
@@ -11,10 +11,10 @@
use std::sync::Arc;
use itertools::{Itertools, Position};
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_abi::{FIRST_VARIANT, VariantIdx};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node, Pinnedness};
use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node};
use rustc_middle::middle::region::{self, TempLifetime};
use rustc_middle::mir::*;
use rustc_middle::thir::{self, *};
@@ -920,10 +920,6 @@ fn visit_primary_bindings_special(
visit_subpat(self, subpattern, &user_tys.deref(), f);
}
PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => {
visit_subpat(self, subpattern, &user_tys.leaf(FieldIdx::ZERO).deref(), f);
}
PatKind::DerefPattern { ref subpattern, .. } => {
visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f);
}
@@ -28,7 +28,7 @@
PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern,
};
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
impl<'tcx> PatCtxt<'tcx> {
/// Converts a constant to a pattern (if possible).
/// This means aggregate values (like structs and enums) are converted
/// to a pattern that matches the value (as if you'd compared via structural equality).
@@ -64,7 +64,7 @@ struct ConstToPat<'tcx> {
}
impl<'tcx> ConstToPat<'tcx> {
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
fn new(pat_ctxt: &PatCtxt<'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
trace!(?pat_ctxt.typeck_results.hir_owner);
ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c }
}
@@ -11,12 +11,12 @@
use rustc_errors::codes::*;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd};
use rustc_hir::{self as hir, LangItem, RangeEnd};
use rustc_index::Idx;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::LitToConstInput;
use rustc_middle::thir::{
Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
Ascription, DerefPatBorrowMode, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
};
use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment};
use rustc_middle::ty::layout::IntegerExt;
@@ -30,19 +30,20 @@
use self::migration::PatMigration;
use crate::errors::*;
struct PatCtxt<'a, 'tcx> {
/// Context for lowering HIR patterns to THIR patterns.
struct PatCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
/// Used by the Rust 2024 migration lint.
rust_2024_migration: Option<PatMigration<'a>>,
rust_2024_migration: Option<PatMigration<'tcx>>,
}
pub(super) fn pat_from_hir<'a, 'tcx>(
pub(super) fn pat_from_hir<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>,
) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt {
@@ -62,7 +63,7 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
result
}
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
impl<'tcx> PatCtxt<'tcx> {
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
let adjustments: &[PatAdjustment<'tcx>] =
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
@@ -114,16 +115,7 @@ fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
let borrow = self.typeck_results.deref_pat_borrow_mode(adjust.source, pat);
PatKind::DerefPattern { subpattern: thir_pat, borrow }
}
PatAdjust::PinDeref => {
let mutable = self.typeck_results.pat_has_ref_mut_binding(pat);
PatKind::DerefPattern {
subpattern: thir_pat,
borrow: ByRef::Yes(
Pinnedness::Pinned,
if mutable { Mutability::Mut } else { Mutability::Not },
),
}
}
PatAdjust::PinDeref => PatKind::Deref { subpattern: thir_pat },
};
Box::new(Pat { span, ty: adjust.source, kind })
});
@@ -334,7 +326,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tc
}
hir::PatKind::Box(subpattern) => PatKind::DerefPattern {
subpattern: self.lower_pattern(subpattern),
borrow: hir::ByRef::No,
borrow: DerefPatBorrowMode::Box,
},
hir::PatKind::Slice(prefix, slice, suffix) => {
@@ -1,107 +1,107 @@
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:7:1
--> $DIR/attribute_targets.rs:7:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:9:1
--> $DIR/attribute_targets.rs:9:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:13:1
--> $DIR/attribute_targets.rs:13:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:15:1
--> $DIR/attribute_targets.rs:15:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:21:1
--> $DIR/attribute_targets.rs:21:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:23:1
--> $DIR/attribute_targets.rs:23:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:27:1
--> $DIR/attribute_targets.rs:27:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:29:1
--> $DIR/attribute_targets.rs:29:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:32:5
--> $DIR/attribute_targets.rs:32:5
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:34:5
--> $DIR/attribute_targets.rs:34:5
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:39:1
--> $DIR/attribute_targets.rs:39:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:41:1
--> $DIR/attribute_targets.rs:41:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:44:5
--> $DIR/attribute_targets.rs:44:5
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:46:5
--> $DIR/attribute_targets.rs:46:5
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:51:1
--> $DIR/attribute_targets.rs:51:1
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:53:1
--> $DIR/attribute_targets.rs:53:1
|
LL | #[eii]
| ^^^^^^
error: `#[foo]` is only valid on functions
--> $DIR/wrong_target.rs:56:5
--> $DIR/attribute_targets.rs:56:5
|
LL | #[foo]
| ^^^^^^
error: `#[eii]` is only valid on functions
--> $DIR/wrong_target.rs:58:5
--> $DIR/attribute_targets.rs:58:5
|
LL | #[eii]
| ^^^^^^