Skip to content

Commit 69e36d6

Browse files
committed
Auto merge of rust-lang#129143 - workingjubilee:rollup-h0hzumu, r=workingjubilee
Rollup of 9 pull requests Successful merges: - rust-lang#128064 (Improve docs for Waker::noop and LocalWaker::noop) - rust-lang#128922 (rust-analyzer: use in-tree `pattern_analysis` crate) - rust-lang#128965 (Remove `print::Pat` from the printing of `WitnessPat`) - rust-lang#129018 (Migrate `rlib-format-packed-bundled-libs` and `native-link-modifier-bundle` `run-make` tests to rmake) - rust-lang#129037 (Port `run-make/libtest-json` and `run-make/libtest-junit` to rmake) - rust-lang#129078 (`ParamEnvAnd::fully_perform`: we have an `ocx`, use it) - rust-lang#129110 (Add a comment explaining the return type of `Ty::kind`.) - rust-lang#129111 (Port the `sysroot-crates-are-unstable` Python script to rmake) - rust-lang#129135 (crashes: more tests) r? `@ghost` `@rustbot` modify labels: rollup
2 parents be0ea0c + e463490 commit 69e36d6

File tree

29 files changed

+564
-350
lines changed

29 files changed

+564
-350
lines changed

compiler/rustc_middle/src/ty/sty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
970970

971971
/// Type utilities
972972
impl<'tcx> Ty<'tcx> {
973+
// It would be nicer if this returned the value instead of a reference,
974+
// like how `Predicate::kind` and `Region::kind` do. (It would result in
975+
// many fewer subsequent dereferences.) But that gives a small but
976+
// noticeable performance hit. See #126069 for details.
973977
#[inline(always)]
974978
pub fn kind(self) -> &'tcx TyKind<'tcx> {
975979
self.0.0

compiler/rustc_pattern_analysis/src/rustc.rs

+45-38
Original file line numberDiff line numberDiff line change
@@ -774,17 +774,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
774774
}
775775
}
776776

777-
/// Convert to a [`print::Pat`] for diagnostic purposes.
778-
fn hoist_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> print::Pat<'tcx> {
779-
use print::{Pat, PatKind};
777+
/// Prints an [`IntRange`] to a string for diagnostic purposes.
778+
fn print_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> String {
780779
use MaybeInfiniteInt::*;
781780
let cx = self;
782-
let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) {
783-
PatKind::Wild
781+
if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) {
782+
"_".to_string()
784783
} else if range.is_singleton() {
785784
let lo = cx.hoist_pat_range_bdy(range.lo, ty);
786785
let value = lo.as_finite().unwrap();
787-
PatKind::Constant { value }
786+
value.to_string()
788787
} else {
789788
// We convert to an inclusive range for diagnostics.
790789
let mut end = rustc_hir::RangeEnd::Included;
@@ -807,32 +806,24 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
807806
range.hi
808807
};
809808
let hi = cx.hoist_pat_range_bdy(hi, ty);
810-
PatKind::Range(Box::new(PatRange { lo, hi, end, ty: ty.inner() }))
811-
};
812-
813-
Pat { ty: ty.inner(), kind }
809+
PatRange { lo, hi, end, ty: ty.inner() }.to_string()
810+
}
814811
}
815812

816813
/// Prints a [`WitnessPat`] to an owned string, for diagnostic purposes.
814+
///
815+
/// This panics for patterns that don't appear in diagnostics, like float ranges.
817816
pub fn print_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> String {
818-
// This works by converting the witness pattern to a `print::Pat`
819-
// and then printing that, but callers don't need to know that.
820-
self.hoist_witness_pat(pat).to_string()
821-
}
822-
823-
/// Convert to a [`print::Pat`] for diagnostic purposes. This panics for patterns that don't
824-
/// appear in diagnostics, like float ranges.
825-
fn hoist_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> print::Pat<'tcx> {
826-
use print::{FieldPat, Pat, PatKind};
827817
let cx = self;
828-
let hoist = |p| Box::new(cx.hoist_witness_pat(p));
829-
let kind = match pat.ctor() {
830-
Bool(b) => PatKind::Constant { value: mir::Const::from_bool(cx.tcx, *b) },
831-
IntRange(range) => return self.hoist_pat_range(range, *pat.ty()),
818+
let print = |p| cx.print_witness_pat(p);
819+
match pat.ctor() {
820+
Bool(b) => b.to_string(),
821+
Str(s) => s.to_string(),
822+
IntRange(range) => return self.print_pat_range(range, *pat.ty()),
832823
Struct if pat.ty().is_box() => {
833824
// Outside of the `alloc` crate, the only way to create a struct pattern
834825
// of type `Box` is to use a `box` pattern via #[feature(box_patterns)].
835-
PatKind::Box { subpattern: hoist(&pat.fields[0]) }
826+
format!("box {}", print(&pat.fields[0]))
836827
}
837828
Struct | Variant(_) | UnionField => {
838829
let enum_info = match *pat.ty().kind() {
@@ -847,12 +838,29 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
847838
let subpatterns = pat
848839
.iter_fields()
849840
.enumerate()
850-
.map(|(i, pat)| FieldPat { field: FieldIdx::new(i), pattern: hoist(pat) })
841+
.map(|(i, pat)| print::FieldPat {
842+
field: FieldIdx::new(i),
843+
pattern: print(pat),
844+
is_wildcard: would_print_as_wildcard(cx.tcx, pat),
845+
})
851846
.collect::<Vec<_>>();
852847

853-
PatKind::StructLike { enum_info, subpatterns }
848+
let mut s = String::new();
849+
print::write_struct_like(
850+
&mut s,
851+
self.tcx,
852+
pat.ty().inner(),
853+
&enum_info,
854+
&subpatterns,
855+
)
856+
.unwrap();
857+
s
858+
}
859+
Ref => {
860+
let mut s = String::new();
861+
print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap();
862+
s
854863
}
855-
Ref => PatKind::Deref { subpattern: hoist(&pat.fields[0]) },
856864
Slice(slice) => {
857865
let (prefix_len, has_dot_dot) = match slice.kind {
858866
SliceKind::FixedLen(len) => (len, false),
@@ -879,24 +887,23 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
879887
}
880888
}
881889

882-
let prefix = prefix.iter().map(hoist).collect();
883-
let suffix = suffix.iter().map(hoist).collect();
890+
let prefix = prefix.iter().map(print).collect::<Vec<_>>();
891+
let suffix = suffix.iter().map(print).collect::<Vec<_>>();
884892

885-
PatKind::Slice { prefix, has_dot_dot, suffix }
893+
let mut s = String::new();
894+
print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap();
895+
s
886896
}
887-
&Str(value) => PatKind::Constant { value },
888-
Never if self.tcx.features().never_patterns => PatKind::Never,
889-
Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild,
897+
Never if self.tcx.features().never_patterns => "!".to_string(),
898+
Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => "_".to_string(),
890899
Missing { .. } => bug!(
891900
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
892901
`Missing` should have been processed in `apply_constructors`"
893902
),
894903
F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Opaque(..) | Or => {
895904
bug!("can't convert to pattern: {:?}", pat)
896905
}
897-
};
898-
899-
Pat { ty: pat.ty().inner(), kind }
906+
}
900907
}
901908
}
902909

@@ -972,7 +979,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
972979
overlaps_on: IntRange,
973980
overlaps_with: &[&crate::pat::DeconstructedPat<Self>],
974981
) {
975-
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
982+
let overlap_as_pat = self.print_pat_range(&overlaps_on, *pat.ty());
976983
let overlaps: Vec<_> = overlaps_with
977984
.iter()
978985
.map(|pat| pat.data().span)
@@ -1012,7 +1019,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
10121019
suggested_range.end = rustc_hir::RangeEnd::Included;
10131020
suggested_range.to_string()
10141021
};
1015-
let gap_as_pat = self.hoist_pat_range(&gap, *pat.ty());
1022+
let gap_as_pat = self.print_pat_range(&gap, *pat.ty());
10161023
if gapped_with.is_empty() {
10171024
// If `gapped_with` is empty, `gap == T::MAX`.
10181025
self.tcx.emit_node_span_lint(

compiler/rustc_pattern_analysis/src/rustc/print.rs

+15-74
Original file line numberDiff line numberDiff line change
@@ -11,75 +11,16 @@
1111
1212
use std::fmt;
1313

14-
use rustc_middle::thir::PatRange;
14+
use rustc_middle::bug;
1515
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
16-
use rustc_middle::{bug, mir};
1716
use rustc_span::sym;
1817
use rustc_target::abi::{FieldIdx, VariantIdx};
1918

2019
#[derive(Clone, Debug)]
21-
pub(crate) struct FieldPat<'tcx> {
20+
pub(crate) struct FieldPat {
2221
pub(crate) field: FieldIdx,
23-
pub(crate) pattern: Box<Pat<'tcx>>,
24-
}
25-
26-
#[derive(Clone, Debug)]
27-
pub(crate) struct Pat<'tcx> {
28-
pub(crate) ty: Ty<'tcx>,
29-
pub(crate) kind: PatKind<'tcx>,
30-
}
31-
32-
#[derive(Clone, Debug)]
33-
pub(crate) enum PatKind<'tcx> {
34-
Wild,
35-
36-
StructLike {
37-
enum_info: EnumInfo<'tcx>,
38-
subpatterns: Vec<FieldPat<'tcx>>,
39-
},
40-
41-
Box {
42-
subpattern: Box<Pat<'tcx>>,
43-
},
44-
45-
Deref {
46-
subpattern: Box<Pat<'tcx>>,
47-
},
48-
49-
Constant {
50-
value: mir::Const<'tcx>,
51-
},
52-
53-
Range(Box<PatRange<'tcx>>),
54-
55-
Slice {
56-
prefix: Box<[Box<Pat<'tcx>>]>,
57-
/// True if this slice-like pattern should include a `..` between the
58-
/// prefix and suffix.
59-
has_dot_dot: bool,
60-
suffix: Box<[Box<Pat<'tcx>>]>,
61-
},
62-
63-
Never,
64-
}
65-
66-
impl<'tcx> fmt::Display for Pat<'tcx> {
67-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68-
match self.kind {
69-
PatKind::Wild => write!(f, "_"),
70-
PatKind::Never => write!(f, "!"),
71-
PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"),
72-
PatKind::StructLike { ref enum_info, ref subpatterns } => {
73-
ty::tls::with(|tcx| write_struct_like(f, tcx, self.ty, enum_info, subpatterns))
74-
}
75-
PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern),
76-
PatKind::Constant { value } => write!(f, "{value}"),
77-
PatKind::Range(ref range) => write!(f, "{range}"),
78-
PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => {
79-
write_slice_like(f, prefix, has_dot_dot, suffix)
80-
}
81-
}
82-
}
22+
pub(crate) pattern: String,
23+
pub(crate) is_wildcard: bool,
8324
}
8425

8526
/// Returns a closure that will return `""` when called the first time,
@@ -103,12 +44,12 @@ pub(crate) enum EnumInfo<'tcx> {
10344
NotEnum,
10445
}
10546

106-
fn write_struct_like<'tcx>(
47+
pub(crate) fn write_struct_like<'tcx>(
10748
f: &mut impl fmt::Write,
10849
tcx: TyCtxt<'_>,
10950
ty: Ty<'tcx>,
11051
enum_info: &EnumInfo<'tcx>,
111-
subpatterns: &[FieldPat<'tcx>],
52+
subpatterns: &[FieldPat],
11253
) -> fmt::Result {
11354
let variant_and_name = match *enum_info {
11455
EnumInfo::Enum { adt_def, variant_index } => {
@@ -139,12 +80,12 @@ fn write_struct_like<'tcx>(
13980
write!(f, " {{ ")?;
14081

14182
let mut printed = 0;
142-
for p in subpatterns {
143-
if let PatKind::Wild = p.pattern.kind {
83+
for &FieldPat { field, ref pattern, is_wildcard } in subpatterns {
84+
if is_wildcard {
14485
continue;
14586
}
146-
let name = variant.fields[p.field].name;
147-
write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?;
87+
let field_name = variant.fields[field].name;
88+
write!(f, "{}{field_name}: {pattern}", start_or_comma())?;
14889
printed += 1;
14990
}
15091

@@ -184,10 +125,10 @@ fn write_struct_like<'tcx>(
184125
Ok(())
185126
}
186127

187-
fn write_ref_like<'tcx>(
128+
pub(crate) fn write_ref_like<'tcx>(
188129
f: &mut impl fmt::Write,
189130
ty: Ty<'tcx>,
190-
subpattern: &Pat<'tcx>,
131+
subpattern: &str,
191132
) -> fmt::Result {
192133
match ty.kind() {
193134
ty::Ref(_, _, mutbl) => {
@@ -198,11 +139,11 @@ fn write_ref_like<'tcx>(
198139
write!(f, "{subpattern}")
199140
}
200141

201-
fn write_slice_like<'tcx>(
142+
pub(crate) fn write_slice_like(
202143
f: &mut impl fmt::Write,
203-
prefix: &[Box<Pat<'tcx>>],
144+
prefix: &[String],
204145
has_dot_dot: bool,
205-
suffix: &[Box<Pat<'tcx>>],
146+
suffix: &[String],
206147
) -> fmt::Result {
207148
let mut start_or_comma = start_or_comma();
208149
write!(f, "[")?;

compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

+3-35
Original file line numberDiff line numberDiff line change
@@ -168,44 +168,12 @@ where
168168
// collecting region constraints via `region_constraints`.
169169
let (mut output, _) = scrape_region_constraints(
170170
infcx,
171-
|_ocx| {
172-
let (output, ei, mut obligations, _) =
171+
|ocx| {
172+
let (output, ei, obligations, _) =
173173
Q::fully_perform_into(self, infcx, &mut region_constraints, span)?;
174174
error_info = ei;
175175

176-
// Typically, instantiating NLL query results does not
177-
// create obligations. However, in some cases there
178-
// are unresolved type variables, and unify them *can*
179-
// create obligations. In that case, we have to go
180-
// fulfill them. We do this via a (recursive) query.
181-
while !obligations.is_empty() {
182-
trace!("{:#?}", obligations);
183-
let mut progress = false;
184-
for obligation in std::mem::take(&mut obligations) {
185-
let obligation = infcx.resolve_vars_if_possible(obligation);
186-
match ProvePredicate::fully_perform_into(
187-
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
188-
infcx,
189-
&mut region_constraints,
190-
span,
191-
) {
192-
Ok(((), _, new, certainty)) => {
193-
obligations.extend(new);
194-
progress = true;
195-
if let Certainty::Ambiguous = certainty {
196-
obligations.push(obligation);
197-
}
198-
}
199-
Err(_) => obligations.push(obligation),
200-
}
201-
}
202-
if !progress {
203-
infcx.dcx().span_bug(
204-
span,
205-
format!("ambiguity processing {obligations:?} from {self:?}"),
206-
);
207-
}
208-
}
176+
ocx.register_obligations(obligations);
209177
Ok(output)
210178
},
211179
"fully_perform",

library/core/src/task/wake.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,18 @@ impl Waker {
530530

531531
/// Returns a reference to a `Waker` that does nothing when used.
532532
///
533+
// Note! Much of the documentation for this method is duplicated
534+
// in the docs for `LocalWaker::noop`.
535+
// If you edit it, consider editing the other copy too.
536+
//
533537
/// This is mostly useful for writing tests that need a [`Context`] to poll
534538
/// some futures, but are not expecting those futures to wake the waker or
535539
/// do not need to do anything specific if it happens.
536540
///
541+
/// More generally, using `Waker::noop()` to poll a future
542+
/// means discarding the notification of when the future should be polled again.
543+
/// So it should only be used when such a notification will not be needed to make progress.
544+
///
537545
/// If an owned `Waker` is needed, `clone()` this one.
538546
///
539547
/// # Examples
@@ -783,12 +791,22 @@ impl LocalWaker {
783791
Self { waker }
784792
}
785793

786-
/// Creates a new `LocalWaker` that does nothing when `wake` is called.
794+
/// Returns a reference to a `LocalWaker` that does nothing when used.
787795
///
796+
// Note! Much of the documentation for this method is duplicated
797+
// in the docs for `Waker::noop`.
798+
// If you edit it, consider editing the other copy too.
799+
//
788800
/// This is mostly useful for writing tests that need a [`Context`] to poll
789801
/// some futures, but are not expecting those futures to wake the waker or
790802
/// do not need to do anything specific if it happens.
791803
///
804+
/// More generally, using `LocalWaker::noop()` to poll a future
805+
/// means discarding the notification of when the future should be polled again,
806+
/// So it should only be used when such a notification will not be needed to make progress.
807+
///
808+
/// If an owned `LocalWaker` is needed, `clone()` this one.
809+
///
792810
/// # Examples
793811
///
794812
/// ```

0 commit comments

Comments
 (0)