From b18c7d85a92011bcc094b33e6a3c646a3cfca8f3 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 22 Jul 2024 17:34:29 +0100 Subject: [PATCH 01/23] Docs for Waker and LocalWaker: Add cross-refs in comment --- library/core/src/task/wake.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 86a965f68e085..4582bf9f42245 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -531,6 +531,10 @@ impl Waker { /// Returns a reference to a `Waker` that does nothing when used. /// + // Note! Much of the documentation for this method is duplicated + // in the docs for `LocalWaker::noop`. + // If you edit it, consider editing the other copy too. + // /// This is mostly useful for writing tests that need a [`Context`] to poll /// some futures, but are not expecting those futures to wake the waker or /// do not need to do anything specific if it happens. @@ -784,6 +788,10 @@ impl LocalWaker { /// Creates a new `LocalWaker` that does nothing when `wake` is called. /// + // Note! Much of the documentation for this method is duplicated + // in the docs for `Waker::noop`. + // If you edit it, consider editing the other copy too. + // /// This is mostly useful for writing tests that need a [`Context`] to poll /// some futures, but are not expecting those futures to wake the waker or /// do not need to do anything specific if it happens. From c404406a87412d50604893d8c347744195ce2dea Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 22 Jul 2024 17:35:11 +0100 Subject: [PATCH 02/23] LocalWaker docs: Make long-ago omitted but probably intended changes In 6f8a944ba4311cbcf5922132721095c226c6fbab, titled Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`. the summary line for Waker was changed: - /// Creates a new `Waker` that does nothing when `wake` is called. + /// Returns a reference to a `Waker` that does nothing when used. and the sentence about clone was added. LocalWaker's docs were not changed, even though the types were, but there is no explanation for why not. It seems like it was simply a slip induced by the clone-and-hack. --- library/core/src/task/wake.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 4582bf9f42245..baa8a956f8af1 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -786,7 +786,7 @@ impl LocalWaker { Self { waker } } - /// Creates a new `LocalWaker` that does nothing when `wake` is called. + /// Returns a reference to a `LocalWaker` that does nothing when used. /// // Note! Much of the documentation for this method is duplicated // in the docs for `Waker::noop`. @@ -796,6 +796,8 @@ impl LocalWaker { /// some futures, but are not expecting those futures to wake the waker or /// do not need to do anything specific if it happens. /// + /// If an owned `LocalWaker` is needed, `clone()` this one. + /// /// # Examples /// /// ``` From 0a777090d80747fc841784c5a6944f2a792f845c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:26:17 +1000 Subject: [PATCH 03/23] Avoid matching on `PatKind::Wild` in `write_struct_like` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 10b7968a1a7e3..22b7ca18f840a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -847,7 +847,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let subpatterns = pat .iter_fields() .enumerate() - .map(|(i, pat)| FieldPat { field: FieldIdx::new(i), pattern: hoist(pat) }) + .map(|(i, pat)| FieldPat { + field: FieldIdx::new(i), + pattern: hoist(pat), + is_wildcard: would_print_as_wildcard(cx.tcx, pat), + }) .collect::>(); PatKind::StructLike { enum_info, subpatterns } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 7d6387146054e..94f625e015326 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -21,6 +21,7 @@ use rustc_target::abi::{FieldIdx, VariantIdx}; pub(crate) struct FieldPat<'tcx> { pub(crate) field: FieldIdx, pub(crate) pattern: Box>, + pub(crate) is_wildcard: bool, } #[derive(Clone, Debug)] @@ -139,12 +140,12 @@ fn write_struct_like<'tcx>( write!(f, " {{ ")?; let mut printed = 0; - for p in subpatterns { - if let PatKind::Wild = p.pattern.kind { + for &FieldPat { field, ref pattern, is_wildcard } in subpatterns { + if is_wildcard { continue; } - let name = variant.fields[p.field].name; - write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?; + let field_name = variant.fields[field].name; + write!(f, "{}{field_name}: {pattern}", start_or_comma())?; printed += 1; } From f53eb2724de4e1a7ec0985d035c208c55c37dd78 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:30:25 +1000 Subject: [PATCH 04/23] Add `print::PatKind::Print` This will allow for the gradual removal of all other variants. --- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 94f625e015326..c929b9b808ab9 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -62,6 +62,8 @@ pub(crate) enum PatKind<'tcx> { }, Never, + + Print(String), } impl<'tcx> fmt::Display for Pat<'tcx> { @@ -79,6 +81,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) } + PatKind::Print(ref string) => write!(f, "{string}"), } } } From 92eb159d04f8fd6009899d978c504ee8522baccb Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:45:12 +1000 Subject: [PATCH 05/23] Remove `PatKind::Wild` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 ++++-- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 22b7ca18f840a..6cf3680b3e8dd 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -780,7 +780,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { use MaybeInfiniteInt::*; let cx = self; let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { - PatKind::Wild + PatKind::Print("_".to_string()) } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); @@ -890,7 +890,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } &Str(value) => PatKind::Constant { value }, Never if self.tcx.features().never_patterns => PatKind::Never, - Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild, + Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { + PatKind::Print("_".to_string()) + } Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index c929b9b808ab9..d8e282ae326a9 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,8 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Wild, - StructLike { enum_info: EnumInfo<'tcx>, subpatterns: Vec>, @@ -69,7 +67,6 @@ pub(crate) enum PatKind<'tcx> { impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { - PatKind::Wild => write!(f, "_"), PatKind::Never => write!(f, "!"), PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), PatKind::StructLike { ref enum_info, ref subpatterns } => { From ed3e38f33697efd2272b2df6a31b450e1e6ee12b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:47:21 +1000 Subject: [PATCH 06/23] Remove `PatKind::StructLike` --- compiler/rustc_pattern_analysis/src/rustc.rs | 11 ++++++++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 10 +--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 6cf3680b3e8dd..1d687cc1065dc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -854,7 +854,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { }) .collect::>(); - PatKind::StructLike { enum_info, subpatterns } + let mut s = String::new(); + print::write_struct_like( + &mut s, + self.tcx, + pat.ty().inner(), + &enum_info, + &subpatterns, + ) + .unwrap(); + PatKind::Print(s) } Ref => PatKind::Deref { subpattern: hoist(&pat.fields[0]) }, Slice(slice) => { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index d8e282ae326a9..dd37cd80ad262 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,11 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - StructLike { - enum_info: EnumInfo<'tcx>, - subpatterns: Vec>, - }, - Box { subpattern: Box>, }, @@ -69,9 +64,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { match self.kind { PatKind::Never => write!(f, "!"), PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), - PatKind::StructLike { ref enum_info, ref subpatterns } => { - ty::tls::with(|tcx| write_struct_like(f, tcx, self.ty, enum_info, subpatterns)) - } PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), @@ -104,7 +96,7 @@ pub(crate) enum EnumInfo<'tcx> { NotEnum, } -fn write_struct_like<'tcx>( +pub(crate) fn write_struct_like<'tcx>( f: &mut impl fmt::Write, tcx: TyCtxt<'_>, ty: Ty<'tcx>, From 15cc0e1b5cb9cc84ce017b656a75d9954f394f03 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:48:52 +1000 Subject: [PATCH 07/23] Remove `PatKind::Box` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 1d687cc1065dc..91650c7531a91 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -832,7 +832,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern // of type `Box` is to use a `box` pattern via #[feature(box_patterns)]. - PatKind::Box { subpattern: hoist(&pat.fields[0]) } + PatKind::Print(format!("box {}", hoist(&pat.fields[0]))) } Struct | Variant(_) | UnionField => { let enum_info = match *pat.ty().kind() { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index dd37cd80ad262..d03c68442cd5e 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,10 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Box { - subpattern: Box>, - }, - Deref { subpattern: Box>, }, @@ -63,7 +59,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), From 283243ac5a3bcf68627491ea64b0d725db8c62f3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:51:32 +1000 Subject: [PATCH 08/23] Remove `PatKind::Ref` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 8 ++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 91650c7531a91..97d4a94756dae 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -865,7 +865,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { .unwrap(); PatKind::Print(s) } - Ref => PatKind::Deref { subpattern: hoist(&pat.fields[0]) }, + Ref => { + let mut s = String::new(); + print::write_ref_like(&mut s, pat.ty().inner(), &hoist(&pat.fields[0])).unwrap(); + PatKind::Print(s) + } Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { SliceKind::FixedLen(len) => (len, false), diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index d03c68442cd5e..f147d62ed9bbc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -26,16 +26,13 @@ pub(crate) struct FieldPat<'tcx> { #[derive(Clone, Debug)] pub(crate) struct Pat<'tcx> { + #[allow(dead_code)] pub(crate) ty: Ty<'tcx>, pub(crate) kind: PatKind<'tcx>, } #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Deref { - subpattern: Box>, - }, - Constant { value: mir::Const<'tcx>, }, @@ -59,7 +56,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { @@ -172,7 +168,7 @@ pub(crate) fn write_struct_like<'tcx>( Ok(()) } -fn write_ref_like<'tcx>( +pub(crate) fn write_ref_like<'tcx>( f: &mut impl fmt::Write, ty: Ty<'tcx>, subpattern: &Pat<'tcx>, From 9952e4d4c8ba5def2861e1a39af61506f0a91655 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:55:50 +1000 Subject: [PATCH 09/23] Remove `PatKind::Constant` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++--- compiler/rustc_pattern_analysis/src/rustc/print.rs | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 97d4a94756dae..9bd17b822af35 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -784,7 +784,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); - PatKind::Constant { value } + PatKind::Print(value.to_string()) } else { // We convert to an inclusive range for diagnostics. let mut end = rustc_hir::RangeEnd::Included; @@ -827,7 +827,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let cx = self; let hoist = |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) }, + Bool(b) => PatKind::Print(b.to_string()), + Str(s) => PatKind::Print(s.to_string()), IntRange(range) => return self.hoist_pat_range(range, *pat.ty()), Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern @@ -901,7 +902,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Slice { prefix, has_dot_dot, suffix } } - &Str(value) => PatKind::Constant { value }, Never if self.tcx.features().never_patterns => PatKind::Never, Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { PatKind::Print("_".to_string()) diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index f147d62ed9bbc..9e24ef58e8bc0 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -11,9 +11,9 @@ use std::fmt; +use rustc_middle::bug; use rustc_middle::thir::PatRange; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; -use rustc_middle::{bug, mir}; use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -33,10 +33,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Constant { - value: mir::Const<'tcx>, - }, - Range(Box>), Slice { @@ -56,7 +52,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) From 2b6f4386ebdedd62a093577dafe5082e4f63b316 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:59:02 +1000 Subject: [PATCH 10/23] Remove `PatKind::Range` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 9bd17b822af35..d7c14348b1b7b 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -807,7 +807,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { range.hi }; let hi = cx.hoist_pat_range_bdy(hi, ty); - PatKind::Range(Box::new(PatRange { lo, hi, end, ty: ty.inner() })) + PatKind::Print(PatRange { lo, hi, end, ty: ty.inner() }.to_string()) }; Pat { ty: ty.inner(), kind } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 9e24ef58e8bc0..fab71b421f8b6 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -12,7 +12,6 @@ use std::fmt; use rustc_middle::bug; -use rustc_middle::thir::PatRange; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -33,8 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Range(Box>), - Slice { prefix: Box<[Box>]>, /// True if this slice-like pattern should include a `..` between the @@ -52,7 +49,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) } From ec1483bf2e317b4a8d073881c3e942f7a011ff1a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:02:00 +1000 Subject: [PATCH 11/23] Remove `PatKind::Slice` --- compiler/rustc_pattern_analysis/src/rustc.rs | 8 +++++--- .../rustc_pattern_analysis/src/rustc/print.rs | 17 +++-------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d7c14348b1b7b..653097314f7fa 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -897,10 +897,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - let prefix = prefix.iter().map(hoist).collect(); - let suffix = suffix.iter().map(hoist).collect(); + let prefix = prefix.iter().map(hoist).collect::>(); + let suffix = suffix.iter().map(hoist).collect::>(); - PatKind::Slice { prefix, has_dot_dot, suffix } + let mut s = String::new(); + print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); + PatKind::Print(s) } Never if self.tcx.features().never_patterns => PatKind::Never, Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index fab71b421f8b6..adda21a8b2582 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -27,19 +27,11 @@ pub(crate) struct FieldPat<'tcx> { pub(crate) struct Pat<'tcx> { #[allow(dead_code)] pub(crate) ty: Ty<'tcx>, - pub(crate) kind: PatKind<'tcx>, + pub(crate) kind: PatKind, } #[derive(Clone, Debug)] -pub(crate) enum PatKind<'tcx> { - Slice { - prefix: Box<[Box>]>, - /// True if this slice-like pattern should include a `..` between the - /// prefix and suffix. - has_dot_dot: bool, - suffix: Box<[Box>]>, - }, - +pub(crate) enum PatKind { Never, Print(String), @@ -49,9 +41,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { - write_slice_like(f, prefix, has_dot_dot, suffix) - } PatKind::Print(ref string) => write!(f, "{string}"), } } @@ -173,7 +162,7 @@ pub(crate) fn write_ref_like<'tcx>( write!(f, "{subpattern}") } -fn write_slice_like<'tcx>( +pub(crate) fn write_slice_like<'tcx>( f: &mut impl fmt::Write, prefix: &[Box>], has_dot_dot: bool, From bfe88a3bd0d0af92405655495a40aefbbed29b23 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:04:51 +1000 Subject: [PATCH 12/23] Remove `PatKind::Never` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 653097314f7fa..35391ebec822a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -904,7 +904,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); PatKind::Print(s) } - Never if self.tcx.features().never_patterns => PatKind::Never, + Never if self.tcx.features().never_patterns => PatKind::Print("!".to_string()), Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { PatKind::Print("_".to_string()) } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index adda21a8b2582..b2ecfa2ae28c2 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,15 +32,12 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind { - Never, - Print(String), } impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { - PatKind::Never => write!(f, "!"), PatKind::Print(ref string) => write!(f, "{string}"), } } From fc55129774c8209d46d89b8a27b13fb7d8ce2b44 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:20:22 +1000 Subject: [PATCH 13/23] Remove `print::Pat` entirely, replacing it with `String` --- compiler/rustc_pattern_analysis/src/rustc.rs | 70 ++++++++----------- .../rustc_pattern_analysis/src/rustc/print.rs | 34 ++------- 2 files changed, 35 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 35391ebec822a..4ad6da5535071 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -774,17 +774,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - /// Convert to a [`print::Pat`] for diagnostic purposes. - fn hoist_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> print::Pat<'tcx> { - use print::{Pat, PatKind}; + /// Prints an [`IntRange`] to a string for diagnostic purposes. + fn print_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> String { use MaybeInfiniteInt::*; let cx = self; - let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { - PatKind::Print("_".to_string()) + if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { + "_".to_string() } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); - PatKind::Print(value.to_string()) + value.to_string() } else { // We convert to an inclusive range for diagnostics. let mut end = rustc_hir::RangeEnd::Included; @@ -807,33 +806,24 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { range.hi }; let hi = cx.hoist_pat_range_bdy(hi, ty); - PatKind::Print(PatRange { lo, hi, end, ty: ty.inner() }.to_string()) - }; - - Pat { ty: ty.inner(), kind } + PatRange { lo, hi, end, ty: ty.inner() }.to_string() + } } /// Prints a [`WitnessPat`] to an owned string, for diagnostic purposes. + /// + /// This panics for patterns that don't appear in diagnostics, like float ranges. pub fn print_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> String { - // This works by converting the witness pattern to a `print::Pat` - // and then printing that, but callers don't need to know that. - self.hoist_witness_pat(pat).to_string() - } - - /// Convert to a [`print::Pat`] for diagnostic purposes. This panics for patterns that don't - /// appear in diagnostics, like float ranges. - fn hoist_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> print::Pat<'tcx> { - use print::{FieldPat, Pat, PatKind}; let cx = self; - let hoist = |p| Box::new(cx.hoist_witness_pat(p)); - let kind = match pat.ctor() { - Bool(b) => PatKind::Print(b.to_string()), - Str(s) => PatKind::Print(s.to_string()), - IntRange(range) => return self.hoist_pat_range(range, *pat.ty()), + let print = |p| cx.print_witness_pat(p); + match pat.ctor() { + Bool(b) => b.to_string(), + Str(s) => s.to_string(), + IntRange(range) => return self.print_pat_range(range, *pat.ty()), Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern // of type `Box` is to use a `box` pattern via #[feature(box_patterns)]. - PatKind::Print(format!("box {}", hoist(&pat.fields[0]))) + format!("box {}", print(&pat.fields[0])) } Struct | Variant(_) | UnionField => { let enum_info = match *pat.ty().kind() { @@ -848,9 +838,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let subpatterns = pat .iter_fields() .enumerate() - .map(|(i, pat)| FieldPat { + .map(|(i, pat)| print::FieldPat { field: FieldIdx::new(i), - pattern: hoist(pat), + pattern: print(pat), is_wildcard: would_print_as_wildcard(cx.tcx, pat), }) .collect::>(); @@ -864,12 +854,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { &subpatterns, ) .unwrap(); - PatKind::Print(s) + s } Ref => { let mut s = String::new(); - print::write_ref_like(&mut s, pat.ty().inner(), &hoist(&pat.fields[0])).unwrap(); - PatKind::Print(s) + print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap(); + s } Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { @@ -897,17 +887,15 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - let prefix = prefix.iter().map(hoist).collect::>(); - let suffix = suffix.iter().map(hoist).collect::>(); + let prefix = prefix.iter().map(print).collect::>(); + let suffix = suffix.iter().map(print).collect::>(); let mut s = String::new(); print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); - PatKind::Print(s) - } - Never if self.tcx.features().never_patterns => PatKind::Print("!".to_string()), - Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { - PatKind::Print("_".to_string()) + s } + Never if self.tcx.features().never_patterns => "!".to_string(), + Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => "_".to_string(), Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" @@ -915,9 +903,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Opaque(..) | Or => { bug!("can't convert to pattern: {:?}", pat) } - }; - - Pat { ty: pat.ty().inner(), kind } + } } } @@ -993,7 +979,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { overlaps_on: IntRange, overlaps_with: &[&crate::pat::DeconstructedPat], ) { - let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty()); + let overlap_as_pat = self.print_pat_range(&overlaps_on, *pat.ty()); let overlaps: Vec<_> = overlaps_with .iter() .map(|pat| pat.data().span) @@ -1033,7 +1019,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { suggested_range.end = rustc_hir::RangeEnd::Included; suggested_range.to_string() }; - let gap_as_pat = self.hoist_pat_range(&gap, *pat.ty()); + let gap_as_pat = self.print_pat_range(&gap, *pat.ty()); if gapped_with.is_empty() { // If `gapped_with` is empty, `gap == T::MAX`. self.tcx.emit_node_span_lint( diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index b2ecfa2ae28c2..17e389df17ed2 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -17,32 +17,12 @@ use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; #[derive(Clone, Debug)] -pub(crate) struct FieldPat<'tcx> { +pub(crate) struct FieldPat { pub(crate) field: FieldIdx, - pub(crate) pattern: Box>, + pub(crate) pattern: String, pub(crate) is_wildcard: bool, } -#[derive(Clone, Debug)] -pub(crate) struct Pat<'tcx> { - #[allow(dead_code)] - pub(crate) ty: Ty<'tcx>, - pub(crate) kind: PatKind, -} - -#[derive(Clone, Debug)] -pub(crate) enum PatKind { - Print(String), -} - -impl<'tcx> fmt::Display for Pat<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - PatKind::Print(ref string) => write!(f, "{string}"), - } - } -} - /// Returns a closure that will return `""` when called the first time, /// and then return `", "` when called any subsequent times. /// Useful for printing comma-separated lists. @@ -69,7 +49,7 @@ pub(crate) fn write_struct_like<'tcx>( tcx: TyCtxt<'_>, ty: Ty<'tcx>, enum_info: &EnumInfo<'tcx>, - subpatterns: &[FieldPat<'tcx>], + subpatterns: &[FieldPat], ) -> fmt::Result { let variant_and_name = match *enum_info { EnumInfo::Enum { adt_def, variant_index } => { @@ -148,7 +128,7 @@ pub(crate) fn write_struct_like<'tcx>( pub(crate) fn write_ref_like<'tcx>( f: &mut impl fmt::Write, ty: Ty<'tcx>, - subpattern: &Pat<'tcx>, + subpattern: &str, ) -> fmt::Result { match ty.kind() { ty::Ref(_, _, mutbl) => { @@ -159,11 +139,11 @@ pub(crate) fn write_ref_like<'tcx>( write!(f, "{subpattern}") } -pub(crate) fn write_slice_like<'tcx>( +pub(crate) fn write_slice_like( f: &mut impl fmt::Write, - prefix: &[Box>], + prefix: &[String], has_dot_dot: bool, - suffix: &[Box>], + suffix: &[String], ) -> fmt::Result { let mut start_or_comma = start_or_comma(); write!(f, "[")?; From c4aa7a71a9cf16a242530fc1c3aedffb8567cba3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 13 Aug 2024 12:55:58 +1000 Subject: [PATCH 14/23] Port `run-make/libtest-json` to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/libtest-json/Makefile | 20 ------------ .../run-make/libtest-json/output-default.json | 2 +- .../libtest-json/output-stdout-success.json | 2 +- tests/run-make/libtest-json/rmake.rs | 31 +++++++++++++++++++ 5 files changed, 33 insertions(+), 23 deletions(-) delete mode 100644 tests/run-make/libtest-json/Makefile create mode 100644 tests/run-make/libtest-json/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 14f0a9cd23d21..96ab097b3885e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -9,7 +9,6 @@ run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile -run-make/libtest-json/Makefile run-make/libtest-junit/Makefile run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile diff --git a/tests/run-make/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile deleted file mode 100644 index c8bc7b5dd4a4c..0000000000000 --- a/tests/run-make/libtest-json/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# ignore-cross-compile -# needs-unwind -include ../tools.mk - -# Test expected libtest's JSON output - -OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-json-output-default.json -OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-json-output-stdout-success.json - -all: f.rs validate_json.py output-default.json output-stdout-success.json - $(RUSTC) --test f.rs - RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE_DEFAULT) || true - RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true - - cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_json.py - cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_json.py - - # Normalize the actual output and compare to expected output file - cat $(OUTPUT_FILE_DEFAULT) | sed 's/"exec_time": [0-9.]*/"exec_time": $$TIME/' | diff output-default.json - - cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/"exec_time": [0-9.]*/"exec_time": $$TIME/' | diff output-stdout-success.json - diff --git a/tests/run-make/libtest-json/output-default.json b/tests/run-make/libtest-json/output-default.json index 01710f59e5d74..a2293a032d012 100644 --- a/tests/run-make/libtest-json/output-default.json +++ b/tests/run-make/libtest-json/output-default.json @@ -7,4 +7,4 @@ { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } { "type": "test", "name": "d", "event": "ignored", "message": "msg" } -{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME } +{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": "$EXEC_TIME" } diff --git a/tests/run-make/libtest-json/output-stdout-success.json b/tests/run-make/libtest-json/output-stdout-success.json index 878eb6c7c260d..cf92f01f63aca 100644 --- a/tests/run-make/libtest-json/output-stdout-success.json +++ b/tests/run-make/libtest-json/output-stdout-success.json @@ -7,4 +7,4 @@ { "type": "test", "name": "c", "event": "ok", "stdout": "thread 'c' panicked at f.rs:15:5:\nassertion failed: false\n" } { "type": "test", "event": "started", "name": "d" } { "type": "test", "name": "d", "event": "ignored", "message": "msg" } -{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME } +{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": "$EXEC_TIME" } diff --git a/tests/run-make/libtest-json/rmake.rs b/tests/run-make/libtest-json/rmake.rs new file mode 100644 index 0000000000000..acbd88dc46cb9 --- /dev/null +++ b/tests/run-make/libtest-json/rmake.rs @@ -0,0 +1,31 @@ +// Check libtest's JSON output against snapshots. + +//@ ignore-cross-compile +//@ needs-unwind (test file contains #[should_panic] test) + +use run_make_support::{cmd, diff, python_command, rustc}; + +fn main() { + rustc().arg("--test").input("f.rs").run(); + + run_tests(&[], "output-default.json"); + run_tests(&["--show-output"], "output-stdout-success.json"); +} + +#[track_caller] +fn run_tests(extra_args: &[&str], expected_file: &str) { + let cmd_out = cmd("./f") + .env("RUST_BACKTRACE", "0") + .args(&["-Zunstable-options", "--test-threads=1", "--format=json"]) + .args(extra_args) + .run_fail(); + let test_stdout = &cmd_out.stdout_utf8(); + + python_command().arg("validate_json.py").stdin(test_stdout).run(); + + diff() + .expected_file(expected_file) + .actual_text("stdout", test_stdout) + .normalize(r#"(?"exec_time": )[0-9.]+"#, r#"${prefix}"$$EXEC_TIME""#) + .run(); +} From fc733a668afe9a16a23a6d249c6d253a08f36ebf Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 13 Aug 2024 13:02:26 +1000 Subject: [PATCH 15/23] Port `run-make/libtest-junit` to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/libtest-junit/Makefile | 20 ------------ tests/run-make/libtest-junit/rmake.rs | 31 +++++++++++++++++++ 3 files changed, 31 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/libtest-junit/Makefile create mode 100644 tests/run-make/libtest-junit/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 96ab097b3885e..e9dcc70dff538 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -9,7 +9,6 @@ run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile -run-make/libtest-junit/Makefile run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile run-make/min-global-align/Makefile diff --git a/tests/run-make/libtest-junit/Makefile b/tests/run-make/libtest-junit/Makefile deleted file mode 100644 index 26e56242dd239..0000000000000 --- a/tests/run-make/libtest-junit/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# ignore-cross-compile -# needs-unwind contains should_panic test -include ../tools.mk - -# Test expected libtest's junit output - -OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-junit-output-default.xml -OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-junit-output-stdout-success.xml - -all: f.rs validate_junit.py output-default.xml output-stdout-success.xml - $(RUSTC) --test f.rs - RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit > $(OUTPUT_FILE_DEFAULT) || true - RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true - - cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_junit.py - cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_junit.py - - # Normalize the actual output and compare to expected output file - cat $(OUTPUT_FILE_DEFAULT) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-default.xml - - cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-stdout-success.xml - diff --git a/tests/run-make/libtest-junit/rmake.rs b/tests/run-make/libtest-junit/rmake.rs new file mode 100644 index 0000000000000..d631313ed9210 --- /dev/null +++ b/tests/run-make/libtest-junit/rmake.rs @@ -0,0 +1,31 @@ +// Check libtest's JUnit (XML) output against snapshots. + +//@ ignore-cross-compile +//@ needs-unwind (test file contains #[should_panic] test) + +use run_make_support::{cmd, diff, python_command, rustc}; + +fn main() { + rustc().arg("--test").input("f.rs").run(); + + run_tests(&[], "output-default.xml"); + run_tests(&["--show-output"], "output-stdout-success.xml"); +} + +#[track_caller] +fn run_tests(extra_args: &[&str], expected_file: &str) { + let cmd_out = cmd("./f") + .env("RUST_BACKTRACE", "0") + .args(&["-Zunstable-options", "--test-threads=1", "--format=junit"]) + .args(extra_args) + .run_fail(); + let test_stdout = &cmd_out.stdout_utf8(); + + python_command().arg("validate_junit.py").stdin(test_stdout).run(); + + diff() + .expected_file(expected_file) + .actual_text("stdout", test_stdout) + .normalize(r#"\btime="[0-9.]+""#, r#"time="$$TIME""#) + .run(); +} From 3a02047d5212fa06f1dca8182d7cf9fb1d379ceb Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 14 Aug 2024 09:36:53 +0200 Subject: [PATCH 16/23] if we have an `ocx`, use it --- .../src/traits/query/type_op/mod.rs | 38 ++----------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 2f64ed963f967..c5586d7d116d4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -170,44 +170,12 @@ where // collecting region constraints via `region_constraints`. let (mut output, _) = scrape_region_constraints( infcx, - |_ocx| { - let (output, ei, mut obligations, _) = + |ocx| { + let (output, ei, obligations, _) = Q::fully_perform_into(self, infcx, &mut region_constraints, span)?; error_info = ei; - // Typically, instantiating NLL query results does not - // create obligations. However, in some cases there - // are unresolved type variables, and unify them *can* - // create obligations. In that case, we have to go - // fulfill them. We do this via a (recursive) query. - while !obligations.is_empty() { - trace!("{:#?}", obligations); - let mut progress = false; - for obligation in std::mem::take(&mut obligations) { - let obligation = infcx.resolve_vars_if_possible(obligation); - match ProvePredicate::fully_perform_into( - obligation.param_env.and(ProvePredicate::new(obligation.predicate)), - infcx, - &mut region_constraints, - span, - ) { - Ok(((), _, new, certainty)) => { - obligations.extend(new); - progress = true; - if let Certainty::Ambiguous = certainty { - obligations.push(obligation); - } - } - Err(_) => obligations.push(obligation), - } - } - if !progress { - infcx.dcx().span_bug( - span, - format!("ambiguity processing {obligations:?} from {self:?}"), - ); - } - } + ocx.register_obligations(obligations); Ok(output) }, "fully_perform", From bb84372e436dfeba61ad1b4deef408a3cf9a12c5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 10 Aug 2024 14:49:26 +0200 Subject: [PATCH 17/23] rust-analyzer: use in-tree pattern_analysis crate --- src/tools/rust-analyzer/crates/hir-ty/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 4c9e0a1e11836..21c84511dc35e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -15,8 +15,10 @@ extern crate rustc_abi; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; -// Use the crates.io version unconditionally until the API settles enough that we can switch to -// using the in-tree one. +#[cfg(feature = "in-rust-tree")] +extern crate rustc_pattern_analysis; + +#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; mod builder; From 99aad72af55e9cfd77adeeca0f9b403758201d42 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 15 Aug 2024 09:46:21 +1000 Subject: [PATCH 18/23] Add a comment explaining the return type of `Ty::kind`. --- compiler/rustc_middle/src/ty/sty.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0a277fea49c12..d60bfb9faa1aa 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -970,6 +970,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { /// Type utilities impl<'tcx> Ty<'tcx> { + // It would be nicer if this returned the value instead of a reference, + // like how `Predicate::kind` and `Region::kind` do. (It would result in + // many fewer subsequent dereferences.) But that gives a small but + // noticeable performance hit. See #126069 for details. #[inline(always)] pub fn kind(self) -> &'tcx TyKind<'tcx> { self.0.0 From 8b990e35f423907d22cb7f386d40acc1599377ad Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 14 Aug 2024 14:41:10 +1000 Subject: [PATCH 19/23] Port the `sysroot-crates-are-unstable` Python script to rmake --- .../sysroot-crates-are-unstable/rmake.rs | 101 +++++++++++++++++- .../sysroot-crates-are-unstable/test.py | 75 ------------- 2 files changed, 99 insertions(+), 77 deletions(-) delete mode 100644 tests/run-make/sysroot-crates-are-unstable/test.py diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs index 24da387eb8016..2240d87237b1a 100644 --- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs +++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs @@ -1,5 +1,102 @@ -use run_make_support::python_command; +// Check that crates in the sysroot are treated as unstable, unless they are +// on a list of known-stable sysroot crates. + +use std::path::{Path, PathBuf}; +use std::str; + +use run_make_support::{rfs, rustc, target}; + +fn is_stable_crate(name: &str) -> bool { + matches!(name, "std" | "alloc" | "core" | "proc_macro") +} fn main() { - python_command().arg("test.py").run(); + for cr in get_unstable_sysroot_crates() { + check_crate_is_unstable(&cr); + } + println!("Done"); +} + +#[derive(Debug)] +struct Crate { + name: String, + path: PathBuf, +} + +fn check_crate_is_unstable(cr: &Crate) { + let Crate { name, path } = cr; + + print!("- Verifying that sysroot crate '{name}' is an unstable crate ..."); + + // Trying to use this crate from a user program should fail. + let output = rustc() + .crate_type("rlib") + .target(target()) + .extern_(name, path) + .input("-") + .stdin(format!("extern crate {name};")) + .run_fail(); + + // Make sure it failed for the intended reason, not some other reason. + // (The actual feature required varies between crates.) + output.assert_stderr_contains("use of unstable library feature"); + + println!(" OK"); +} + +fn get_unstable_sysroot_crates() -> Vec { + let sysroot = PathBuf::from(rustc().print("sysroot").run().stdout_utf8().trim()); + let sysroot_libs_dir = sysroot.join("lib").join("rustlib").join(target()).join("lib"); + println!("Sysroot libs dir: {sysroot_libs_dir:?}"); + + // Generate a list of all library crates in the sysroot. + let sysroot_crates = get_all_crates_in_dir(&sysroot_libs_dir); + println!( + "Found {} sysroot crates: {:?}", + sysroot_crates.len(), + sysroot_crates.iter().map(|cr| &cr.name).collect::>() + ); + + // Self-check: If we didn't find `core`, we probably checked the wrong directory. + assert!( + sysroot_crates.iter().any(|cr| cr.name == "core"), + "Couldn't find `core` in {sysroot_libs_dir:?}" + ); + + let unstable_sysroot_crates = + sysroot_crates.into_iter().filter(|cr| !is_stable_crate(&cr.name)).collect::>(); + // Self-check: There should be at least one unstable crate in the directory. + assert!( + !unstable_sysroot_crates.is_empty(), + "Couldn't find any unstable crates in {sysroot_libs_dir:?}" + ); + unstable_sysroot_crates +} + +fn get_all_crates_in_dir(libs_dir: &Path) -> Vec { + let mut libs = vec![]; + rfs::read_dir_entries(libs_dir, |path| { + if !path.is_file() { + return; + } + if let Some(name) = crate_name_from_path(path) { + libs.push(Crate { name, path: path.to_owned() }); + } + }); + libs.sort_by(|a, b| a.name.cmp(&b.name)); + libs +} + +/// Treat a file as a crate if its name begins with `lib` and ends with `.rlib`. +/// The crate name is the part before the first hyphen (if any). +fn crate_name_from_path(path: &Path) -> Option { + let name = path + .file_name()? + .to_str()? + .strip_prefix("lib")? + .strip_suffix(".rlib")? + .split('-') + .next() + .expect("split always yields at least one string"); + Some(name.to_owned()) } diff --git a/tests/run-make/sysroot-crates-are-unstable/test.py b/tests/run-make/sysroot-crates-are-unstable/test.py deleted file mode 100644 index 45cfdd195b4e2..0000000000000 --- a/tests/run-make/sysroot-crates-are-unstable/test.py +++ /dev/null @@ -1,75 +0,0 @@ -import sys -import os -from os import listdir -from os.path import isfile, join -from subprocess import PIPE, Popen - - -# This is n list of files which are stable crates or simply are not crates, -# we don't check for the instability of these crates as they're all stable! -STABLE_CRATES = ['std', 'alloc', 'core', 'proc_macro', - 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt'] - - -def convert_to_string(s): - if s.__class__.__name__ == 'bytes': - return s.decode('utf-8') - return s - - -def set_ld_lib_path(): - var = os.environ.get("LD_LIB_PATH_ENVVAR") - rpath = os.environ.get("HOST_RPATH_DIR") - if var and rpath: - path = os.environ.get(var) - if path: - os.environ[var] = rpath + os.pathsep + path - else: - os.environ[var] = rpath - - -def exec_command(command, to_input=None): - child = None - if to_input is None: - child = Popen(command, stdout=PIPE, stderr=PIPE) - else: - child = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE) - stdout, stderr = child.communicate(input=to_input) - return (convert_to_string(stdout), convert_to_string(stderr)) - - -def check_lib(lib): - if lib['name'] in STABLE_CRATES: - return True - print('verifying if {} is an unstable crate'.format(lib['name'])) - stdout, stderr = exec_command([os.environ['RUSTC'], '-', '--crate-type', 'rlib', - '--target', os.environ['TARGET'], - '--extern', '{}={}'.format(lib['name'], lib['path'])], - to_input=('extern crate {};'.format(lib['name'])).encode('utf-8')) - if 'use of unstable library feature' not in '{}{}'.format(stdout, stderr): - print('crate {} "{}" is not unstable'.format(lib['name'], lib['path'])) - print('{}{}'.format(stdout, stderr)) - print('') - return False - return True - -# Generate a list of all crates in the sysroot. To do this we list all files in -# rustc's sysroot, look at the filename, strip everything after the `-`, and -# strip the leading `lib` (if present) -def get_all_libs(dir_path): - return [{ 'path': join(dir_path, f), 'name': f[3:].split('-')[0] } - for f in listdir(dir_path) - if isfile(join(dir_path, f)) and f.endswith('.rlib') and f not in STABLE_CRATES] - - -set_ld_lib_path() -sysroot = exec_command([os.environ['RUSTC'], '--print', 'sysroot'])[0].replace('\n', '') -assert sysroot, "Could not read the rustc sysroot!" -libs = get_all_libs(join(sysroot, 'lib/rustlib/{}/lib'.format(os.environ['TARGET']))) - -ret = 0 -for lib in libs: - if not check_lib(lib): - # We continue so users can see all the not unstable crates. - ret = 1 -sys.exit(ret) From 2e4d5bbba7b4efe27b8afca47fef98a2254e684b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Mon, 12 Aug 2024 13:26:25 -0400 Subject: [PATCH 20/23] rewrite rlib-format-packed-bundled-libs to rmake --- .../src/external_deps/llvm.rs | 6 ++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../rlib-format-packed-bundled-libs/Makefile | 39 --------- .../rlib-format-packed-bundled-libs/rmake.rs | 81 +++++++++++++++++++ 4 files changed, 87 insertions(+), 40 deletions(-) delete mode 100644 tests/run-make/rlib-format-packed-bundled-libs/Makefile create mode 100644 tests/run-make/rlib-format-packed-bundled-libs/rmake.rs diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index 7af79443affd6..021858dea7a27 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -291,6 +291,12 @@ impl LlvmAr { self } + /// Print the table of contents. + pub fn table_of_contents(&mut self) -> &mut Self { + self.cmd.arg("t"); + self + } + /// Provide an output, then an input file. Bundled in one function, as llvm-ar has /// no "--output"-style flag. pub fn output_input(&mut self, out: impl AsRef, input: impl AsRef) -> &mut Self { diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index bc4465557738e..34008623a4c39 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -15,7 +15,6 @@ run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile run-make/native-link-modifier-bundle/Makefile run-make/reproducible-build/Makefile -run-make/rlib-format-packed-bundled-libs/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/tests/run-make/rlib-format-packed-bundled-libs/Makefile b/tests/run-make/rlib-format-packed-bundled-libs/Makefile deleted file mode 100644 index f454da67893d0..0000000000000 --- a/tests/run-make/rlib-format-packed-bundled-libs/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -include ../tools.mk - -# ignore-cross-compile - -# Make sure rlib format with -Zpacked_bundled_libs is correct. - -# We're using the llvm-nm instead of the system nm to ensure it is compatible -# with the LLVM bitcode generated by rustc. -# Except on Windows where piping/IO redirection under MSYS2 is wonky with llvm-nm. -ifndef IS_WINDOWS -NM = "$(LLVM_BIN_DIR)"/llvm-nm -else -NM = nm -endif - -all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) - $(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs - $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2" - $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3" - $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up" - $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2" - $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3" - $(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib - $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1" - $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local" - $(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1" - - # Make sure compiler doesn't use files, that it shouldn't know about. - rm $(TMPDIR)/*native_dep_* - - $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3" - -ifndef IS_MSVC - $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1" - $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2" - $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3" - $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local" - $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up" -endif diff --git a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs new file mode 100644 index 0000000000000..7cd0932ecf342 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs @@ -0,0 +1,81 @@ +// `-Z packed_bundled_libs` is an unstable rustc flag that makes the compiler +// only require a native library and no supplementary object files to compile. +// Output files compiled with this flag should still contain all expected symbols - +// that is what this test checks. +// See https://github.com/rust-lang/rust/pull/100101 + +// FIXME(Oneirical): MSVC and cross-compile + +use run_make_support::{ + bin_name, build_native_static_lib, cwd, filename_contains, llvm_ar, llvm_nm, rfs, + rust_lib_name, rustc, shallow_find_files, +}; + +fn main() { + build_native_static_lib("native_dep_1"); + build_native_static_lib("native_dep_2"); + build_native_static_lib("native_dep_3"); + rustc().input("rust_dep_up.rs").crate_type("rlib").arg("-Zpacked_bundled_libs").run(); + llvm_nm() + .input(rust_lib_name("rust_dep_up")) + .run() + .assert_stdout_contains_regex("U.*native_f2"); + llvm_nm() + .input(rust_lib_name("rust_dep_up")) + .run() + .assert_stdout_contains_regex("U.*native_f3"); + llvm_nm() + .input(rust_lib_name("rust_dep_up")) + .run() + .assert_stdout_contains_regex("T.*rust_dep_up"); + llvm_ar() + .table_of_contents() + .arg(rust_lib_name("rust_dep_up")) + .run() + .assert_stdout_contains("native_dep_2"); + llvm_ar() + .table_of_contents() + .arg(rust_lib_name("rust_dep_up")) + .run() + .assert_stdout_contains("native_dep_3"); + rustc() + .input("rust_dep_local.rs") + .extern_("rlib", rust_lib_name("rust_dep_up")) + .arg("-Zpacked_bundled_libs") + .crate_type("rlib") + .run(); + llvm_nm() + .input(rust_lib_name("rust_dep_local")) + .run() + .assert_stdout_contains_regex("U.*native_f1"); + llvm_nm() + .input(rust_lib_name("rust_dep_local")) + .run() + .assert_stdout_contains_regex("T.*rust_dep_local"); + llvm_ar() + .table_of_contents() + .arg(rust_lib_name("rust_dep_local")) + .run() + .assert_stdout_contains("native_dep_1"); + + // Ensure the compiler will not use files it should not know about. + for file in shallow_find_files(cwd(), |path| filename_contains(path, "native_dep_")) { + rfs::remove_file(file); + } + + rustc() + .input("main.rs") + .extern_("lib", rust_lib_name("rust_dep_local")) + .output(bin_name("main")) + .arg("-Zpacked_bundled_libs") + .print("link-args") + .run() + .assert_stdout_contains_regex("native_dep_1.*native_dep_2.*native_dep_3"); + + //FIXME(Oneirical): This part will apparently fail on MSVC + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f1"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f2"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f3"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_local"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_up"); +} From 51628fb6662128306b4f5aa852729fff6b7f8e00 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Mon, 12 Aug 2024 13:45:38 -0400 Subject: [PATCH 21/23] rewrite native-link-modifier-bundle to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../native-link-modifier-bundle/Makefile | 38 -------- .../native-link-modifier-bundle/rmake.rs | 90 +++++++++++++++++++ .../rlib-format-packed-bundled-libs/rmake.rs | 19 ++-- 4 files changed, 101 insertions(+), 47 deletions(-) delete mode 100644 tests/run-make/native-link-modifier-bundle/Makefile create mode 100644 tests/run-make/native-link-modifier-bundle/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 34008623a4c39..dd0dbe7cb4b02 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -13,7 +13,6 @@ run-make/libtest-json/Makefile run-make/libtest-junit/Makefile run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile -run-make/native-link-modifier-bundle/Makefile run-make/reproducible-build/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile diff --git a/tests/run-make/native-link-modifier-bundle/Makefile b/tests/run-make/native-link-modifier-bundle/Makefile deleted file mode 100644 index 527720922fe58..0000000000000 --- a/tests/run-make/native-link-modifier-bundle/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# ignore-cross-compile -# ignore-windows-msvc - -include ../tools.mk - -# We're using the llvm-nm instead of the system nm to ensure it is compatible -# with the LLVM bitcode generated by rustc. -# Except on Windows where piping/IO redirection under MSYS2 is wonky with llvm-nm. -ifndef IS_WINDOWS -NM = "$(LLVM_BIN_DIR)"/llvm-nm -else -NM = nm -endif - -all: $(call NATIVE_STATICLIB,native-staticlib) - # Build a staticlib and a rlib, the `native_func` symbol will be bundled into them - $(RUSTC) bundled.rs --crate-type=staticlib --crate-type=rlib - $(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "T _*native_func" - $(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "U _*native_func" - $(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "T _*native_func" - $(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "U _*native_func" - - # Build a staticlib and a rlib, the `native_func` symbol will not be bundled into it - $(RUSTC) non-bundled.rs --crate-type=staticlib --crate-type=rlib - $(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -ve "T _*native_func" - $(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -e "U _*native_func" - $(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -ve "T _*native_func" - $(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -e "U _*native_func" - - # Build a cdylib, `native-staticlib` will not appear on the linker line because it was bundled previously - # The cdylib will contain the `native_func` symbol in the end - $(RUSTC) cdylib-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -ve '-l[" ]*native-staticlib' - $(NM) $(call DYLIB,cdylib_bundled) | $(CGREP) -e "[Tt] _*native_func" - - # Build a cdylib, `native-staticlib` will appear on the linker line because it was not bundled previously - # The cdylib will contain the `native_func` symbol in the end - $(RUSTC) cdylib-non-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -e '-l[" ]*native-staticlib' - $(NM) $(call DYLIB,cdylib_non_bundled) | $(CGREP) -e "[Tt] _*native_func" diff --git a/tests/run-make/native-link-modifier-bundle/rmake.rs b/tests/run-make/native-link-modifier-bundle/rmake.rs new file mode 100644 index 0000000000000..058b66b15f12f --- /dev/null +++ b/tests/run-make/native-link-modifier-bundle/rmake.rs @@ -0,0 +1,90 @@ +// This test exercises the `bundle` link argument, which can be turned on or off. + +// When building a rlib or staticlib, +bundle means that all object files from the native static +// library will be added to the rlib or staticlib archive, and then used from it during linking of +// the final binary. + +// When building a rlib -bundle means that the native static library is registered as a dependency +// of that rlib "by name", and object files from it are included only during linking of the final +// binary, the file search by that name is also performed during final linking. +// When building a staticlib -bundle means that the native static library is simply not included +// into the archive and some higher level build system will need to add it later during linking of +// the final binary. + +// This modifier has no effect when building other targets like executables or dynamic libraries. + +// The default for this modifier is +bundle. +// See https://github.com/rust-lang/rust/pull/95818 + +//@ ignore-cross-compile +// Reason: cross-compilation fails to export native symbols + +use run_make_support::{ + build_native_static_lib, dynamic_lib_name, is_msvc, llvm_nm, rust_lib_name, rustc, + static_lib_name, +}; + +fn main() { + build_native_static_lib("native-staticlib"); + // Build a staticlib and a rlib, the `native_func` symbol will be bundled into them + rustc().input("bundled.rs").crate_type("staticlib").crate_type("rlib").run(); + llvm_nm() + .input(static_lib_name("bundled")) + .run() + .assert_stdout_contains_regex("T _*native_func"); + llvm_nm() + .input(static_lib_name("bundled")) + .run() + .assert_stdout_contains_regex("U _*native_func"); + llvm_nm().input(rust_lib_name("bundled")).run().assert_stdout_contains_regex("T _*native_func"); + llvm_nm().input(rust_lib_name("bundled")).run().assert_stdout_contains_regex("U _*native_func"); + + // Build a staticlib and a rlib, the `native_func` symbol will not be bundled into it + build_native_static_lib("native-staticlib"); + rustc().input("non-bundled.rs").crate_type("staticlib").crate_type("rlib").run(); + llvm_nm() + .input(static_lib_name("non_bundled")) + .run() + .assert_stdout_not_contains_regex("T _*native_func"); + llvm_nm() + .input(static_lib_name("non_bundled")) + .run() + .assert_stdout_contains_regex("U _*native_func"); + llvm_nm() + .input(rust_lib_name("non_bundled")) + .run() + .assert_stdout_not_contains_regex("T _*native_func"); + llvm_nm() + .input(rust_lib_name("non_bundled")) + .run() + .assert_stdout_contains_regex("U _*native_func"); + + // This part of the test does not function on Windows MSVC - no symbols are printed. + if !is_msvc() { + // Build a cdylib, `native-staticlib` will not appear on the linker line because it was + // bundled previously. The cdylib will contain the `native_func` symbol in the end. + rustc() + .input("cdylib-bundled.rs") + .crate_type("cdylib") + .print("link-args") + .run() + .assert_stdout_not_contains(r#"-l[" ]*native-staticlib"#); + llvm_nm() + .input(dynamic_lib_name("cdylib_bundled")) + .run() + .assert_stdout_contains_regex("[Tt] _*native_func"); + + // Build a cdylib, `native-staticlib` will appear on the linker line because it was not + // bundled previously. The cdylib will contain the `native_func` symbol in the end + rustc() + .input("cdylib-non-bundled.rs") + .crate_type("cdylib") + .print("link-args") + .run() + .assert_stdout_contains_regex(r#"-l[" ]*native-staticlib"#); + llvm_nm() + .input(dynamic_lib_name("cdylib_non_bundled")) + .run() + .assert_stdout_contains_regex("[Tt] _*native_func"); + } +} diff --git a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs index 7cd0932ecf342..ff0438a6b72be 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs +++ b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs @@ -4,10 +4,11 @@ // that is what this test checks. // See https://github.com/rust-lang/rust/pull/100101 -// FIXME(Oneirical): MSVC and cross-compile +//@ ignore-cross-compile +// Reason: cross-compilation fails to export native symbols use run_make_support::{ - bin_name, build_native_static_lib, cwd, filename_contains, llvm_ar, llvm_nm, rfs, + bin_name, build_native_static_lib, cwd, filename_contains, is_msvc, llvm_ar, llvm_nm, rfs, rust_lib_name, rustc, shallow_find_files, }; @@ -72,10 +73,12 @@ fn main() { .run() .assert_stdout_contains_regex("native_dep_1.*native_dep_2.*native_dep_3"); - //FIXME(Oneirical): This part will apparently fail on MSVC - llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f1"); - llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f2"); - llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f3"); - llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_local"); - llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_up"); + // The binary "main" will not contain any symbols on MSVC. + if !is_msvc() { + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f1"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f2"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f3"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_local"); + llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*rust_dep_up"); + } } From 9a95573c2bb3e76643f0c1c4deb5eea24c37ec5c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 5 Aug 2024 17:25:00 +0100 Subject: [PATCH 22/23] Add cautionary paragraph about noop wakers. Based on a suggestion from @kpreid, with some further editing. --- library/core/src/task/wake.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index baa8a956f8af1..4d2de6be025bc 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -539,6 +539,10 @@ impl Waker { /// some futures, but are not expecting those futures to wake the waker or /// do not need to do anything specific if it happens. /// + /// More generally, using `Waker::noop()` to poll a future + /// means discarding the notification of when the future should be polled again. + /// So it should only be used when such a notification will not be needed to make progress. + /// /// If an owned `Waker` is needed, `clone()` this one. /// /// # Examples @@ -796,6 +800,10 @@ impl LocalWaker { /// some futures, but are not expecting those futures to wake the waker or /// do not need to do anything specific if it happens. /// + /// More generally, using `LocalWaker::noop()` to poll a future + /// means discarding the notification of when the future should be polled again, + /// So it should only be used when such a notification will not be needed to make progress. + /// /// If an owned `LocalWaker` is needed, `clone()` this one. /// /// # Examples From 7d99549073b8785feec85c9ed25eb29bb09daa29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 15 Aug 2024 22:44:16 +0200 Subject: [PATCH 23/23] crashes: more tests --- tests/crashes/128695.rs | 11 +++++++++++ tests/crashes/128810.rs | 25 +++++++++++++++++++++++++ tests/crashes/128848.rs | 5 +++++ tests/crashes/128870.rs | 18 ++++++++++++++++++ tests/crashes/129075.rs | 16 ++++++++++++++++ tests/crashes/129095.rs | 10 ++++++++++ tests/crashes/129099.rs | 15 +++++++++++++++ tests/crashes/129109.rs | 10 ++++++++++ tests/crashes/129127.rs | 21 +++++++++++++++++++++ 9 files changed, 131 insertions(+) create mode 100644 tests/crashes/128695.rs create mode 100644 tests/crashes/128810.rs create mode 100644 tests/crashes/128848.rs create mode 100644 tests/crashes/128870.rs create mode 100644 tests/crashes/129075.rs create mode 100644 tests/crashes/129095.rs create mode 100644 tests/crashes/129099.rs create mode 100644 tests/crashes/129109.rs create mode 100644 tests/crashes/129127.rs diff --git a/tests/crashes/128695.rs b/tests/crashes/128695.rs new file mode 100644 index 0000000000000..661f427dc0e99 --- /dev/null +++ b/tests/crashes/128695.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#128695 +//@ edition: 2021 + +use core::pin::{pin, Pin}; + +fn main() { + let fut = pin!(async { + let async_drop_fut = pin!(core::future::async_drop(async {})); + (async_drop_fut).await; + }); +} diff --git a/tests/crashes/128810.rs b/tests/crashes/128810.rs new file mode 100644 index 0000000000000..68214ff010c99 --- /dev/null +++ b/tests/crashes/128810.rs @@ -0,0 +1,25 @@ +//@ known-bug: rust-lang/rust#128810 + +#![feature(fn_delegation)] + +use std::marker::PhantomData; + +pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); + +impl<'a> InvariantRef<'a, ()> { + pub const NEW: Self = InvariantRef::new(&()); +} + +trait Trait { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } + fn meh(&self) -> u8 { 2 } +} + +struct Z(u8); + +impl Trait for Z { + reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } +} + +fn main() { } diff --git a/tests/crashes/128848.rs b/tests/crashes/128848.rs new file mode 100644 index 0000000000000..636811fc6b504 --- /dev/null +++ b/tests/crashes/128848.rs @@ -0,0 +1,5 @@ +//@ known-bug: rust-lang/rust#128848 + +fn f(a: T, b: T, c: T) { + f.call_once() +} diff --git a/tests/crashes/128870.rs b/tests/crashes/128870.rs new file mode 100644 index 0000000000000..2b7319621440c --- /dev/null +++ b/tests/crashes/128870.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#128870 +//@ compile-flags: -Zvalidate-mir + +#[repr(packed)] +#[repr(u32)] +enum E { + A, + B, + C, +} + +fn main() { + union InvalidTag { + int: u32, + e: E, + } + let _invalid_tag = InvalidTag { int: 4 }; +} diff --git a/tests/crashes/129075.rs b/tests/crashes/129075.rs new file mode 100644 index 0000000000000..4a0e920914cc5 --- /dev/null +++ b/tests/crashes/129075.rs @@ -0,0 +1,16 @@ +//@ known-bug: rust-lang/rust#129075 +//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes + +struct Foo([T; 2]); + +impl Default for Foo { + fn default(&mut self) -> Self { + Foo([Default::default(); 2]) + } +} + +fn field_array() { + let a: i32; + let b; + Foo([a, b]) = Default::default(); +} diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs new file mode 100644 index 0000000000000..ea70c0565fc36 --- /dev/null +++ b/tests/crashes/129095.rs @@ -0,0 +1,10 @@ +//@ known-bug: rust-lang/rust#129095 +//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir + +pub fn function_with_bytes() -> &'static [u8] { + BYTES +} + +pub fn main() { + assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); +} diff --git a/tests/crashes/129099.rs b/tests/crashes/129099.rs new file mode 100644 index 0000000000000..9aaab756b5b8d --- /dev/null +++ b/tests/crashes/129099.rs @@ -0,0 +1,15 @@ +//@ known-bug: rust-lang/rust#129099 + +#![feature(type_alias_impl_trait)] + +fn dyn_hoops() -> dyn for<'a> Iterator> { + loop {} +} + +pub fn main() { + type Opaque = impl Sized; + fn define() -> Opaque { + let x: Opaque = dyn_hoops::<()>(0); + x + } +} diff --git a/tests/crashes/129109.rs b/tests/crashes/129109.rs new file mode 100644 index 0000000000000..8b9ebdf03c779 --- /dev/null +++ b/tests/crashes/129109.rs @@ -0,0 +1,10 @@ +//@ known-bug: rust-lang/rust#129109 +//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir + +extern "C" { + pub static mut symbol: [i8]; +} + +fn main() { + println!("C", unsafe { &symbol }); +} diff --git a/tests/crashes/129127.rs b/tests/crashes/129127.rs new file mode 100644 index 0000000000000..8ec848dbd0578 --- /dev/null +++ b/tests/crashes/129127.rs @@ -0,0 +1,21 @@ +//@ known-bug: rust-lang/rust#129127 +//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir -Zcross-crate-inline-threshold=always + + + + +pub struct Rows<'a>(); + +impl<'a> Iterator for Rows<'a> { + type Item = (); + + fn next() -> Option { + let mut rows = Rows(); + rows.map(|row| row).next() + } +} + +fn main() { + let mut rows = Rows(); + rows.next(); +}