mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Apply suggestions from code review
Co-authored-by: varkor <github@varkor.com>
This commit is contained in:
parent
1c176d1150
commit
85fdb34d3a
@ -451,7 +451,7 @@ impl Slice {
|
|||||||
///
|
///
|
||||||
/// A slice pattern `[x, .., y]` behaves like the infinite or-pattern `[x, y] | [x, _, y] | [x, _,
|
/// A slice pattern `[x, .., y]` behaves like the infinite or-pattern `[x, y] | [x, _, y] | [x, _,
|
||||||
/// _, y] | ...`. The corresponding value constructors are fixed-length array constructors above a
|
/// _, y] | ...`. The corresponding value constructors are fixed-length array constructors above a
|
||||||
/// given minimum length. We obviously can't list all of this infinity of constructors. Thankfully,
|
/// given minimum length. We obviously can't list this infinitude of constructors. Thankfully,
|
||||||
/// it turns out that for each finite set of slice patterns, all sufficiently large array lengths
|
/// it turns out that for each finite set of slice patterns, all sufficiently large array lengths
|
||||||
/// are equivalent.
|
/// are equivalent.
|
||||||
///
|
///
|
||||||
@ -491,7 +491,7 @@ impl Slice {
|
|||||||
/// middle. This means that the set of witnesses for length `l >= 5` if equivalent to the set for
|
/// middle. This means that the set of witnesses for length `l >= 5` if equivalent to the set for
|
||||||
/// any other `l' >= 5`: simply add or remove wildcards in the middle to convert between them.
|
/// any other `l' >= 5`: simply add or remove wildcards in the middle to convert between them.
|
||||||
///
|
///
|
||||||
/// This applies to any set of slice patterns: there will be a length `L` above which all length
|
/// This applies to any set of slice patterns: there will be a length `L` above which all lengths
|
||||||
/// behave the same. This is exactly what we need for constructor splitting. Therefore a
|
/// behave the same. This is exactly what we need for constructor splitting. Therefore a
|
||||||
/// variable-length slice can be split into a variable-length slice of minimal length `L`, and many
|
/// variable-length slice can be split into a variable-length slice of minimal length `L`, and many
|
||||||
/// fixed-length slices of lengths `< L`.
|
/// fixed-length slices of lengths `< L`.
|
||||||
@ -736,8 +736,8 @@ impl<'tcx> Constructor<'tcx> {
|
|||||||
// ranges check.
|
// ranges check.
|
||||||
IntRange(ctor_range) if !ctor_range.is_singleton() => {
|
IntRange(ctor_range) if !ctor_range.is_singleton() => {
|
||||||
let mut split_range = SplitIntRange::new(ctor_range.clone());
|
let mut split_range = SplitIntRange::new(ctor_range.clone());
|
||||||
let intranges = ctors.filter_map(|ctor| ctor.as_int_range());
|
let int_ranges = ctors.filter_map(|ctor| ctor.as_int_range());
|
||||||
split_range.split(intranges.cloned());
|
split_range.split(int_ranges.cloned());
|
||||||
split_range.iter().map(IntRange).collect()
|
split_range.iter().map(IntRange).collect()
|
||||||
}
|
}
|
||||||
&Slice(Slice { kind: VarLen(self_prefix, self_suffix), array_len }) => {
|
&Slice(Slice { kind: VarLen(self_prefix, self_suffix), array_len }) => {
|
||||||
@ -1080,7 +1080,7 @@ impl<'p, 'tcx> FilteredField<'p, 'tcx> {
|
|||||||
///
|
///
|
||||||
/// If a private or `non_exhaustive` field is uninhabited, the code mustn't observe that it is
|
/// If a private or `non_exhaustive` field is uninhabited, the code mustn't observe that it is
|
||||||
/// uninhabited. For that, we filter these fields out of the matrix. This is handled automatically
|
/// uninhabited. For that, we filter these fields out of the matrix. This is handled automatically
|
||||||
/// in `Fields`. This filtering is uncommon in practice, because uninhabited fields are rare used,
|
/// in `Fields`. This filtering is uncommon in practice, because uninhabited fields are rarely used,
|
||||||
/// so we avoid it when possible to preserve performance.
|
/// so we avoid it when possible to preserve performance.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(super) enum Fields<'p, 'tcx> {
|
pub(super) enum Fields<'p, 'tcx> {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
//!
|
//!
|
||||||
//! The algorithm implemented here is a modified version of the one described in [this
|
//! The algorithm implemented here is a modified version of the one described in [this
|
||||||
//! paper](http://moscova.inria.fr/~maranget/papers/warn/index.html). We have however generalized
|
//! paper](http://moscova.inria.fr/~maranget/papers/warn/index.html). We have however generalized
|
||||||
//! it to accomodate the variety of patterns that rust supports. We thus explain our version here,
|
//! it to accommodate the variety of patterns that Rust supports. We thus explain our version here,
|
||||||
//! without being as rigorous.
|
//! without being as rigorous.
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
@ -27,13 +27,13 @@
|
|||||||
//!
|
//!
|
||||||
//! The core of the algorithm is the notion of "usefulness". A pattern `q` is said to be *useful*
|
//! The core of the algorithm is the notion of "usefulness". A pattern `q` is said to be *useful*
|
||||||
//! relative to another pattern `p` of the same type if there is a value that is matched by `q` and
|
//! relative to another pattern `p` of the same type if there is a value that is matched by `q` and
|
||||||
//! not matched by `p`. This generalizes to many `p`s: `q` is useful wrt a list of patterns `p_1 ..
|
//! not matched by `p`. This generalizes to many `p`s: `q` is useful w.r.t. a list of patterns
|
||||||
//! p_n` if there is a value that is matched by `q` and by none of the `p_i`. We write
|
//! `p_1 .. p_n` if there is a value that is matched by `q` and by none of the `p_i`. We write
|
||||||
//! `usefulness(p_1 .. p_n, q)` for a function that returns a list of such values. The aim of this
|
//! `usefulness(p_1 .. p_n, q)` for a function that returns a list of such values. The aim of this
|
||||||
//! file is to compute it efficiently.
|
//! file is to compute it efficiently.
|
||||||
//!
|
//!
|
||||||
//! This is enough to compute reachability: a pattern in a `match` expression is reachable iff it
|
//! This is enough to compute reachability: a pattern in a `match` expression is reachable iff it
|
||||||
//! is useful wrt the patterns above it:
|
//! is useful w.r.t. the patterns above it:
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! match x {
|
//! match x {
|
||||||
//! Some(_) => ...,
|
//! Some(_) => ...,
|
||||||
@ -44,8 +44,8 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! This is also enough to compute exhaustiveness: a match is exhaustive iff the wildcard `_`
|
//! This is also enough to compute exhaustiveness: a match is exhaustive iff the wildcard `_`
|
||||||
//! pattern is _not_ useful wrt the patterns in the match. The values returned by `usefulness` are
|
//! pattern is _not_ useful w.r.t. the patterns in the match. The values returned by `usefulness`
|
||||||
//! used to tell the user which values are missing.
|
//! are used to tell the user which values are missing.
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! match x {
|
//! match x {
|
||||||
//! Some(0) => ...,
|
//! Some(0) => ...,
|
||||||
@ -102,7 +102,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Note: this constructors/fields distinction may not straightforwardly apply to every Rust type.
|
//! Note: this constructors/fields distinction may not straightforwardly apply to every Rust type.
|
||||||
//! For example a value of type `Rc<u64>` can't be deconstructed that way, and `&str` has an
|
//! For example a value of type `Rc<u64>` can't be deconstructed that way, and `&str` has an
|
||||||
//! infinity of constructors. There are also subtleties with visibility of fields and
|
//! infinitude of constructors. There are also subtleties with visibility of fields and
|
||||||
//! uninhabitedness and various other things. The constructors idea can be extended to handle most
|
//! uninhabitedness and various other things. The constructors idea can be extended to handle most
|
||||||
//! of these subtleties though; caveats are documented where relevant throughout the code.
|
//! of these subtleties though; caveats are documented where relevant throughout the code.
|
||||||
//!
|
//!
|
||||||
@ -184,7 +184,8 @@
|
|||||||
//!
|
//!
|
||||||
//! `specialize(c, p0 | p1) := specialize(c, p0) ++ specialize(c, p1)`
|
//! `specialize(c, p0 | p1) := specialize(c, p0) ++ specialize(c, p1)`
|
||||||
//!
|
//!
|
||||||
//! - We treat the other pattern constructors lik big or-patterns of all the possibilities:
|
//! - We treat the other pattern constructors as if they were a large or-pattern of all the
|
||||||
|
//! possibilities:
|
||||||
//!
|
//!
|
||||||
//! `specialize(c, _) := specialize(c, Variant1(_) | Variant2(_, _) | ...)`
|
//! `specialize(c, _) := specialize(c, Variant1(_) | Variant2(_, _) | ...)`
|
||||||
//!
|
//!
|
||||||
@ -193,7 +194,7 @@
|
|||||||
//! `specialize(c, [p0, .., p1]) := specialize(c, [p0, p1] | [p0, _, p1] | [p0, _, _, p1] | ...)`
|
//! `specialize(c, [p0, .., p1]) := specialize(c, [p0, p1] | [p0, _, p1] | [p0, _, _, p1] | ...)`
|
||||||
//!
|
//!
|
||||||
//! - If `c` is a pattern-only constructor, `specialize` is defined on a case-by-case basis. See
|
//! - If `c` is a pattern-only constructor, `specialize` is defined on a case-by-case basis. See
|
||||||
//! the discussion abount constructor splitting in [`super::deconstruct_pat`].
|
//! the discussion about constructor splitting in [`super::deconstruct_pat`].
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! We then extend this function to work with pattern-stacks as input, by acting on the first
|
//! We then extend this function to work with pattern-stacks as input, by acting on the first
|
||||||
|
Loading…
Reference in New Issue
Block a user