mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Remove Ty: Copy bound
This commit is contained in:
parent
227abacaef
commit
796cdc590c
@ -1130,7 +1130,7 @@ fn collect_non_exhaustive_tys<'tcx>(
|
|||||||
non_exhaustive_tys.insert(pat.ty().inner());
|
non_exhaustive_tys.insert(pat.ty().inner());
|
||||||
}
|
}
|
||||||
if let Constructor::IntRange(range) = pat.ctor() {
|
if let Constructor::IntRange(range) = pat.ctor() {
|
||||||
if cx.is_range_beyond_boundaries(range, pat.ty()) {
|
if cx.is_range_beyond_boundaries(range, *pat.ty()) {
|
||||||
// The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`.
|
// The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`.
|
||||||
non_exhaustive_tys.insert(pat.ty().inner());
|
non_exhaustive_tys.insert(pat.ty().inner());
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ impl<'a, T: ?Sized> Captures<'a> for T {}
|
|||||||
/// Most of the crate is parameterized on a type that implements this trait.
|
/// Most of the crate is parameterized on a type that implements this trait.
|
||||||
pub trait TypeCx: Sized + fmt::Debug {
|
pub trait TypeCx: Sized + fmt::Debug {
|
||||||
/// The type of a pattern.
|
/// The type of a pattern.
|
||||||
type Ty: Copy + Clone + fmt::Debug; // FIXME: remove Copy
|
type Ty: Clone + fmt::Debug;
|
||||||
/// Errors that can abort analysis.
|
/// Errors that can abort analysis.
|
||||||
type Error: fmt::Debug;
|
type Error: fmt::Debug;
|
||||||
/// The index of an enum variant.
|
/// The index of an enum variant.
|
||||||
@ -97,16 +97,16 @@ pub trait TypeCx: Sized + fmt::Debug {
|
|||||||
fn is_exhaustive_patterns_feature_on(&self) -> bool;
|
fn is_exhaustive_patterns_feature_on(&self) -> bool;
|
||||||
|
|
||||||
/// The number of fields for this constructor.
|
/// The number of fields for this constructor.
|
||||||
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: Self::Ty) -> usize;
|
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;
|
||||||
|
|
||||||
/// The types of the fields for this constructor. The result must have a length of
|
/// The types of the fields for this constructor. The result must have a length of
|
||||||
/// `ctor_arity()`.
|
/// `ctor_arity()`.
|
||||||
fn ctor_sub_tys(&self, ctor: &Constructor<Self>, ty: Self::Ty) -> &[Self::Ty];
|
fn ctor_sub_tys(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> &[Self::Ty];
|
||||||
|
|
||||||
/// The set of all the constructors for `ty`.
|
/// The set of all the constructors for `ty`.
|
||||||
///
|
///
|
||||||
/// This must follow the invariants of `ConstructorSet`
|
/// This must follow the invariants of `ConstructorSet`
|
||||||
fn ctors_for_ty(&self, ty: Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>;
|
fn ctors_for_ty(&self, ty: &Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>;
|
||||||
|
|
||||||
/// Best-effort `Debug` implementation.
|
/// Best-effort `Debug` implementation.
|
||||||
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;
|
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;
|
||||||
|
@ -46,7 +46,7 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn head_ty(&self) -> Option<RevealedTy<'tcx>> {
|
fn head_ty(&self) -> Option<RevealedTy<'tcx>> {
|
||||||
self.patterns.first().map(|pat| pat.ty())
|
self.patterns.first().map(|pat| *pat.ty())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do constructor splitting on the constructors of the column.
|
/// Do constructor splitting on the constructors of the column.
|
||||||
@ -101,7 +101,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
|
|||||||
let Some(ty) = column.head_ty() else {
|
let Some(ty) = column.head_ty() else {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
};
|
};
|
||||||
let pcx = &PlaceCtxt::new_dummy(cx, ty);
|
let pcx = &PlaceCtxt::new_dummy(cx, &ty);
|
||||||
|
|
||||||
let set = column.analyze_ctors(pcx)?;
|
let set = column.analyze_ctors(pcx)?;
|
||||||
if set.present.is_empty() {
|
if set.present.is_empty() {
|
||||||
|
@ -54,8 +54,8 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
|
|||||||
pub fn ctor(&self) -> &Constructor<Cx> {
|
pub fn ctor(&self) -> &Constructor<Cx> {
|
||||||
&self.ctor
|
&self.ctor
|
||||||
}
|
}
|
||||||
pub fn ty(&self) -> Cx::Ty {
|
pub fn ty(&self) -> &Cx::Ty {
|
||||||
self.ty
|
&self.ty
|
||||||
}
|
}
|
||||||
/// Returns the extra data stored in a pattern. Returns `None` if the pattern is a wildcard that
|
/// Returns the extra data stored in a pattern. Returns `None` if the pattern is a wildcard that
|
||||||
/// does not correspond to a user-supplied pattern.
|
/// does not correspond to a user-supplied pattern.
|
||||||
@ -242,15 +242,15 @@ impl<Cx: TypeCx> WitnessPat<Cx> {
|
|||||||
/// `Some(_)`.
|
/// `Some(_)`.
|
||||||
pub(crate) fn wild_from_ctor(pcx: &PlaceCtxt<'_, Cx>, ctor: Constructor<Cx>) -> Self {
|
pub(crate) fn wild_from_ctor(pcx: &PlaceCtxt<'_, Cx>, ctor: Constructor<Cx>) -> Self {
|
||||||
let field_tys = pcx.ctor_sub_tys(&ctor);
|
let field_tys = pcx.ctor_sub_tys(&ctor);
|
||||||
let fields = field_tys.iter().map(|ty| Self::wildcard(*ty)).collect();
|
let fields = field_tys.iter().cloned().map(|ty| Self::wildcard(ty)).collect();
|
||||||
Self::new(ctor, fields, pcx.ty)
|
Self::new(ctor, fields, pcx.ty.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ctor(&self) -> &Constructor<Cx> {
|
pub fn ctor(&self) -> &Constructor<Cx> {
|
||||||
&self.ctor
|
&self.ctor
|
||||||
}
|
}
|
||||||
pub fn ty(&self) -> Cx::Ty {
|
pub fn ty(&self) -> &Cx::Ty {
|
||||||
self.ty
|
&self.ty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_fields(&self) -> impl Iterator<Item = &WitnessPat<Cx>> {
|
pub fn iter_fields(&self) -> impl Iterator<Item = &WitnessPat<Cx>> {
|
||||||
|
@ -766,7 +766,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
let mut subpatterns = pat.iter_fields().map(|p| Box::new(cx.hoist_witness_pat(p)));
|
let mut subpatterns = pat.iter_fields().map(|p| Box::new(cx.hoist_witness_pat(p)));
|
||||||
let kind = match pat.ctor() {
|
let kind = match pat.ctor() {
|
||||||
Bool(b) => PatKind::Constant { value: mir::Const::from_bool(cx.tcx, *b) },
|
Bool(b) => PatKind::Constant { value: mir::Const::from_bool(cx.tcx, *b) },
|
||||||
IntRange(range) => return self.hoist_pat_range(range, pat.ty()),
|
IntRange(range) => return self.hoist_pat_range(range, *pat.ty()),
|
||||||
Struct | Variant(_) | UnionField => match pat.ty().kind() {
|
Struct | Variant(_) | UnionField => match pat.ty().kind() {
|
||||||
ty::Tuple(..) => PatKind::Leaf {
|
ty::Tuple(..) => PatKind::Leaf {
|
||||||
subpatterns: subpatterns
|
subpatterns: subpatterns
|
||||||
@ -785,7 +785,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
RustcMatchCheckCtxt::variant_index_for_adt(&pat.ctor(), *adt_def);
|
RustcMatchCheckCtxt::variant_index_for_adt(&pat.ctor(), *adt_def);
|
||||||
let variant = &adt_def.variant(variant_index);
|
let variant = &adt_def.variant(variant_index);
|
||||||
let subpatterns = cx
|
let subpatterns = cx
|
||||||
.list_variant_nonhidden_fields(pat.ty(), variant)
|
.list_variant_nonhidden_fields(*pat.ty(), variant)
|
||||||
.zip(subpatterns)
|
.zip(subpatterns)
|
||||||
.map(|((field, _ty), pattern)| FieldPat { field, pattern })
|
.map(|((field, _ty), pattern)| FieldPat { field, pattern })
|
||||||
.collect();
|
.collect();
|
||||||
@ -796,7 +796,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
PatKind::Leaf { subpatterns }
|
PatKind::Leaf { subpatterns }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => bug!("unexpected ctor for type {:?} {:?}", pat.ctor(), pat.ty()),
|
_ => bug!("unexpected ctor for type {:?} {:?}", pat.ctor(), *pat.ty()),
|
||||||
},
|
},
|
||||||
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
|
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
|
||||||
// be careful to reconstruct the correct constant pattern here. However a string
|
// be careful to reconstruct the correct constant pattern here. However a string
|
||||||
@ -961,21 +961,21 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
self.tcx.features().exhaustive_patterns
|
self.tcx.features().exhaustive_patterns
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: Self::Ty) -> usize {
|
fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
|
||||||
self.ctor_arity(ctor, ty)
|
self.ctor_arity(ctor, *ty)
|
||||||
}
|
}
|
||||||
fn ctor_sub_tys(
|
fn ctor_sub_tys(
|
||||||
&self,
|
&self,
|
||||||
ctor: &crate::constructor::Constructor<Self>,
|
ctor: &crate::constructor::Constructor<Self>,
|
||||||
ty: Self::Ty,
|
ty: &Self::Ty,
|
||||||
) -> &[Self::Ty] {
|
) -> &[Self::Ty] {
|
||||||
self.ctor_sub_tys(ctor, ty)
|
self.ctor_sub_tys(ctor, *ty)
|
||||||
}
|
}
|
||||||
fn ctors_for_ty(
|
fn ctors_for_ty(
|
||||||
&self,
|
&self,
|
||||||
ty: Self::Ty,
|
ty: &Self::Ty,
|
||||||
) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> {
|
) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> {
|
||||||
self.ctors_for_ty(ty)
|
self.ctors_for_ty(*ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_pat(
|
fn debug_pat(
|
||||||
@ -994,7 +994,7 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
overlaps_on: IntRange,
|
overlaps_on: IntRange,
|
||||||
overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
|
overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
|
||||||
) {
|
) {
|
||||||
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, pat.ty());
|
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
|
||||||
let overlaps: Vec<_> = overlaps_with
|
let overlaps: Vec<_> = overlaps_with
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pat| pat.data().unwrap().span)
|
.map(|pat| pat.data().unwrap().span)
|
||||||
|
@ -736,13 +736,14 @@ pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
|
|||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub(crate) mcx: MatchCtxt<'a, Cx>,
|
pub(crate) mcx: MatchCtxt<'a, Cx>,
|
||||||
/// Type of the place under investigation.
|
/// Type of the place under investigation.
|
||||||
pub(crate) ty: Cx::Ty,
|
#[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
|
||||||
|
pub(crate) ty: &'a Cx::Ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
|
impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
|
||||||
/// A `PlaceCtxt` when code other than `is_useful` needs one.
|
/// A `PlaceCtxt` when code other than `is_useful` needs one.
|
||||||
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
|
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
|
||||||
pub(crate) fn new_dummy(mcx: MatchCtxt<'a, Cx>, ty: Cx::Ty) -> Self {
|
pub(crate) fn new_dummy(mcx: MatchCtxt<'a, Cx>, ty: &'a Cx::Ty) -> Self {
|
||||||
PlaceCtxt { mcx, ty }
|
PlaceCtxt { mcx, ty }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,8 +1024,8 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
|
|||||||
matrix
|
matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
fn head_ty(&self) -> Option<Cx::Ty> {
|
fn head_ty(&self) -> Option<&Cx::Ty> {
|
||||||
self.place_ty.first().copied()
|
self.place_ty.first()
|
||||||
}
|
}
|
||||||
fn column_count(&self) -> usize {
|
fn column_count(&self) -> usize {
|
||||||
self.place_ty.len()
|
self.place_ty.len()
|
||||||
@ -1058,7 +1059,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
|
|||||||
let ctor_sub_tys = pcx.ctor_sub_tys(ctor);
|
let ctor_sub_tys = pcx.ctor_sub_tys(ctor);
|
||||||
let arity = ctor_sub_tys.len();
|
let arity = ctor_sub_tys.len();
|
||||||
let specialized_place_ty =
|
let specialized_place_ty =
|
||||||
ctor_sub_tys.iter().chain(self.place_ty[1..].iter()).copied().collect();
|
ctor_sub_tys.iter().chain(self.place_ty[1..].iter()).cloned().collect();
|
||||||
let ctor_sub_validity = self.place_validity[0].specialize(ctor);
|
let ctor_sub_validity = self.place_validity[0].specialize(ctor);
|
||||||
let specialized_place_validity = std::iter::repeat(ctor_sub_validity)
|
let specialized_place_validity = std::iter::repeat(ctor_sub_validity)
|
||||||
.take(arity)
|
.take(arity)
|
||||||
@ -1214,7 +1215,7 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
|
|||||||
let len = self.0.len();
|
let len = self.0.len();
|
||||||
let arity = ctor.arity(pcx);
|
let arity = ctor.arity(pcx);
|
||||||
let fields = self.0.drain((len - arity)..).rev().collect();
|
let fields = self.0.drain((len - arity)..).rev().collect();
|
||||||
let pat = WitnessPat::new(ctor.clone(), fields, pcx.ty);
|
let pat = WitnessPat::new(ctor.clone(), fields, pcx.ty.clone());
|
||||||
self.0.push(pat);
|
self.0.push(pat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1410,7 +1411,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
|
|||||||
return Ok(WitnessMatrix::empty());
|
return Ok(WitnessMatrix::empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(ty) = matrix.head_ty() else {
|
let Some(ty) = matrix.head_ty().cloned() else {
|
||||||
// The base case: there are no columns in the matrix. We are morally pattern-matching on ().
|
// The base case: there are no columns in the matrix. We are morally pattern-matching on ().
|
||||||
// A row is useful iff it has no (unguarded) rows above it.
|
// A row is useful iff it has no (unguarded) rows above it.
|
||||||
let mut useful = true; // Whether the next row is useful.
|
let mut useful = true; // Whether the next row is useful.
|
||||||
@ -1431,7 +1432,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug!("ty: {ty:?}");
|
debug!("ty: {ty:?}");
|
||||||
let pcx = &PlaceCtxt { mcx, ty };
|
let pcx = &PlaceCtxt { mcx, ty: &ty };
|
||||||
let ctors_for_ty = pcx.ctors_for_ty()?;
|
let ctors_for_ty = pcx.ctors_for_ty()?;
|
||||||
|
|
||||||
// Whether the place/column we are inspecting is known to contain valid data.
|
// Whether the place/column we are inspecting is known to contain valid data.
|
||||||
|
Loading…
Reference in New Issue
Block a user