Skip to content

Commit

Permalink
Auto merge of rust-lang#120432 - matthiaskrgr:rollup-ho8zrrk, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#116677 (References refer to allocated objects)
 - rust-lang#120232 (Add support for custom JSON targets when using build-std.)
 - rust-lang#120266 (Improve documentation for [A]Rc::into_inner)
 - rust-lang#120358 (Bump Fuchsia, build tests, and use 8 core bots)
 - rust-lang#120373 (Adjust Behaviour of `read_dir` and `ReadDir` in Windows Implementation: Check Whether Path to Search In Exists)
 - rust-lang#120402 (Make the coroutine def id of an async closure the child of the closure def id)
 - rust-lang#120420 (Stop using derivative in rustc_pattern_analysis)
 - rust-lang#120425 (Remove unnecessary unit returns in query declarations)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 28, 2024
2 parents 6351247 + e1fa42e commit 02dde5d
Show file tree
Hide file tree
Showing 22 changed files with 374 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ jobs:
- name: x86_64-gnu-integration
env:
CI_ONLY_WHEN_CHANNEL: nightly
os: ubuntu-20.04-16core-64gb
os: ubuntu-20.04-8core-32gb
- name: x86_64-gnu-debug
os: ubuntu-20.04-8core-32gb
env: {}
Expand Down
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
28 changes: 14 additions & 14 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
// as they will raise an fatal error on query cycles instead.
rustc_queries! {
/// This exists purely for testing the interactions between span_delayed_bug and incremental.
query trigger_span_delayed_bug(key: DefId) -> () {
query trigger_span_delayed_bug(key: DefId) {
desc { "triggering a span delayed bug for testing incremental" }
}

Expand All @@ -119,7 +119,7 @@ rustc_queries! {
desc { "compute registered tools for crate" }
}

query early_lint_checks(_: ()) -> () {
query early_lint_checks(_: ()) {
desc { "perform lints prior to macro expansion" }
}

Expand Down Expand Up @@ -299,7 +299,7 @@ rustc_queries! {
/// name. This is useful for cases were not all linting code from rustc
/// was called. With the default `None` all registered lints will also
/// be checked for expectation fulfillment.
query check_expectations(key: Option<Symbol>) -> () {
query check_expectations(key: Option<Symbol>) {
eval_always
desc { "checking lint expectations (RFC 2383)" }
}
Expand Down Expand Up @@ -906,39 +906,39 @@ rustc_queries! {
}

/// Performs lint checking for the module.
query lint_mod(key: LocalModDefId) -> () {
query lint_mod(key: LocalModDefId) {
desc { |tcx| "linting {}", describe_as_module(key, tcx) }
}

query check_unused_traits(_: ()) -> () {
query check_unused_traits(_: ()) {
desc { "checking unused trait imports in crate" }
}

/// Checks the attributes in the module.
query check_mod_attrs(key: LocalModDefId) -> () {
query check_mod_attrs(key: LocalModDefId) {
desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
}

/// Checks for uses of unstable APIs in the module.
query check_mod_unstable_api_usage(key: LocalModDefId) -> () {
query check_mod_unstable_api_usage(key: LocalModDefId) {
desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
}

/// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
query check_mod_const_bodies(key: LocalModDefId) -> () {
query check_mod_const_bodies(key: LocalModDefId) {
desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) }
}

/// Checks the loops in the module.
query check_mod_loops(key: LocalModDefId) -> () {
query check_mod_loops(key: LocalModDefId) {
desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
}

query check_mod_naked_functions(key: LocalModDefId) -> () {
query check_mod_naked_functions(key: LocalModDefId) {
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
}

query check_mod_privacy(key: LocalModDefId) -> () {
query check_mod_privacy(key: LocalModDefId) {
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
}

Expand All @@ -958,7 +958,7 @@ rustc_queries! {
desc { "finding live symbols in crate" }
}

query check_mod_deathness(key: LocalModDefId) -> () {
query check_mod_deathness(key: LocalModDefId) {
desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
}

Expand All @@ -972,7 +972,7 @@ rustc_queries! {
ensure_forwards_result_if_red
}

query collect_mod_item_types(key: LocalModDefId) -> () {
query collect_mod_item_types(key: LocalModDefId) {
desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
}

Expand Down Expand Up @@ -1121,7 +1121,7 @@ rustc_queries! {
eval_always
desc { "checking effective visibilities" }
}
query check_private_in_public(_: ()) -> () {
query check_private_in_public(_: ()) {
eval_always
desc { "checking for private elements in public interfaces" }
}
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
Loading

0 comments on commit 02dde5d

Please sign in to comment.