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 8 pull requests #120187

Merged
merged 23 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
27f419b
implement strict_* operations for signed integer types
rmehri01 Sep 22, 2023
fb349a2
implement strict_* operations for unsigned integer types
rmehri01 Sep 23, 2023
8c7a5b0
add `#[track_caller]` to improve panic locations
rmehri01 Sep 23, 2023
6d17169
reword panic comments and add spaces to unlikely branches
rmehri01 Nov 28, 2023
605504c
Add Ipv6Addr::is_ipv4_mapped
CDirkx Jun 19, 2021
70b0364
std: move OS String implementation into `sys`
joboet Jan 15, 2024
f149442
coverage: Add `#[rustfmt::skip]` to tests with non-standard formatting
Zalathar Jan 16, 2024
1f9353a
coverage: Tweak individual tests to be unaffected by `rustfmt`
Zalathar Jan 16, 2024
99797bb
coverage: Format all remaining tests
Zalathar Jan 16, 2024
9650c30
fix(rust-analyzer): use new pkgid spec to compare
weihanglo Jan 18, 2024
be9668d
Use an interpreter in jump threading.
cjgillot Dec 31, 2023
b22742e
Extract process_constant.
cjgillot Dec 31, 2023
e72b2b1
Extract process_assign.
cjgillot Dec 31, 2023
796cdc5
Remove Ty: Copy bound
Nadrieril Dec 22, 2023
606eeb8
Use bool instead of PartiolOrd in is_sorted_by
EbbDrop Dec 10, 2023
b661cd6
Rollup merge of #116090 - rmehri01:strict_integer_ops, r=m-ou-se
Nadrieril Jan 21, 2024
e8d1c2e
Rollup merge of #118811 - EbbDrop:is-sorted-by-bool, r=Mark-Simulacrum
Nadrieril Jan 21, 2024
3cd378c
Rollup merge of #119081 - jstasiak:is-ipv4-mapped, r=dtolnay
Nadrieril Jan 21, 2024
203cc69
Rollup merge of #119461 - cjgillot:jump-threading-interp, r=tmiasko
Nadrieril Jan 21, 2024
a1b41a9
Rollup merge of #119996 - joboet:move_pal_os_str, r=ChrisDenton
Nadrieril Jan 21, 2024
e8678b1
Rollup merge of #120015 - Zalathar:format, r=dtolnay
Nadrieril Jan 21, 2024
e7f3dc7
Rollup merge of #120027 - Nadrieril:remove-ty-copy-bound, r=compiler-…
Nadrieril Jan 21, 2024
01669d2
Rollup merge of #120084 - weihanglo:pkgid-spec, r=Mark-Simulacrum
Nadrieril Jan 21, 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
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ fn collect_non_exhaustive_tys<'tcx>(
non_exhaustive_tys.insert(pat.ty().inner());
}
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`.
non_exhaustive_tys.insert(pat.ty().inner());
}
Expand Down
262 changes: 155 additions & 107 deletions compiler/rustc_mir_transform/src/jump_threading.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ where
}

// Ensure CGUs are sorted by name, so that we get deterministic results.
if !codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))) {
if !codegen_units.is_sorted_by(|a, b| a.name().as_str() <= b.name().as_str()) {
let mut names = String::new();
for cgu in codegen_units.iter() {
names += &format!("- {}\n", cgu.name());
Expand Down Expand Up @@ -317,7 +317,7 @@ fn merge_codegen_units<'tcx>(
assert!(cx.tcx.sess.codegen_units().as_usize() >= 1);

// A sorted order here ensures merging is deterministic.
assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))));
assert!(codegen_units.is_sorted_by(|a, b| a.name().as_str() <= b.name().as_str()));

// This map keeps track of what got merged into what.
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_pattern_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
pub trait TypeCx: Sized + fmt::Debug {
/// The type of a pattern.
type Ty: Copy + Clone + fmt::Debug; // FIXME: remove Copy
type Ty: Clone + fmt::Debug;
/// Errors that can abort analysis.
type Error: fmt::Debug;
/// The index of an enum variant.
Expand All @@ -97,16 +97,16 @@ pub trait TypeCx: Sized + fmt::Debug {
fn is_exhaustive_patterns_feature_on(&self) -> bool;

/// 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
/// `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`.
///
/// 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.
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_pattern_analysis/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<'p, 'tcx> PatternColumn<'p, '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.
Expand Down Expand Up @@ -101,7 +101,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
let Some(ty) = column.head_ty() else {
return Ok(Vec::new());
};
let pcx = &PlaceCtxt::new_dummy(cx, ty);
let pcx = &PlaceCtxt::new_dummy(cx, &ty);

let set = column.analyze_ctors(pcx)?;
if set.present.is_empty() {
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_pattern_analysis/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
pub fn ctor(&self) -> &Constructor<Cx> {
&self.ctor
}
pub fn ty(&self) -> Cx::Ty {
self.ty
pub fn ty(&self) -> &Cx::Ty {
&self.ty
}
/// 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.
Expand Down Expand Up @@ -242,15 +242,15 @@ impl<Cx: TypeCx> WitnessPat<Cx> {
/// `Some(_)`.
pub(crate) fn wild_from_ctor(pcx: &PlaceCtxt<'_, Cx>, ctor: Constructor<Cx>) -> Self {
let field_tys = pcx.ctor_sub_tys(&ctor);
let fields = field_tys.iter().map(|ty| Self::wildcard(*ty)).collect();
Self::new(ctor, fields, pcx.ty)
let fields = field_tys.iter().cloned().map(|ty| Self::wildcard(ty)).collect();
Self::new(ctor, fields, pcx.ty.clone())
}

pub fn ctor(&self) -> &Constructor<Cx> {
&self.ctor
}
pub fn ty(&self) -> Cx::Ty {
self.ty
pub fn ty(&self) -> &Cx::Ty {
&self.ty
}

pub fn iter_fields(&self) -> impl Iterator<Item = &WitnessPat<Cx>> {
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 kind = match pat.ctor() {
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() {
ty::Tuple(..) => PatKind::Leaf {
subpatterns: subpatterns
Expand All @@ -785,7 +785,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
RustcMatchCheckCtxt::variant_index_for_adt(&pat.ctor(), *adt_def);
let variant = &adt_def.variant(variant_index);
let subpatterns = cx
.list_variant_nonhidden_fields(pat.ty(), variant)
.list_variant_nonhidden_fields(*pat.ty(), variant)
.zip(subpatterns)
.map(|((field, _ty), pattern)| FieldPat { field, pattern })
.collect();
Expand All @@ -796,7 +796,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
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
// be careful to reconstruct the correct constant pattern here. However a string
Expand Down Expand Up @@ -961,21 +961,21 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
self.tcx.features().exhaustive_patterns
}

fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: Self::Ty) -> usize {
self.ctor_arity(ctor, ty)
fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
self.ctor_arity(ctor, *ty)
}
fn ctor_sub_tys(
&self,
ctor: &crate::constructor::Constructor<Self>,
ty: Self::Ty,
ty: &Self::Ty,
) -> &[Self::Ty] {
self.ctor_sub_tys(ctor, ty)
self.ctor_sub_tys(ctor, *ty)
}
fn ctors_for_ty(
&self,
ty: Self::Ty,
ty: &Self::Ty,
) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> {
self.ctors_for_ty(ty)
self.ctors_for_ty(*ty)
}

fn debug_pat(
Expand All @@ -994,7 +994,7 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
overlaps_on: IntRange,
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
.iter()
.map(|pat| pat.data().unwrap().span)
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_pattern_analysis/src/usefulness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,13 +736,14 @@ pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
#[derivative(Debug = "ignore")]
pub(crate) mcx: MatchCtxt<'a, Cx>,
/// 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> {
/// A `PlaceCtxt` when code other than `is_useful` needs one.
#[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 }
}

Expand Down Expand Up @@ -1023,8 +1024,8 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
matrix
}

fn head_ty(&self) -> Option<Cx::Ty> {
self.place_ty.first().copied()
fn head_ty(&self) -> Option<&Cx::Ty> {
self.place_ty.first()
}
fn column_count(&self) -> usize {
self.place_ty.len()
Expand Down Expand Up @@ -1058,7 +1059,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
let ctor_sub_tys = pcx.ctor_sub_tys(ctor);
let arity = ctor_sub_tys.len();
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 specialized_place_validity = std::iter::repeat(ctor_sub_validity)
.take(arity)
Expand Down Expand Up @@ -1214,7 +1215,7 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
let len = self.0.len();
let arity = ctor.arity(pcx);
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);
}
}
Expand Down Expand Up @@ -1410,7 +1411,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
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 ().
// A row is useful iff it has no (unguarded) rows above it.
let mut useful = true; // Whether the next row is useful.
Expand All @@ -1431,7 +1432,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
};

debug!("ty: {ty:?}");
let pcx = &PlaceCtxt { mcx, ty };
let pcx = &PlaceCtxt { mcx, ty: &ty };
let ctors_for_ty = pcx.ctors_for_ty()?;

// Whether the place/column we are inspecting is known to contain valid data.
Expand Down
26 changes: 13 additions & 13 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4033,42 +4033,42 @@ pub trait Iterator {
Self: Sized,
Self::Item: PartialOrd,
{
self.is_sorted_by(PartialOrd::partial_cmp)
self.is_sorted_by(|a, b| a <= b)
}

/// Checks if the elements of this iterator are sorted using the given comparator function.
///
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
/// [`is_sorted`]; see its documentation for more information.
/// function to determine whether two elements are to be considered in sorted order.
///
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// ```
/// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a <= b));
/// assert!(![1, 2, 2, 9].iter().is_sorted_by(|a, b| a < b));
///
/// [`is_sorted`]: Iterator::is_sorted
/// assert!([0].iter().is_sorted_by(|a, b| true));
/// assert!([0].iter().is_sorted_by(|a, b| false));
///
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| false));
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| true));
/// ```
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[rustc_do_not_const_check]
fn is_sorted_by<F>(mut self, compare: F) -> bool
where
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
F: FnMut(&Self::Item, &Self::Item) -> bool,
{
#[inline]
fn check<'a, T>(
last: &'a mut T,
mut compare: impl FnMut(&T, &T) -> Option<Ordering> + 'a,
mut compare: impl FnMut(&T, &T) -> bool + 'a,
) -> impl FnMut(T) -> bool + 'a {
move |curr| {
if let Some(Ordering::Greater) | None = compare(&last, &curr) {
if !compare(&last, &curr) {
return false;
}
*last = curr;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
#![feature(const_slice_ptr_len)]
#![feature(const_slice_split_at_mut)]
#![feature(const_str_from_utf8_unchecked_mut)]
#![feature(const_strict_overflow_ops)]
#![feature(const_swap)]
#![feature(const_try)]
#![feature(const_type_id)]
Expand Down
25 changes: 25 additions & 0 deletions library/core/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,31 @@ impl Ipv6Addr {
(self.segments()[0] & 0xff00) == 0xff00
}

/// Returns [`true`] if the address is an IPv4-mapped address (`::ffff:0:0/96`).
///
/// IPv4-mapped addresses can be converted to their canonical IPv4 address with
/// [`to_ipv4_mapped`](Ipv6Addr::to_ipv4_mapped).
///
/// # Examples
/// ```
/// #![feature(ip)]
///
/// use std::net::{Ipv4Addr, Ipv6Addr};
///
/// let ipv4_mapped = Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped();
/// assert_eq!(ipv4_mapped.is_ipv4_mapped(), true);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff).is_ipv4_mapped(), true);
///
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_ipv4_mapped(), false);
/// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[unstable(feature = "ip", issue = "27709")]
#[must_use]
#[inline]
pub const fn is_ipv4_mapped(&self) -> bool {
matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
}

/// Converts this address to an [`IPv4` address] if it's an [IPv4-mapped] address,
/// as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
///
Expand Down
Loading
Loading