Skip to content

Commit 06e4768

Browse files
committed
Auto merge of #73316 - Dylan-DPC:rollup-zgouwou, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #72932 (Clarify the behaviour of Pattern when used with methods like str::contains) - #73066 (Querify whether a type has structural equality (Take 2)) - #73194 (Prefer the associated constants for pattern matching error) - #73241 (Add/update comments about MinGW late_link_args) - #73267 (Use the built cargo for cargotest.) - #73290 (Fix links when pinging notification groups) - #73302 (Adjusted some doctests in libcore to use `should_panic`.) - #73308 (pretty/asm.rs should only be tested for x86_64 and not AArch64) Failed merges: r? @ghost
2 parents 1fb612b + 8d97ccf commit 06e4768

38 files changed

+300
-234
lines changed

src/bootstrap/test.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ impl Step for Cargotest {
154154
fn run(self, builder: &Builder<'_>) {
155155
let compiler = builder.compiler(self.stage, self.host);
156156
builder.ensure(compile::Rustc { compiler, target: compiler.host });
157+
let cargo = builder.ensure(tool::Cargo { compiler, target: compiler.host });
157158

158159
// Note that this is a short, cryptic, and not scoped directory name. This
159160
// is currently to minimize the length of path on Windows where we otherwise
@@ -165,7 +166,7 @@ impl Step for Cargotest {
165166
let mut cmd = builder.tool_cmd(Tool::CargoTest);
166167
try_run(
167168
builder,
168-
cmd.arg(&builder.initial_cargo)
169+
cmd.arg(&cargo)
169170
.arg(&out_dir)
170171
.env("RUSTC", builder.rustc(compiler))
171172
.env("RUSTDOC", builder.rustdoc(compiler)),

src/libcore/cell.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -778,18 +778,13 @@ impl<T: ?Sized> RefCell<T> {
778778
///
779779
/// An example of panic:
780780
///
781-
/// ```
781+
/// ```should_panic
782782
/// use std::cell::RefCell;
783-
/// use std::thread;
784-
///
785-
/// let result = thread::spawn(move || {
786-
/// let c = RefCell::new(5);
787-
/// let m = c.borrow_mut();
788783
///
789-
/// let b = c.borrow(); // this causes a panic
790-
/// }).join();
784+
/// let c = RefCell::new(5);
791785
///
792-
/// assert!(result.is_err());
786+
/// let m = c.borrow_mut();
787+
/// let b = c.borrow(); // this causes a panic
793788
/// ```
794789
#[stable(feature = "rust1", since = "1.0.0")]
795790
#[inline]
@@ -858,18 +853,13 @@ impl<T: ?Sized> RefCell<T> {
858853
///
859854
/// An example of panic:
860855
///
861-
/// ```
856+
/// ```should_panic
862857
/// use std::cell::RefCell;
863-
/// use std::thread;
864-
///
865-
/// let result = thread::spawn(move || {
866-
/// let c = RefCell::new(5);
867-
/// let m = c.borrow();
868858
///
869-
/// let b = c.borrow_mut(); // this causes a panic
870-
/// }).join();
859+
/// let c = RefCell::new(5);
860+
/// let m = c.borrow();
871861
///
872-
/// assert!(result.is_err());
862+
/// let b = c.borrow_mut(); // this causes a panic
873863
/// ```
874864
#[stable(feature = "rust1", since = "1.0.0")]
875865
#[inline]

src/libcore/char/convert.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,11 @@ impl fmt::Display for CharTryFromError {
278278
///
279279
/// Passing a large radix, causing a panic:
280280
///
281-
/// ```
282-
/// use std::thread;
281+
/// ```should_panic
283282
/// use std::char;
284283
///
285-
/// let result = thread::spawn(|| {
286-
/// // this panics
287-
/// let c = char::from_digit(1, 37);
288-
/// }).join();
289-
///
290-
/// assert!(result.is_err());
284+
/// // this panics
285+
/// let c = char::from_digit(1, 37);
291286
/// ```
292287
#[inline]
293288
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/char/methods.rs

+17-45
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,11 @@ impl char {
229229
///
230230
/// Passing a large radix, causing a panic:
231231
///
232-
/// ```
233-
/// use std::thread;
232+
/// ```should_panic
234233
/// use std::char;
235234
///
236-
/// let result = thread::spawn(|| {
237-
/// // this panics
238-
/// let c = char::from_digit(1, 37);
239-
/// }).join();
240-
///
241-
/// assert!(result.is_err());
235+
/// // this panics
236+
/// char::from_digit(1, 37);
242237
/// ```
243238
#[unstable(feature = "assoc_char_funcs", reason = "recently added", issue = "71763")]
244239
#[inline]
@@ -282,15 +277,9 @@ impl char {
282277
///
283278
/// Passing a large radix, causing a panic:
284279
///
285-
/// ```
286-
/// use std::thread;
287-
///
288-
/// let result = thread::spawn(|| {
289-
/// // this panics
290-
/// '1'.is_digit(37);
291-
/// }).join();
292-
///
293-
/// assert!(result.is_err());
280+
/// ```should_panic
281+
/// // this panics
282+
/// '1'.is_digit(37);
294283
/// ```
295284
#[stable(feature = "rust1", since = "1.0.0")]
296285
#[inline]
@@ -337,14 +326,9 @@ impl char {
337326
///
338327
/// Passing a large radix, causing a panic:
339328
///
340-
/// ```
341-
/// use std::thread;
342-
///
343-
/// let result = thread::spawn(|| {
344-
/// '1'.to_digit(37);
345-
/// }).join();
346-
///
347-
/// assert!(result.is_err());
329+
/// ```should_panic
330+
/// // this panics
331+
/// '1'.to_digit(37);
348332
/// ```
349333
#[stable(feature = "rust1", since = "1.0.0")]
350334
#[inline]
@@ -646,17 +630,11 @@ impl char {
646630
///
647631
/// A buffer that's too small:
648632
///
649-
/// ```
650-
/// use std::thread;
651-
///
652-
/// let result = thread::spawn(|| {
653-
/// let mut b = [0; 1];
654-
///
655-
/// // this panics
656-
/// 'ß'.encode_utf8(&mut b);
657-
/// }).join();
633+
/// ```should_panic
634+
/// let mut b = [0; 1];
658635
///
659-
/// assert!(result.is_err());
636+
/// // this panics
637+
/// 'ß'.encode_utf8(&mut b);
660638
/// ```
661639
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
662640
#[inline]
@@ -687,17 +665,11 @@ impl char {
687665
///
688666
/// A buffer that's too small:
689667
///
690-
/// ```
691-
/// use std::thread;
692-
///
693-
/// let result = thread::spawn(|| {
694-
/// let mut b = [0; 1];
695-
///
696-
/// // this panics
697-
/// '𝕊'.encode_utf16(&mut b);
698-
/// }).join();
668+
/// ```should_panic
669+
/// let mut b = [0; 1];
699670
///
700-
/// assert!(result.is_err());
671+
/// // this panics
672+
/// '𝕊'.encode_utf16(&mut b);
701673
/// ```
702674
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
703675
#[inline]

src/libcore/str/pattern.rs

+37
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,43 @@ use crate::slice::memchr;
6060
/// The trait itself acts as a builder for an associated
6161
/// `Searcher` type, which does the actual work of finding
6262
/// occurrences of the pattern in a string.
63+
///
64+
/// Depending on the type of the pattern, the behaviour of methods like
65+
/// [`str::find`] and [`str::contains`] can change. The table below describes
66+
/// some of those behaviours.
67+
///
68+
/// | Pattern type | Match condition |
69+
/// |--------------------------|-------------------------------------------|
70+
/// | `&str` | is substring |
71+
/// | `char` | is contained in string |
72+
/// | `&[char] | any char in slice is contained in string |
73+
/// | `F: FnMut(char) -> bool` | `F` returns `true` for a char in string |
74+
/// | `&&str` | is substring |
75+
/// | `&String` | is substring |
76+
///
77+
/// # Examples
78+
/// ```
79+
/// // &str
80+
/// assert_eq!("abaaa".find("ba"), Some(1));
81+
/// assert_eq!("abaaa".find("bac"), None);
82+
///
83+
/// // char
84+
/// assert_eq!("abaaa".find('a'), Some(0));
85+
/// assert_eq!("abaaa".find('b'), Some(1));
86+
/// assert_eq!("abaaa".find('c'), None);
87+
///
88+
/// // &[char]
89+
/// assert_eq!("ab".find(&['b', 'a'][..]), Some(0));
90+
/// assert_eq!("abaaa".find(&['a', 'z'][..]), Some(0));
91+
/// assert_eq!("abaaa".find(&['c', 'd'][..]), None);
92+
///
93+
/// // FnMut(char) -> bool
94+
/// assert_eq!("abcdef_z".find(|ch| ch > 'd' && ch < 'y'), Some(4));
95+
/// assert_eq!("abcddd_z".find(|ch| ch > 'd' && ch < 'y'), None);
96+
/// ```
97+
///
98+
/// [`str::find`]: ../../../std/primitive.str.html#method.find
99+
/// [`str::contains`]: ../../../std/primitive.str.html#method.contains
63100
pub trait Pattern<'a>: Sized {
64101
/// Associated searcher for this pattern
65102
type Searcher: Searcher<'a>;

src/librustc_middle/query/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,17 @@ rustc_queries! {
789789
desc { "computing whether `{}` needs drop", env.value }
790790
}
791791

792+
/// Query backing `TyS::is_structural_eq_shallow`.
793+
///
794+
/// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types
795+
/// correctly.
796+
query has_structural_eq_impls(ty: Ty<'tcx>) -> bool {
797+
desc {
798+
"computing whether `{:?}` implements `PartialStructuralEq` and `StructuralEq`",
799+
ty
800+
}
801+
}
802+
792803
/// A list of types where the ADT requires drop if and only if any of
793804
/// those types require drop. If the ADT is known to always need drop
794805
/// then `Err(AlwaysRequiresDrop)` is returned.

src/librustc_middle/ty/print/pretty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ pub trait PrettyPrinter<'tcx>:
986986

987987
let ui_str = ui.name_str();
988988
if data == max {
989-
p!(write("std::{}::MAX", ui_str))
989+
p!(write("{}::MAX", ui_str))
990990
} else {
991991
if print_ty { p!(write("{}{}", data, ui_str)) } else { p!(write("{}", data)) }
992992
};
@@ -999,8 +999,8 @@ pub trait PrettyPrinter<'tcx>:
999999

10001000
let i_str = i.name_str();
10011001
match data {
1002-
d if d == min => p!(write("std::{}::MIN", i_str)),
1003-
d if d == max => p!(write("std::{}::MAX", i_str)),
1002+
d if d == min => p!(write("{}::MIN", i_str)),
1003+
d if d == max => p!(write("{}::MAX", i_str)),
10041004
_ => {
10051005
let data = sign_extend(data, size) as i128;
10061006
if print_ty {

src/librustc_middle/ty/util.rs

+51
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,57 @@ impl<'tcx> ty::TyS<'tcx> {
778778
}
779779
}
780780

781+
/// Returns `true` if equality for this type is both reflexive and structural.
782+
///
783+
/// Reflexive equality for a type is indicated by an `Eq` impl for that type.
784+
///
785+
/// Primitive types (`u32`, `str`) have structural equality by definition. For composite data
786+
/// types, equality for the type as a whole is structural when it is the same as equality
787+
/// between all components (fields, array elements, etc.) of that type. For ADTs, structural
788+
/// equality is indicated by an implementation of `PartialStructuralEq` and `StructuralEq` for
789+
/// that type.
790+
///
791+
/// This function is "shallow" because it may return `true` for a composite type whose fields
792+
/// are not `StructuralEq`. For example, `[T; 4]` has structural equality regardless of `T`
793+
/// because equality for arrays is determined by the equality of each array element. If you
794+
/// want to know whether a given call to `PartialEq::eq` will proceed structurally all the way
795+
/// down, you will need to use a type visitor.
796+
#[inline]
797+
pub fn is_structural_eq_shallow(&'tcx self, tcx: TyCtxt<'tcx>) -> bool {
798+
match self.kind {
799+
// Look for an impl of both `PartialStructuralEq` and `StructuralEq`.
800+
Adt(..) => tcx.has_structural_eq_impls(self),
801+
802+
// Primitive types that satisfy `Eq`.
803+
Bool | Char | Int(_) | Uint(_) | Str | Never => true,
804+
805+
// Composite types that satisfy `Eq` when all of their fields do.
806+
//
807+
// Because this function is "shallow", we return `true` for these composites regardless
808+
// of the type(s) contained within.
809+
Ref(..) | Array(..) | Slice(_) | Tuple(..) => true,
810+
811+
// Raw pointers use bitwise comparison.
812+
RawPtr(_) | FnPtr(_) => true,
813+
814+
// Floating point numbers are not `Eq`.
815+
Float(_) => false,
816+
817+
// Conservatively return `false` for all others...
818+
819+
// Anonymous function types
820+
FnDef(..) | Closure(..) | Dynamic(..) | Generator(..) => false,
821+
822+
// Generic or inferred types
823+
//
824+
// FIXME(ecstaticmorse): Maybe we should `bug` here? This should probably only be
825+
// called for known, fully-monomorphized types.
826+
Projection(_) | Opaque(..) | Param(_) | Bound(..) | Placeholder(_) | Infer(_) => false,
827+
828+
Foreign(_) | GeneratorWitness(..) | Error => false,
829+
}
830+
}
831+
781832
pub fn same_type(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
782833
match (&a.kind, &b.kind) {
783834
(&Adt(did_a, substs_a), &Adt(did_b, substs_b)) => {

src/librustc_mir/transform/check_consts/qualifs.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//!
33
//! See the `Qualif` trait for more info.
44
5-
use rustc_infer::infer::TyCtxtInferExt;
65
use rustc_middle::mir::*;
76
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
87
use rustc_span::DUMMY_SP;
@@ -137,10 +136,7 @@ impl Qualif for CustomEq {
137136
substs: SubstsRef<'tcx>,
138137
) -> bool {
139138
let ty = cx.tcx.mk_ty(ty::Adt(adt, substs));
140-
let id = cx.tcx.hir().local_def_id_to_hir_id(cx.def_id.as_local().unwrap());
141-
cx.tcx
142-
.infer_ctxt()
143-
.enter(|infcx| !traits::type_marked_structural(id, cx.body.span, &infcx, ty))
139+
!ty.is_structural_eq_shallow(cx.tcx)
144140
}
145141
}
146142

src/librustc_mir_build/hair/pattern/const_to_pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
8080
}
8181

8282
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
83-
traits::type_marked_structural(self.id, self.span, &self.infcx, ty)
83+
ty.is_structural_eq_shallow(self.infcx.tcx)
8484
}
8585

8686
fn to_pat(

src/librustc_target/spec/windows_gnu_base.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub fn opts() -> TargetOptions {
1717
let mut late_link_args = LinkArgs::new();
1818
let mut late_link_args_dynamic = LinkArgs::new();
1919
let mut late_link_args_static = LinkArgs::new();
20+
// Order of `late_link_args*` was found through trial and error to work with various
21+
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
2022
late_link_args.insert(
2123
LinkerFlavor::Gcc,
2224
vec![
@@ -27,10 +29,9 @@ pub fn opts() -> TargetOptions {
2729
// And it seems that the linker fails to use import symbols from msvcrt
2830
// that are required from functions in msvcrt in certain cases. For example
2931
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
30-
// Listing the library twice seems to fix that, and seems to also be done
31-
// by mingw's gcc (Though not sure if it's done on purpose, or by mistake).
32+
// The library is purposely listed twice to fix that.
3233
//
33-
// See https://github.com/rust-lang/rust/pull/47483
34+
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
3435
"-lmsvcrt".to_string(),
3536
"-luser32".to_string(),
3637
"-lkernel32".to_string(),

src/librustc_trait_selection/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapError;
6060
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
6161
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
6262
pub use self::structural_match::search_for_structural_match_violation;
63-
pub use self::structural_match::type_marked_structural;
6463
pub use self::structural_match::NonStructuralMatchTy;
6564
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
6665
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
@@ -553,6 +552,7 @@ fn type_implements_trait<'tcx>(
553552

554553
pub fn provide(providers: &mut ty::query::Providers<'_>) {
555554
object_safety::provide(providers);
555+
structural_match::provide(providers);
556556
*providers = ty::query::Providers {
557557
specialization_graph_of: specialize::specialization_graph_provider,
558558
specializes: specialize::specializes,

0 commit comments

Comments
 (0)