Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #120466

Merged
merged 30 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a208662
References refer to allocated objects
joshlf Oct 12, 2023
4f0192a
Update primitive_docs.rs
joshlf Oct 13, 2023
39660c4
Update library/core/src/primitive_docs.rs
joshlf Oct 13, 2023
55487e2
Update primitive_docs.rs
joshlf Oct 13, 2023
1a0309a
Update primitive_docs.rs
joshlf Nov 3, 2023
ab938b9
Improve documentation for [A]Rc::into_inner
steffahn Jan 23, 2024
c2c6e33
Update primitive_docs.rs
joshlf Jan 25, 2024
3269513
fix issue 120040
HTGAzureX1212 Jan 26, 2024
8f89e57
remove redundant call to Error::last_os_error
HTGAzureX1212 Jan 26, 2024
2241d16
fix
HTGAzureX1212 Jan 26, 2024
e26f213
make modifications as per reviews
HTGAzureX1212 Jan 27, 2024
018bf30
add extra check for invalid handle in ReadDir::next
HTGAzureX1212 Jan 27, 2024
f5c7895
Stop using derivative in rustc_pattern_analysis
lnicola Jan 27, 2024
b867c7c
Update primitive_docs.rs
joshlf Jan 27, 2024
5f8030d
hir: Remove unnecessary `HirId` from `hir::Let`
petrochenkov Jan 27, 2024
b2b5b91
hir: Use `InferArg` in `ArrayLen::Infer`
petrochenkov Jan 27, 2024
6f014a8
Handle methodcalls & operators in patterns
ShE3py Jan 28, 2024
6755805
normalize_newlines(): fix incorrect comment
mattheww Jan 28, 2024
d3bf8b7
Clean dead code
mu001999 Jan 28, 2024
83fa46f
Borrow check inline const patterns
matthewjasper Jan 26, 2024
44824e0
Enable tests for unsafe blocks in inline const patterns
matthewjasper Jan 26, 2024
8017ea4
Rollup merge of #116677 - joshlf:patch-11, r=RalfJung
Dylan-DPC Jan 29, 2024
0138151
Rollup merge of #118625 - ShE3py:expr-in-pats, r=WaffleLapkin
Dylan-DPC Jan 29, 2024
4528b37
Rollup merge of #120266 - steffahn:a_rc_into_inner_docs, r=Mark-Simul…
Dylan-DPC Jan 29, 2024
d04bede
Rollup merge of #120373 - HTGAzureX1212:HTGAzureX1212/issue-120040, r…
Dylan-DPC Jan 29, 2024
549eeb0
Rollup merge of #120390 - matthewjasper:inline-constant-pat-mir, r=da…
Dylan-DPC Jan 29, 2024
5de94a3
Rollup merge of #120420 - lnicola:rm-pattern-analysis-derivative, r=N…
Dylan-DPC Jan 29, 2024
eaa1002
Rollup merge of #120428 - petrochenkov:somehir2, r=compiler-errors
Dylan-DPC Jan 29, 2024
15e8b90
Rollup merge of #120453 - mattheww:2024-01_normalize_newlines, r=oli-obk
Dylan-DPC Jan 29, 2024
c70c4cc
Rollup merge of #120462 - mu001999:clean, r=Nilstrieb
Dylan-DPC Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Stop using derivative in rustc_pattern_analysis
  • Loading branch information
lnicola committed Jan 27, 2024
commit f5c78955c88ac37b7422bef6ee9ec993c0a5dad2
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4342,7 +4342,6 @@ dependencies = [
name = "rustc_pattern_analysis"
version = "0.0.0"
dependencies = [
"derivative",
"rustc-hash",
"rustc_apfloat",
"rustc_arena",
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_pattern_analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
derivative = "2.2.0"
rustc-hash = "1.1.0"
rustc_apfloat = "0.2.0"
rustc_arena = { path = "../rustc_arena", optional = true }
Expand Down
98 changes: 96 additions & 2 deletions compiler/rustc_pattern_analysis/src/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
use std::cmp::{self, max, min, Ordering};
use std::fmt;
use std::iter::once;
use std::mem;

use smallvec::SmallVec;

Expand Down Expand Up @@ -648,8 +649,6 @@ impl OpaqueId {
/// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
/// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
/// `Fields`.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))]
pub enum Constructor<Cx: TypeCx> {
/// Tuples and structs.
Struct,
Expand Down Expand Up @@ -692,6 +691,101 @@ pub enum Constructor<Cx: TypeCx> {
Missing,
}

impl<Cx: TypeCx> Clone for Constructor<Cx> {
fn clone(&self) -> Self {
match self {
Constructor::Struct => Constructor::Struct,
Constructor::Variant(idx) => Constructor::Variant(idx.clone()),
Constructor::Ref => Constructor::Ref,
Constructor::Slice(slice) => Constructor::Slice(slice.clone()),
Constructor::UnionField => Constructor::UnionField,
Constructor::Bool(b) => Constructor::Bool(b.clone()),
Constructor::IntRange(range) => Constructor::IntRange(range.clone()),
Constructor::F32Range(lo, hi, end) => {
Constructor::F32Range(lo.clone(), hi.clone(), end.clone())
}
Constructor::F64Range(lo, hi, end) => {
Constructor::F64Range(lo.clone(), hi.clone(), end.clone())
}
Constructor::Str(value) => Constructor::Str(value.clone()),
Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
Constructor::Or => Constructor::Or,
Constructor::Wildcard => Constructor::Wildcard,
Constructor::NonExhaustive => Constructor::NonExhaustive,
Constructor::Hidden => Constructor::Hidden,
Constructor::Missing => Constructor::Missing,
}
}
}

impl<Cx: TypeCx> fmt::Debug for Constructor<Cx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Constructor::Struct => f.debug_tuple("Struct").finish(),
Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(),
Constructor::Ref => f.debug_tuple("Ref").finish(),
Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(),
Constructor::UnionField => f.debug_tuple("UnionField").finish(),
Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(),
Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(),
Constructor::F32Range(lo, hi, end) => {
f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish()
}
Constructor::F64Range(lo, hi, end) => {
f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish()
}
Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(),
Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(),
Constructor::Or => f.debug_tuple("Or").finish(),
Constructor::Wildcard => f.debug_tuple("Wildcard").finish(),
Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(),
Constructor::Hidden => f.debug_tuple("Hidden").finish(),
Constructor::Missing => f.debug_tuple("Missing").finish(),
}
}
}

impl<Cx: TypeCx> PartialEq for Constructor<Cx> {
fn eq(&self, other: &Self) -> bool {
(mem::discriminant(self) == mem::discriminant(other))
&& match (self, other) {
(Constructor::Struct, Constructor::Struct) => true,
(Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => {
self_variant == other_variant
}
(Constructor::Ref, Constructor::Ref) => true,
(Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => {
self_slice == other_slice
}
(Constructor::UnionField, Constructor::UnionField) => true,
(Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b,
(Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => {
self_range == other_range
}
(
Constructor::F32Range(self_lo, self_hi, self_end),
Constructor::F32Range(other_lo, other_hi, other_end),
) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
(
Constructor::F64Range(self_lo, self_hi, self_end),
Constructor::F64Range(other_lo, other_hi, other_end),
) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
(Constructor::Str(self_value), Constructor::Str(other_value)) => {
self_value == other_value
}
(Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => {
self_inner == other_inner
}
(Constructor::Or, Constructor::Or) => true,
(Constructor::Wildcard, Constructor::Wildcard) => true,
(Constructor::NonExhaustive, Constructor::NonExhaustive) => true,
(Constructor::Hidden, Constructor::Hidden) => true,
(Constructor::Missing, Constructor::Missing) => true,
_ => unreachable!(),
}
}
}

impl<Cx: TypeCx> Constructor<Cx> {
pub(crate) fn is_non_exhaustive(&self) -> bool {
matches!(self, NonExhaustive)
Expand Down
20 changes: 16 additions & 4 deletions compiler/rustc_pattern_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,35 @@ pub trait TypeCx: Sized + fmt::Debug {
}

/// Context that provides information global to a match.
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), Copy(bound = ""))]
pub struct MatchCtxt<'a, Cx: TypeCx> {
/// The context for type information.
pub tycx: &'a Cx,
}

impl<'a, Cx: TypeCx> Clone for MatchCtxt<'a, Cx> {
fn clone(&self) -> Self {
Self { tycx: self.tycx }
}
}

impl<'a, Cx: TypeCx> Copy for MatchCtxt<'a, Cx> {}

/// The arm of a match expression.
#[derive(Debug)]
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), Copy(bound = ""))]
pub struct MatchArm<'p, Cx: TypeCx> {
pub pat: &'p DeconstructedPat<'p, Cx>,
pub has_guard: bool,
pub arm_data: Cx::ArmData,
}

impl<'p, Cx: TypeCx> Clone for MatchArm<'p, Cx> {
fn clone(&self) -> Self {
Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data }
}
}

impl<'p, Cx: TypeCx> Copy for MatchArm<'p, Cx> {}

/// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are
/// useful, and runs some lints.
#[cfg(feature = "rustc")]
Expand Down
31 changes: 27 additions & 4 deletions compiler/rustc_pattern_analysis/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,24 @@ impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
/// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input.
///
/// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard.
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), Copy(bound = ""))]
pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
/// A non-user-provided wildcard, created during specialization.
Wild,
/// A user-provided pattern.
Pat(&'p DeconstructedPat<'p, Cx>),
}

impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
fn clone(&self) -> Self {
match self {
PatOrWild::Wild => PatOrWild::Wild,
PatOrWild::Pat(pat) => PatOrWild::Pat(pat),
}
}
}

impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}

impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
match self {
Expand Down Expand Up @@ -289,14 +298,28 @@ impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> {

/// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
/// purposes. As such they don't use interning and can be cloned.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
pub struct WitnessPat<Cx: TypeCx> {
ctor: Constructor<Cx>,
pub(crate) fields: Vec<WitnessPat<Cx>>,
ty: Cx::Ty,
}

impl<Cx: TypeCx> Clone for WitnessPat<Cx> {
fn clone(&self) -> Self {
Self { ctor: self.ctor.clone(), fields: self.fields.clone(), ty: self.ty.clone() }
}
}

impl<Cx: TypeCx> fmt::Debug for WitnessPat<Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("WitnessPat")
.field("ctor", &self.ctor)
.field("fields", &self.fields)
.field("ty", &self.ty)
.finish()
}
}

impl<Cx: TypeCx> WitnessPat<Cx> {
pub(crate) fn new(ctor: Constructor<Cx>, fields: Vec<Self>, ty: Cx::Ty) -> Self {
Self { ctor, fields, ty }
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat<RustcMatchCheckCtxt<'p, '
///
/// Use `.inner()` or deref to get to the `Ty<'tcx>`.
#[repr(transparent)]
#[derive(derivative::Derivative)]
#[derive(Clone, Copy)]
#[derivative(Debug = "transparent")]
pub struct RevealedTy<'tcx>(Ty<'tcx>);

impl<'tcx> fmt::Debug for RevealedTy<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(fmt)
}
}

impl<'tcx> std::ops::Deref for RevealedTy<'tcx> {
type Target = Ty<'tcx>;
fn deref(&self) -> &Self::Target {
Expand Down
58 changes: 46 additions & 12 deletions compiler/rustc_pattern_analysis/src/usefulness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,16 +731,26 @@ pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
}

/// Context that provides information local to a place under investigation.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))]
pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
#[derivative(Debug = "ignore")]
pub(crate) mcx: MatchCtxt<'a, Cx>,
/// Type of the place under investigation.
#[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
pub(crate) ty: &'a Cx::Ty,
}

impl<'a, Cx: TypeCx> Clone for PlaceCtxt<'a, Cx> {
fn clone(&self) -> Self {
Self { mcx: self.mcx, ty: self.ty }
}
}

impl<'a, Cx: TypeCx> Copy for PlaceCtxt<'a, Cx> {}

impl<'a, Cx: TypeCx> fmt::Debug for PlaceCtxt<'a, Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("PlaceCtxt").field("ty", self.ty).finish()
}
}

impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
/// A `PlaceCtxt` when code other than `is_useful` needs one.
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
Expand Down Expand Up @@ -813,8 +823,6 @@ impl fmt::Display for ValidityConstraint {
// The three lifetimes are:
// - 'p coming from the input
// - Cx global compilation context
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""))]
struct PatStack<'p, Cx: TypeCx> {
// Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
Expand All @@ -824,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> {
relevant: bool,
}

impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
fn clone(&self) -> Self {
Self { pats: self.pats.clone(), relevant: self.relevant }
}
}

impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
Expand Down Expand Up @@ -1184,10 +1198,20 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> {
/// The final `Pair(Some(_), true)` is then the resulting witness.
///
/// See the top of the file for more detailed explanations and examples.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
struct WitnessStack<Cx: TypeCx>(Vec<WitnessPat<Cx>>);

impl<Cx: TypeCx> Clone for WitnessStack<Cx> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}

impl<Cx: TypeCx> fmt::Debug for WitnessStack<Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("WitnessStack").field(&self.0).finish()
}
}

impl<Cx: TypeCx> WitnessStack<Cx> {
/// Asserts that the witness contains a single pattern, and returns it.
fn single_pattern(self) -> WitnessPat<Cx> {
Expand Down Expand Up @@ -1232,18 +1256,28 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
///
/// Just as the `Matrix` starts with a single column, by the end of the algorithm, this has a single
/// column, which contains the patterns that are missing for the match to be exhaustive.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
struct WitnessMatrix<Cx: TypeCx>(Vec<WitnessStack<Cx>>);

impl<Cx: TypeCx> Clone for WitnessMatrix<Cx> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}

impl<Cx: TypeCx> fmt::Debug for WitnessMatrix<Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("WitnessMatrix").field(&self.0).finish()
}
}

impl<Cx: TypeCx> WitnessMatrix<Cx> {
/// New matrix with no witnesses.
fn empty() -> Self {
WitnessMatrix(vec![])
WitnessMatrix(Vec::new())
}
/// New matrix with one `()` witness, i.e. with no columns.
fn unit_witness() -> Self {
WitnessMatrix(vec![WitnessStack(vec![])])
WitnessMatrix(vec![WitnessStack(Vec::new())])
}

/// Whether this has any witnesses.
Expand Down
Loading