Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e8e1b32

Browse files
committedAug 10, 2021
Auto merge of #87923 - JohnTitor:rollup-id54fyz, r=JohnTitor
Rollup of 14 pull requests Successful merges: - #86840 (Constify implementations of `(Try)From` for int types) - #87582 (Implement `Printer` for `&mut SymbolPrinter`) - #87636 (Added the `Option::unzip()` method) - #87700 (Expand explanation of E0530) - #87811 (Do not ICE on HIR based WF check when involving lifetimes) - #87848 (removed references to parent/child from std::thread documentation) - #87854 (correctly handle enum variants in `opt_const_param_of`) - #87861 (Fix heading colours in Ayu theme) - #87865 (Clarify terms in rustdoc book) - #87876 (add `windows` count test) - #87880 (Remove duplicate trait bounds in `rustc_data_structures::graph`) - #87881 (Proper table row formatting in platform support) - #87889 (Use smaller spans when suggesting method call disambiguation) - #87895 (typeck: don't suggest inaccessible fields in struct literals and suggest ignoring inaccessible fields in struct patterns) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ae90dcf + 4be63b2 commit e8e1b32

File tree

32 files changed

+399
-132
lines changed

32 files changed

+399
-132
lines changed
 

‎compiler/rustc_data_structures/src/graph/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,13 @@ pub trait WithStartNode: DirectedGraph {
6060
}
6161

6262
pub trait ControlFlowGraph:
63-
DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes
63+
DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
6464
{
6565
// convenient trait
6666
}
6767

6868
impl<T> ControlFlowGraph for T where
69-
T: DirectedGraph
70-
+ WithStartNode
71-
+ WithPredecessors
72-
+ WithStartNode
73-
+ WithSuccessors
74-
+ WithNumNodes
69+
T: DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
7570
{
7671
}
7772

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,57 @@
11
A binding shadowed something it shouldn't.
22

3-
Erroneous code example:
3+
A match arm or a variable has a name that is already used by
4+
something else, e.g.
5+
6+
* struct name
7+
* enum variant
8+
* static
9+
* associated constant
10+
11+
This error may also happen when an enum variant *with fields* is used
12+
in a pattern, but without its fields.
13+
14+
```compile_fail
15+
enum Enum {
16+
WithField(i32)
17+
}
18+
19+
use Enum::*;
20+
match WithField(1) {
21+
WithField => {} // error: missing (_)
22+
}
23+
```
24+
25+
Match bindings cannot shadow statics:
426

527
```compile_fail,E0530
628
static TEST: i32 = 0;
729
8-
let r: (i32, i32) = (0, 0);
30+
let r = 123;
931
match r {
10-
TEST => {} // error: match bindings cannot shadow statics
32+
TEST => {} // error: name of a static
1133
}
1234
```
1335

14-
To fix this error, just change the binding's name in order to avoid shadowing
15-
one of the following:
36+
Fixed examples:
1637

17-
* struct name
18-
* struct/enum variant
19-
* static
20-
* const
21-
* associated const
38+
```
39+
static TEST: i32 = 0;
2240
23-
Fixed example:
41+
let r = 123;
42+
match r {
43+
some_value => {} // ok!
44+
}
45+
```
46+
47+
or
2448

2549
```
26-
static TEST: i32 = 0;
50+
const TEST: i32 = 0; // const, not static
2751
28-
let r: (i32, i32) = (0, 0);
52+
let r = 123;
2953
match r {
30-
something => {} // ok!
54+
TEST => {} // const is ok!
55+
other_values => {}
3156
}
3257
```

‎compiler/rustc_symbol_mangling/src/legacy.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ pub(super) fn mangle(
5555

5656
let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
5757

58-
let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false }
58+
let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false };
59+
printer
5960
.print_def_path(
6061
def_id,
6162
if let ty::InstanceDef::DropGlue(_, _) = instance.def {
@@ -198,7 +199,7 @@ struct SymbolPrinter<'tcx> {
198199
// `PrettyPrinter` aka pretty printing of e.g. types in paths,
199200
// symbol names should have their own printing machinery.
200201

201-
impl Printer<'tcx> for SymbolPrinter<'tcx> {
202+
impl Printer<'tcx> for &mut SymbolPrinter<'tcx> {
202203
type Error = fmt::Error;
203204

204205
type Path = Self;
@@ -242,7 +243,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
242243
Ok(self)
243244
}
244245

245-
fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
246+
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
246247
// only print integers
247248
if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int { .. })) = ct.val {
248249
if ct.ty.is_integral() {
@@ -253,7 +254,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
253254
Ok(self)
254255
}
255256

256-
fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
257+
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
257258
self.write_str(&self.tcx.crate_name(cnum).as_str())?;
258259
Ok(self)
259260
}
@@ -344,7 +345,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
344345
}
345346
}
346347

347-
impl PrettyPrinter<'tcx> for SymbolPrinter<'tcx> {
348+
impl PrettyPrinter<'tcx> for &mut SymbolPrinter<'tcx> {
348349
fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool {
349350
false
350351
}

‎compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
245245
if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
246246
root_obligation.cause.code.peel_derives()
247247
{
248-
if let Some(cause) =
249-
self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone()))
250-
{
248+
if let Some(cause) = self.tcx.diagnostic_hir_wf_check((
249+
tcx.erase_regions(obligation.predicate),
250+
wf_loc.clone(),
251+
)) {
251252
obligation.cause = cause;
252253
span = obligation.cause.span;
253254
}

‎compiler/rustc_typeck/src/check/expr.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,15 +1313,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13131313
.emit();
13141314
}
13151315
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
1316-
let no_accessible_remaining_fields = remaining_fields
1317-
.iter()
1318-
.find(|(_, (_, field))| {
1319-
field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
1320-
})
1321-
.is_none();
1316+
let inaccessible_remaining_fields = remaining_fields.iter().any(|(_, (_, field))| {
1317+
!field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
1318+
});
13221319

1323-
if no_accessible_remaining_fields {
1324-
self.report_no_accessible_fields(adt_ty, span);
1320+
if inaccessible_remaining_fields {
1321+
self.report_inaccessible_fields(adt_ty, span);
13251322
} else {
13261323
self.report_missing_fields(adt_ty, span, remaining_fields);
13271324
}
@@ -1398,7 +1395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13981395
.emit();
13991396
}
14001397

1401-
/// Report an error for a struct field expression when there are no visible fields.
1398+
/// Report an error for a struct field expression when there are invisible fields.
14021399
///
14031400
/// ```text
14041401
/// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
@@ -1409,7 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091406
///
14101407
/// error: aborting due to previous error
14111408
/// ```
1412-
fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
1409+
fn report_inaccessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
14131410
self.tcx.sess.span_err(
14141411
span,
14151412
&format!(

‎compiler/rustc_typeck/src/check/method/suggest.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,8 +1695,8 @@ fn print_disambiguation_help(
16951695
source_map: &source_map::SourceMap,
16961696
) {
16971697
let mut applicability = Applicability::MachineApplicable;
1698-
let sugg_args = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
1699-
format!(
1698+
let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
1699+
let args = format!(
17001700
"({}{})",
17011701
if rcvr_ty.is_region_ptr() {
17021702
if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
@@ -1710,12 +1710,12 @@ fn print_disambiguation_help(
17101710
}))
17111711
.collect::<Vec<_>>()
17121712
.join(", "),
1713-
)
1713+
);
1714+
(span, format!("{}::{}{}", trait_name, item_name, args))
17141715
} else {
1715-
String::new()
1716+
(span.with_hi(item_name.span.lo()), format!("{}::", trait_name))
17161717
};
1717-
let sugg = format!("{}::{}{}", trait_name, item_name, sugg_args);
1718-
err.span_suggestion(
1718+
err.span_suggestion_verbose(
17191719
span,
17201720
&format!(
17211721
"disambiguate the {} for {}",

‎compiler/rustc_typeck/src/check/pat.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,15 +1250,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12501250
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
12511251
}
12521252
} else if !etc && !unmentioned_fields.is_empty() {
1253-
let no_accessible_unmentioned_fields = !unmentioned_fields.iter().any(|(field, _)| {
1254-
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
1255-
});
1253+
let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
1254+
.iter()
1255+
.copied()
1256+
.filter(|(field, _)| {
1257+
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
1258+
})
1259+
.collect();
12561260

1257-
if no_accessible_unmentioned_fields {
1261+
if accessible_unmentioned_fields.is_empty() {
12581262
unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
12591263
} else {
1260-
unmentioned_err =
1261-
Some(self.error_unmentioned_fields(pat, &unmentioned_fields, &fields));
1264+
unmentioned_err = Some(self.error_unmentioned_fields(
1265+
pat,
1266+
&accessible_unmentioned_fields,
1267+
accessible_unmentioned_fields.len() != unmentioned_fields.len(),
1268+
&fields,
1269+
));
12621270
}
12631271
}
12641272
match (inexistent_fields_err, unmentioned_err) {
@@ -1583,17 +1591,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15831591
&self,
15841592
pat: &Pat<'_>,
15851593
unmentioned_fields: &[(&ty::FieldDef, Ident)],
1594+
have_inaccessible_fields: bool,
15861595
fields: &'tcx [hir::PatField<'tcx>],
15871596
) -> DiagnosticBuilder<'tcx> {
1597+
let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
15881598
let field_names = if unmentioned_fields.len() == 1 {
1589-
format!("field `{}`", unmentioned_fields[0].1)
1599+
format!("field `{}`{}", unmentioned_fields[0].1, inaccessible)
15901600
} else {
15911601
let fields = unmentioned_fields
15921602
.iter()
15931603
.map(|(_, name)| format!("`{}`", name))
15941604
.collect::<Vec<String>>()
15951605
.join(", ");
1596-
format!("fields {}", fields)
1606+
format!("fields {}{}", fields, inaccessible)
15971607
};
15981608
let mut err = struct_span_err!(
15991609
self.tcx.sess,
@@ -1624,17 +1634,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16241634
err.span_suggestion(
16251635
sp,
16261636
&format!(
1627-
"include the missing field{} in the pattern",
1637+
"include the missing field{} in the pattern{}",
16281638
if len == 1 { "" } else { "s" },
1639+
if have_inaccessible_fields { " and ignore the inaccessible fields" } else { "" }
16291640
),
16301641
format!(
1631-
"{}{}{}",
1642+
"{}{}{}{}",
16321643
prefix,
16331644
unmentioned_fields
16341645
.iter()
16351646
.map(|(_, name)| name.to_string())
16361647
.collect::<Vec<_>>()
16371648
.join(", "),
1649+
if have_inaccessible_fields { ", .." } else { "" },
16381650
postfix,
16391651
),
16401652
Applicability::MachineApplicable,

‎compiler/rustc_typeck/src/collect/type_of.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
190190
// Try to use the segment resolution if it is valid, otherwise we
191191
// default to the path resolution.
192192
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
193+
use def::CtorOf;
193194
let generics = match res {
194-
Res::Def(DefKind::Ctor(..), def_id) => {
195+
Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => tcx.generics_of(
196+
tcx.parent(def_id).and_then(|def_id| tcx.parent(def_id)).unwrap(),
197+
),
198+
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => {
195199
tcx.generics_of(tcx.parent(def_id).unwrap())
196200
}
197201
// Other `DefKind`s don't have generics and would ICE when calling
@@ -200,7 +204,6 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
200204
DefKind::Struct
201205
| DefKind::Union
202206
| DefKind::Enum
203-
| DefKind::Variant
204207
| DefKind::Trait
205208
| DefKind::OpaqueTy
206209
| DefKind::TyAlias

‎library/core/src/convert/num.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
4545
macro_rules! impl_from {
4646
($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => {
4747
#[$attr]
48-
impl From<$Small> for $Large {
48+
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
49+
impl const From<$Small> for $Large {
4950
// Rustdocs on the impl block show a "[+] show undocumented items" toggle.
5051
// Rustdocs on functions do not.
5152
#[doc = $doc]
@@ -172,7 +173,8 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
172173
macro_rules! try_from_unbounded {
173174
($source:ty, $($target:ty),*) => {$(
174175
#[stable(feature = "try_from", since = "1.34.0")]
175-
impl TryFrom<$source> for $target {
176+
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
177+
impl const TryFrom<$source> for $target {
176178
type Error = TryFromIntError;
177179

178180
/// Try to create the target number type from a source
@@ -190,7 +192,8 @@ macro_rules! try_from_unbounded {
190192
macro_rules! try_from_lower_bounded {
191193
($source:ty, $($target:ty),*) => {$(
192194
#[stable(feature = "try_from", since = "1.34.0")]
193-
impl TryFrom<$source> for $target {
195+
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
196+
impl const TryFrom<$source> for $target {
194197
type Error = TryFromIntError;
195198

196199
/// Try to create the target number type from a source
@@ -212,7 +215,8 @@ macro_rules! try_from_lower_bounded {
212215
macro_rules! try_from_upper_bounded {
213216
($source:ty, $($target:ty),*) => {$(
214217
#[stable(feature = "try_from", since = "1.34.0")]
215-
impl TryFrom<$source> for $target {
218+
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
219+
impl const TryFrom<$source> for $target {
216220
type Error = TryFromIntError;
217221

218222
/// Try to create the target number type from a source
@@ -234,7 +238,8 @@ macro_rules! try_from_upper_bounded {
234238
macro_rules! try_from_both_bounded {
235239
($source:ty, $($target:ty),*) => {$(
236240
#[stable(feature = "try_from", since = "1.34.0")]
237-
impl TryFrom<$source> for $target {
241+
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
242+
impl const TryFrom<$source> for $target {
238243
type Error = TryFromIntError;
239244

240245
/// Try to create the target number type from a source

‎library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#![feature(const_slice_from_raw_parts)]
100100
#![feature(const_slice_ptr_len)]
101101
#![feature(const_swap)]
102+
#![feature(const_trait_impl)]
102103
#![feature(const_type_id)]
103104
#![feature(const_type_name)]
104105
#![feature(const_unreachable_unchecked)]

‎library/core/src/option.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,33 @@ impl<T> Option<T> {
13991399
}
14001400
}
14011401

1402+
impl<T, U> Option<(T, U)> {
1403+
/// Unzips an option containing a tuple of two options
1404+
///
1405+
/// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`.
1406+
/// Otherwise, `(None, None)` is returned.
1407+
///
1408+
/// # Examples
1409+
///
1410+
/// ```
1411+
/// #![feature(unzip_option)]
1412+
///
1413+
/// let x = Some((1, "hi"));
1414+
/// let y = None::<(u8, u32)>;
1415+
///
1416+
/// assert_eq!(x.unzip(), (Some(1), Some("hi")));
1417+
/// assert_eq!(y.unzip(), (None, None));
1418+
/// ```
1419+
#[inline]
1420+
#[unstable(feature = "unzip_option", issue = "87800", reason = "recently added")]
1421+
pub const fn unzip(self) -> (Option<T>, Option<U>) {
1422+
match self {
1423+
Some((a, b)) => (Some(a), Some(b)),
1424+
None => (None, None),
1425+
}
1426+
}
1427+
}
1428+
14021429
impl<T: Copy> Option<&T> {
14031430
/// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
14041431
/// option.

‎library/core/tests/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#![feature(const_ptr_read)]
1414
#![feature(const_ptr_write)]
1515
#![feature(const_ptr_offset)]
16+
#![feature(const_trait_impl)]
17+
#![feature(const_num_from_num)]
1618
#![feature(core_intrinsics)]
1719
#![feature(core_private_bignum)]
1820
#![feature(core_private_diy_float)]
@@ -66,6 +68,7 @@
6668
#![feature(slice_group_by)]
6769
#![feature(trusted_random_access)]
6870
#![feature(unsize)]
71+
#![feature(unzip_option)]
6972
#![deny(unsafe_op_in_unsafe_fn)]
7073

7174
extern crate test;

‎library/core/tests/num/const_from.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[test]
2+
fn from() {
3+
use core::convert::TryFrom;
4+
use core::num::TryFromIntError;
5+
6+
// From
7+
const FROM: i64 = i64::from(1i32);
8+
assert_eq!(FROM, 1i64);
9+
10+
// From int to float
11+
const FROM_F64: f64 = f64::from(42u8);
12+
assert_eq!(FROM_F64, 42f64);
13+
14+
// Upper bounded
15+
const U8_FROM_U16: Result<u8, TryFromIntError> = u8::try_from(1u16);
16+
assert_eq!(U8_FROM_U16, Ok(1u8));
17+
18+
// Both bounded
19+
const I8_FROM_I16: Result<i8, TryFromIntError> = i8::try_from(1i16);
20+
assert_eq!(I8_FROM_I16, Ok(1i8));
21+
22+
// Lower bounded
23+
const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16);
24+
assert_eq!(I16_FROM_U16, Ok(1i16));
25+
}

‎library/core/tests/num/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ mod u64;
2727
mod u8;
2828

2929
mod bignum;
30+
31+
mod const_from;
3032
mod dec2flt;
3133
mod flt2dec;
3234
mod int_log;

‎library/core/tests/option.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,43 @@ fn test_unwrap_drop() {
399399
}
400400

401401
#[test]
402-
pub fn option_ext() {
402+
fn option_ext() {
403403
let thing = "{{ f }}";
404404
let f = thing.find("{{");
405405

406406
if f.is_none() {
407407
println!("None!");
408408
}
409409
}
410+
411+
#[test]
412+
fn zip_options() {
413+
let x = Some(10);
414+
let y = Some("foo");
415+
let z: Option<usize> = None;
416+
417+
assert_eq!(x.zip(y), Some((10, "foo")));
418+
assert_eq!(x.zip(z), None);
419+
assert_eq!(z.zip(x), None);
420+
}
421+
422+
#[test]
423+
fn unzip_options() {
424+
let x = Some((10, "foo"));
425+
let y = None::<(bool, i32)>;
426+
427+
assert_eq!(x.unzip(), (Some(10), Some("foo")));
428+
assert_eq!(y.unzip(), (None, None));
429+
}
430+
431+
#[test]
432+
fn zip_unzip_roundtrip() {
433+
let x = Some(10);
434+
let y = Some("foo");
435+
436+
let z = x.zip(y);
437+
assert_eq!(z, Some((10, "foo")));
438+
439+
let a = z.unzip();
440+
assert_eq!(a, (x, y));
441+
}

‎library/core/tests/slice.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,10 @@ fn test_array_windows_count() {
739739
let v3: &[i32] = &[];
740740
let c3 = v3.array_windows::<2>();
741741
assert_eq!(c3.count(), 0);
742+
743+
let v4: &[()] = &[(); usize::MAX];
744+
let c4 = v4.array_windows::<1>();
745+
assert_eq!(c4.count(), usize::MAX);
742746
}
743747

744748
#[test]
@@ -1050,6 +1054,10 @@ fn test_windows_count() {
10501054
let v3: &[i32] = &[];
10511055
let c3 = v3.windows(2);
10521056
assert_eq!(c3.count(), 0);
1057+
1058+
let v4 = &[(); usize::MAX];
1059+
let c4 = v4.windows(1);
1060+
assert_eq!(c4.count(), usize::MAX);
10531061
}
10541062

10551063
#[test]

‎library/std/src/thread/mod.rs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
//! When the main thread of a Rust program terminates, the entire program shuts
2929
//! down, even if other threads are still running. However, this module provides
3030
//! convenient facilities for automatically waiting for the termination of a
31-
//! child thread (i.e., join).
31+
//! thread (i.e., join).
3232
//!
3333
//! ## Spawning a thread
3434
//!
@@ -42,38 +42,43 @@
4242
//! });
4343
//! ```
4444
//!
45-
//! In this example, the spawned thread is "detached" from the current
46-
//! thread. This means that it can outlive its parent (the thread that spawned
47-
//! it), unless this parent is the main thread.
45+
//! In this example, the spawned thread is "detached," which means that there is
46+
//! no way for the program to learn when the spawned thread completes or otherwise
47+
//! terminates.
4848
//!
49-
//! The parent thread can also wait on the completion of the child
50-
//! thread; a call to [`spawn`] produces a [`JoinHandle`], which provides
51-
//! a `join` method for waiting:
49+
//! To learn when a thread completes, it is necessary to capture the [`JoinHandle`]
50+
//! object that is returned by the call to [`spawn`], which provides
51+
//! a `join` method that allows the caller to wait for the completion of the
52+
//! spawned thread:
5253
//!
5354
//! ```rust
5455
//! use std::thread;
5556
//!
56-
//! let child = thread::spawn(move || {
57+
//! let thread_join_handle = thread::spawn(move || {
5758
//! // some work here
5859
//! });
5960
//! // some work here
60-
//! let res = child.join();
61+
//! let res = thread_join_handle.join();
6162
//! ```
6263
//!
6364
//! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
64-
//! value produced by the child thread, or [`Err`] of the value given to
65-
//! a call to [`panic!`] if the child panicked.
65+
//! value produced by the spawned thread, or [`Err`] of the value given to
66+
//! a call to [`panic!`] if the thread panicked.
67+
//!
68+
//! Note that there is no parent/child relationship between a thread that spawns a
69+
//! new thread and the thread being spawned. In particular, the spawned thread may or
70+
//! may not outlive the spawning thread, unless the spawning thread is the main thread.
6671
//!
6772
//! ## Configuring threads
6873
//!
6974
//! A new thread can be configured before it is spawned via the [`Builder`] type,
70-
//! which currently allows you to set the name and stack size for the child thread:
75+
//! which currently allows you to set the name and stack size for the thread:
7176
//!
7277
//! ```rust
7378
//! # #![allow(unused_must_use)]
7479
//! use std::thread;
7580
//!
76-
//! thread::Builder::new().name("child1".to_string()).spawn(move || {
81+
//! thread::Builder::new().name("thread1".to_string()).spawn(move || {
7782
//! println!("Hello, world!");
7883
//! });
7984
//! ```
@@ -344,7 +349,7 @@ impl Builder {
344349
/// The spawned thread may outlive the caller (unless the caller thread
345350
/// is the main thread; the whole process is terminated when the main
346351
/// thread finishes). The join handle can be used to block on
347-
/// termination of the child thread, including recovering its panics.
352+
/// termination of the spawned thread, including recovering its panics.
348353
///
349354
/// For a more complete documentation see [`thread::spawn`][`spawn`].
350355
///
@@ -389,7 +394,7 @@ impl Builder {
389394
/// The spawned thread may outlive the caller (unless the caller thread
390395
/// is the main thread; the whole process is terminated when the main
391396
/// thread finishes). The join handle can be used to block on
392-
/// termination of the child thread, including recovering its panics.
397+
/// termination of the spawned thread, including recovering its panics.
393398
///
394399
/// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`],
395400
/// except for the relaxed lifetime bounds, which render it unsafe.
@@ -516,15 +521,16 @@ impl Builder {
516521

517522
/// Spawns a new thread, returning a [`JoinHandle`] for it.
518523
///
519-
/// The join handle will implicitly *detach* the child thread upon being
520-
/// dropped. In this case, the child thread may outlive the parent (unless
521-
/// the parent thread is the main thread; the whole process is terminated when
522-
/// the main thread finishes). Additionally, the join handle provides a [`join`]
523-
/// method that can be used to join the child thread. If the child thread
524-
/// panics, [`join`] will return an [`Err`] containing the argument given to
525-
/// [`panic!`].
524+
/// The join handle provides a [`join`] method that can be used to join the spawned
525+
/// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing
526+
/// the argument given to [`panic!`].
527+
///
528+
/// If the join handle is dropped, the spawned thread will implicitly be *detached*.
529+
/// In this case, the spawned thread may no longer be joined.
530+
/// (It is the responsibility of the program to either eventually join threads it
531+
/// creates or detach them; otherwise, a resource leak will result.)
526532
///
527-
/// This will create a thread using default parameters of [`Builder`], if you
533+
/// This call will create a thread using default parameters of [`Builder`], if you
528534
/// want to specify the stack size or the name of the thread, use this API
529535
/// instead.
530536
///
@@ -533,8 +539,8 @@ impl Builder {
533539
///
534540
/// - The `'static` constraint means that the closure and its return value
535541
/// must have a lifetime of the whole program execution. The reason for this
536-
/// is that threads can `detach` and outlive the lifetime they have been
537-
/// created in.
542+
/// is that threads can outlive the lifetime they have been created in.
543+
///
538544
/// Indeed if the thread, and by extension its return value, can outlive their
539545
/// caller, we need to make sure that they will be valid afterwards, and since
540546
/// we *can't* know when it will return we need to have them valid as long as
@@ -1236,10 +1242,10 @@ impl fmt::Debug for Thread {
12361242
#[stable(feature = "rust1", since = "1.0.0")]
12371243
pub type Result<T> = crate::result::Result<T, Box<dyn Any + Send + 'static>>;
12381244

1239-
// This packet is used to communicate the return value between the child thread
1240-
// and the parent thread. Memory is shared through the `Arc` within and there's
1245+
// This packet is used to communicate the return value between the spawned thread
1246+
// and the rest of the program. Memory is shared through the `Arc` within and there's
12411247
// no need for a mutex here because synchronization happens with `join()` (the
1242-
// parent thread never reads this packet until the child has exited).
1248+
// caller will never read this packet until the thread has exited).
12431249
//
12441250
// This packet itself is then stored into a `JoinInner` which in turns is placed
12451251
// in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
@@ -1303,7 +1309,7 @@ impl<T> JoinInner<T> {
13031309
/// }).unwrap();
13041310
/// ```
13051311
///
1306-
/// Child being detached and outliving its parent:
1312+
/// A thread being detached and outliving the thread that spawned it:
13071313
///
13081314
/// ```no_run
13091315
/// use std::thread;
@@ -1361,12 +1367,15 @@ impl<T> JoinHandle<T> {
13611367

13621368
/// Waits for the associated thread to finish.
13631369
///
1370+
/// This function will return immediately if the associated thread has already finished.
1371+
///
13641372
/// In terms of [atomic memory orderings], the completion of the associated
13651373
/// thread synchronizes with this function returning. In other words, all
1366-
/// operations performed by that thread are ordered before all
1374+
/// operations performed by that thread [happen
1375+
/// before](https://doc.rust-lang.org/nomicon/atomics.html#data-accesses) all
13671376
/// operations that happen after `join` returns.
13681377
///
1369-
/// If the child thread panics, [`Err`] is returned with the parameter given
1378+
/// If the associated thread panics, [`Err`] is returned with the parameter given
13701379
/// to [`panic!`].
13711380
///
13721381
/// [`Err`]: crate::result::Result::Err

‎src/doc/rustc/src/platform-support.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ The `std` column in the table below has the following meanings:
115115
target | std | notes
116116
-------|:---:|-------
117117
`aarch64-apple-ios` | ✓ | ARM64 iOS
118+
[`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | Apple iOS Simulator on ARM64
118119
`aarch64-fuchsia` | ✓ | ARM64 Fuchsia
119120
`aarch64-linux-android` | ✓ | ARM64 Android
120121
`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
@@ -165,7 +166,6 @@ target | std | notes
165166
`wasm32-unknown-unknown` | ✓ | WebAssembly
166167
`wasm32-wasi` | ✓ | WebAssembly with WASI
167168
`x86_64-apple-ios` | ✓ | 64-bit x86 iOS
168-
[`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | | Apple iOS Simulator on ARM64
169169
`x86_64-fortanix-unknown-sgx` | ✓ | [Fortanix ABI] for 64-bit Intel SGX
170170
`x86_64-fuchsia` | ✓ | 64-bit Fuchsia
171171
`x86_64-linux-android` | ✓ | 64-bit x86 Android

‎src/doc/rustdoc/src/documentation-tests.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -297,20 +297,23 @@ we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
297297

298298
## Attributes
299299

300-
There are a few annotations that are useful to help `rustdoc` do the right
300+
Code blocks can be annotated with attributes that help `rustdoc` do the right
301301
thing when testing your code:
302302

303+
The `ignore` attribute tells Rust to ignore your code. This is almost never
304+
what you want as it's the most generic. Instead, consider annotating it
305+
with `text` if it's not code or using `#`s to get a working example that
306+
only shows the part you care about.
307+
303308
```rust
304309
/// ```ignore
305310
/// fn foo() {
306311
/// ```
307312
# fn foo() {}
308313
```
309314

310-
The `ignore` directive tells Rust to ignore your code. This is almost never
311-
what you want, as it's the most generic. Instead, consider annotating it
312-
with `text` if it's not code, or using `#`s to get a working example that
313-
only shows the part you care about.
315+
`should_panic` tells `rustdoc` that the code should compile correctly but
316+
panic during execution. If the code doesn't panic, the test will fail.
314317

315318
```rust
316319
/// ```should_panic
@@ -319,8 +322,10 @@ only shows the part you care about.
319322
# fn foo() {}
320323
```
321324

322-
`should_panic` tells `rustdoc` that the code should compile correctly, but
323-
not actually pass as a test.
325+
The `no_run` attribute will compile your code but not run it. This is
326+
important for examples such as "Here's how to retrieve a web page,"
327+
which you would want to ensure compiles, but might be run in a test
328+
environment that has no network access.
324329

325330
```rust
326331
/// ```no_run
@@ -331,24 +336,24 @@ not actually pass as a test.
331336
# fn foo() {}
332337
```
333338

334-
The `no_run` attribute will compile your code, but not run it. This is
335-
important for examples such as "Here's how to retrieve a web page,"
336-
which you would want to ensure compiles, but might be run in a test
337-
environment that has no network access.
339+
`compile_fail` tells `rustdoc` that the compilation should fail. If it
340+
compiles, then the test will fail. However, please note that code failing
341+
with the current Rust release may work in a future release, as new features
342+
are added.
338343

339-
```text
344+
```rust
340345
/// ```compile_fail
341346
/// let x = 5;
342347
/// x += 2; // shouldn't compile!
343348
/// ```
349+
# fn foo() {}
344350
```
345351

346-
`compile_fail` tells `rustdoc` that the compilation should fail. If it
347-
compiles, then the test will fail. However please note that code failing
348-
with the current Rust release may work in a future release, as new features
349-
are added.
352+
`edition2018` tells `rustdoc` that the code sample should be compiled using
353+
the 2018 edition of Rust. Similarly, you can specify `edition2015` to compile
354+
the code with the 2015 edition.
350355

351-
```text
356+
```rust
352357
/// Only runs on the 2018 edition.
353358
///
354359
/// ```edition2018
@@ -358,12 +363,9 @@ are added.
358363
/// + "3".parse::<i32>()?
359364
/// };
360365
/// ```
366+
# fn foo() {}
361367
```
362368

363-
`edition2018` tells `rustdoc` that the code sample should be compiled using
364-
the 2018 edition of Rust. Similarly, you can specify `edition2015` to compile
365-
the code with the 2015 edition.
366-
367369
## Syntax reference
368370

369371
The *exact* syntax for code blocks, including the edge cases, can be found
@@ -385,7 +387,7 @@ section.
385387

386388
However, it's preferable to use fenced code blocks over indented code blocks.
387389
Not only are fenced code blocks considered more idiomatic for Rust code,
388-
but there is no way to use directives such as `ignore` or `should_panic` with
390+
but there is no way to use attributes such as `ignore` or `should_panic` with
389391
indented code blocks.
390392

391393
### Include items only when collecting doctests

‎src/librustdoc/html/static/css/themes/ayu.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ h4 {
3737
.docblock code {
3838
color: #ffb454;
3939
}
40-
h3 > code, h4 > code, h5 > code {
40+
.code-header {
4141
color: #e6e1cf;
4242
}
4343
pre > code {

‎src/test/ui/associated-consts/associated-const-ambiguity-report.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ LL | const ID: i32 = 3;
1717
help: disambiguate the associated constant for candidate #1
1818
|
1919
LL | const X: i32 = Foo::ID;
20-
| ^^^^^^^
20+
| ^^^^^
2121
help: disambiguate the associated constant for candidate #2
2222
|
2323
LL | const X: i32 = Bar::ID;
24-
| ^^^^^^^
24+
| ^^^^^
2525

2626
error: aborting due to previous error
2727

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// check-pass
2+
enum Foo<const N: usize> {
3+
Variant,
4+
Variant2(),
5+
Variant3{},
6+
}
7+
8+
struct Bar<const N: usize>;
9+
struct Bar2<const N: usize>();
10+
struct Bar3<const N: usize> {}
11+
12+
fn main() {
13+
let _ = Foo::Variant::<1>;
14+
let _ = Foo::Variant2::<1>();
15+
let _ = Foo::Variant3::<1>{};
16+
17+
let _ = Foo::<1>::Variant;
18+
let _ = Foo::<1>::Variant2();
19+
let _ = Foo::<1>::Variant3{};
20+
21+
let _ = Bar::<1>;
22+
let _ = Bar2::<1>();
23+
let _ = Bar3::<1>{};
24+
}

‎src/test/ui/error-codes/E0034.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ LL | fn foo() {}
1717
help: disambiguate the associated function for candidate #1
1818
|
1919
LL | Trait1::foo()
20-
| ^^^^^^^^^^^
20+
| ^^^^^^^^
2121
help: disambiguate the associated function for candidate #2
2222
|
2323
LL | Trait2::foo()
24-
| ^^^^^^^^^^^
24+
| ^^^^^^^^
2525

2626
error: aborting due to previous error
2727

‎src/test/ui/issues/issue-18446.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ error[E0034]: multiple applicable items in scope
22
--> $DIR/issue-18446.rs:18:7
33
|
44
LL | x.foo();
5-
| --^^^--
6-
| | |
7-
| | multiple `foo` found
8-
| help: disambiguate the associated function for candidate #2: `T::foo(&x)`
5+
| ^^^ multiple `foo` found
96
|
107
note: candidate #1 is defined in an impl for the type `(dyn T + 'a)`
118
--> $DIR/issue-18446.rs:9:5
@@ -17,6 +14,10 @@ note: candidate #2 is defined in the trait `T`
1714
|
1815
LL | fn foo(&self);
1916
| ^^^^^^^^^^^^^^
17+
help: disambiguate the associated function for candidate #2
18+
|
19+
LL | T::foo(&x);
20+
| ^^^^^^^^^^
2021

2122
error: aborting due to previous error
2223

‎src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ LL | fn foo() {}
1717
help: disambiguate the associated function for candidate #1
1818
|
1919
LL | A::foo();
20-
| ^^^^^^
20+
| ^^^
2121
help: disambiguate the associated function for candidate #2
2222
|
2323
LL | B::foo();
24-
| ^^^^^^
24+
| ^^^
2525

2626
error: aborting due to previous error
2727

‎src/test/ui/span/issue-7575.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,7 @@ error[E0599]: no method named `is_str` found for type parameter `T` in the curre
6161
--> $DIR/issue-7575.rs:70:7
6262
|
6363
LL | t.is_str()
64-
| --^^^^^^--
65-
| | |
66-
| | this is an associated function, not a method
67-
| help: disambiguate the associated function for the candidate: `ManyImplTrait::is_str(t)`
64+
| ^^^^^^ this is an associated function, not a method
6865
|
6966
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
7067
note: the candidate is defined in the trait `ManyImplTrait`
@@ -73,6 +70,10 @@ note: the candidate is defined in the trait `ManyImplTrait`
7370
LL | fn is_str() -> bool {
7471
| ^^^^^^^^^^^^^^^^^^^
7572
= help: items from traits can only be used if the type parameter is bounded by the trait
73+
help: disambiguate the associated function for the candidate
74+
|
75+
LL | ManyImplTrait::is_str(t)
76+
|
7677

7778
error: aborting due to 3 previous errors
7879

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub mod foo {
2+
pub struct Foo {
3+
pub you_can_use_this_field: bool,
4+
you_cant_use_this_field: bool,
5+
}
6+
}
7+
8+
fn main() {
9+
foo::Foo {};
10+
//~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
2+
--> $DIR/issue-87872-missing-inaccessible-field-literal.rs:9:5
3+
|
4+
LL | foo::Foo {};
5+
| ^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(dead_code, unused_variables)]
2+
3+
pub mod foo {
4+
#[derive(Default)]
5+
pub struct Foo { pub visible: bool, invisible: bool, }
6+
}
7+
8+
fn main() {
9+
let foo::Foo {} = foo::Foo::default();
10+
//~^ ERROR pattern does not mention field `visible` and inaccessible fields
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0027]: pattern does not mention field `visible` and inaccessible fields
2+
--> $DIR/issue-87872-missing-inaccessible-field-pattern.rs:9:9
3+
|
4+
LL | let foo::Foo {} = foo::Foo::default();
5+
| ^^^^^^^^^^^ missing field `visible` and inaccessible fields
6+
|
7+
help: include the missing field in the pattern and ignore the inaccessible fields
8+
|
9+
LL | let foo::Foo { visible, .. } = foo::Foo::default();
10+
| ^^^^^^^^^^^^^^^
11+
help: if you don't care about this missing field, you can explicitly ignore it
12+
|
13+
LL | let foo::Foo { .. } = foo::Foo::default();
14+
| ^^^^^^
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0027`.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for #87549.
2+
// compile-flags: -C incremental=tmp/wf/hir-wf-check-erase-regions
3+
4+
pub struct Table<T, const N: usize>([Option<T>; N]);
5+
6+
impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
7+
type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; //~ ERROR `&T` is not an iterator
8+
type Item = &'a T;
9+
10+
fn into_iter(self) -> Self::IntoIter { //~ ERROR `&T` is not an iterator
11+
unimplemented!()
12+
}
13+
}
14+
fn main() {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0277]: `&T` is not an iterator
2+
--> $DIR/hir-wf-check-erase-regions.rs:7:5
3+
|
4+
LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&T` is not an iterator
6+
|
7+
::: $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
8+
|
9+
LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
10+
| ------------ required by this bound in `Flatten`
11+
|
12+
= help: the trait `Iterator` is not implemented for `&T`
13+
= note: required because of the requirements on the impl of `IntoIterator` for `&T`
14+
15+
error[E0277]: `&T` is not an iterator
16+
--> $DIR/hir-wf-check-erase-regions.rs:10:27
17+
|
18+
LL | fn into_iter(self) -> Self::IntoIter {
19+
| ^^^^^^^^^^^^^^ `&T` is not an iterator
20+
|
21+
::: $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
22+
|
23+
LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
24+
| ------------ required by this bound in `Flatten`
25+
|
26+
= help: the trait `Iterator` is not implemented for `&T`
27+
= note: required because of the requirements on the impl of `IntoIterator` for `&T`
28+
29+
error: aborting due to 2 previous errors
30+
31+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)
Please sign in to comment.