Skip to content

Commit f83e026

Browse files
committed
Auto merge of #102632 - matthiaskrgr:rollup-h8s3zmo, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #98218 (Document the conditional existence of `alloc::sync` and `alloc::task`.) - #99216 (docs: be less harsh in wording for Vec::from_raw_parts) - #99460 (docs: Improve AsRef / AsMut docs on blanket impls) - #100470 (Tweak `FpCategory` example order.) - #101040 (Fix `#[derive(Default)]` on a generic `#[default]` enum adding unnecessary `Default` bounds) - #101308 (introduce `{char, u8}::is_ascii_octdigit`) - #102486 (Add diagnostic struct for const eval error in `rustc_middle`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0922559 + 1b9014f commit f83e026

File tree

27 files changed

+450
-34
lines changed

27 files changed

+450
-34
lines changed

Diff for: compiler/rustc_builtin_macros/src/deriving/bounds.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub fn expand_deriving_copy(
1616
let trait_def = TraitDef {
1717
span,
1818
path: path_std!(marker::Copy),
19+
skip_path_as_bound: false,
1920
additional_bounds: Vec::new(),
2021
generics: Bounds::empty(),
2122
supports_unions: true,

Diff for: compiler/rustc_builtin_macros/src/deriving/clone.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub fn expand_deriving_clone(
7272
let trait_def = TraitDef {
7373
span,
7474
path: path_std!(clone::Clone),
75+
skip_path_as_bound: false,
7576
additional_bounds: bounds,
7677
generics: Bounds::empty(),
7778
supports_unions: true,

Diff for: compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn expand_deriving_eq(
2525
let trait_def = TraitDef {
2626
span,
2727
path: path_std!(cmp::Eq),
28+
skip_path_as_bound: false,
2829
additional_bounds: Vec::new(),
2930
generics: Bounds::empty(),
3031
supports_unions: true,

Diff for: compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn expand_deriving_ord(
1919
let trait_def = TraitDef {
2020
span,
2121
path: path_std!(cmp::Ord),
22+
skip_path_as_bound: false,
2223
additional_bounds: Vec::new(),
2324
generics: Bounds::empty(),
2425
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub fn expand_deriving_partial_eq(
8383
let trait_def = TraitDef {
8484
span,
8585
path: path_std!(cmp::PartialEq),
86+
skip_path_as_bound: false,
8687
additional_bounds: Vec::new(),
8788
generics: Bounds::empty(),
8889
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub fn expand_deriving_partial_ord(
3737
let trait_def = TraitDef {
3838
span,
3939
path: path_std!(cmp::PartialOrd),
40+
skip_path_as_bound: false,
4041
additional_bounds: vec![],
4142
generics: Bounds::empty(),
4243
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/debug.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub fn expand_deriving_debug(
2020
let trait_def = TraitDef {
2121
span,
2222
path: path_std!(fmt::Debug),
23+
skip_path_as_bound: false,
2324
additional_bounds: Vec::new(),
2425
generics: Bounds::empty(),
2526
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/decodable.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn expand_deriving_rustc_decodable(
2323
let trait_def = TraitDef {
2424
span,
2525
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
26+
skip_path_as_bound: false,
2627
additional_bounds: Vec::new(),
2728
generics: Bounds::empty(),
2829
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/default.rs

+20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn expand_deriving_default(
2424
let trait_def = TraitDef {
2525
span,
2626
path: Path::new(vec![kw::Default, sym::Default]),
27+
skip_path_as_bound: has_a_default_variant(item),
2728
additional_bounds: Vec::new(),
2829
generics: Bounds::empty(),
2930
supports_unions: false,
@@ -262,3 +263,22 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
262263
}
263264
}
264265
}
266+
267+
fn has_a_default_variant(item: &Annotatable) -> bool {
268+
struct HasDefaultAttrOnVariant {
269+
found: bool,
270+
}
271+
272+
impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
273+
fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
274+
if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
275+
self.found = true;
276+
}
277+
// no need to subrecurse.
278+
}
279+
}
280+
281+
let mut visitor = HasDefaultAttrOnVariant { found: false };
282+
item.visit_with(&mut visitor);
283+
visitor.found
284+
}

Diff for: compiler/rustc_builtin_macros/src/deriving/encodable.rs

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub fn expand_deriving_rustc_encodable(
107107
let trait_def = TraitDef {
108108
span,
109109
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
110+
skip_path_as_bound: false,
110111
additional_bounds: Vec::new(),
111112
generics: Bounds::empty(),
112113
supports_unions: false,

Diff for: compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
174174
use rustc_span::Span;
175175
use std::cell::RefCell;
176176
use std::iter;
177+
use std::ops::Not;
177178
use std::vec;
178179
use thin_vec::thin_vec;
179180
use ty::{Bounds, Path, Ref, Self_, Ty};
@@ -187,6 +188,9 @@ pub struct TraitDef<'a> {
187188
/// Path of the trait, including any type parameters
188189
pub path: Path,
189190

191+
/// Whether to skip adding the current trait as a bound to the type parameters of the type.
192+
pub skip_path_as_bound: bool,
193+
190194
/// Additional bounds required of any type parameters of the type,
191195
/// other than the current trait
192196
pub additional_bounds: Vec<Ty>,
@@ -596,7 +600,7 @@ impl<'a> TraitDef<'a> {
596600
cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
597601
}).chain(
598602
// require the current trait
599-
iter::once(cx.trait_bound(trait_path.clone()))
603+
self.skip_path_as_bound.not().then(|| cx.trait_bound(trait_path.clone()))
600604
).chain(
601605
// also add in any bounds from the declaration
602606
param.bounds.iter().cloned()

Diff for: compiler/rustc_builtin_macros/src/deriving/hash.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub fn expand_deriving_hash(
2222
let hash_trait_def = TraitDef {
2323
span,
2424
path,
25+
skip_path_as_bound: false,
2526
additional_bounds: Vec::new(),
2627
generics: Bounds::empty(),
2728
supports_unions: false,

Diff for: compiler/rustc_error_messages/locales/en-US/middle.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ middle_previous_use_here =
1515
middle_limit_invalid =
1616
`limit` must be a non-negative integer
1717
.label = {$error_str}
18+
19+
middle_const_eval_non_int =
20+
constant evaluation of enum discriminant resulted in non-integer

Diff for: compiler/rustc_middle/src/error.rs

+7
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,10 @@ pub struct LimitInvalid<'a> {
4848
pub value_span: Span,
4949
pub error_str: &'a str,
5050
}
51+
52+
#[derive(Diagnostic)]
53+
#[diag(middle::const_eval_non_int)]
54+
pub struct ConstEvalNonIntError {
55+
#[primary_span]
56+
pub span: Span,
57+
}

Diff for: compiler/rustc_middle/src/ty/adt.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,9 @@ impl<'tcx> AdtDef<'tcx> {
458458
Some(Discr { val: b, ty })
459459
} else {
460460
info!("invalid enum discriminant: {:#?}", val);
461-
crate::mir::interpret::struct_error(
462-
tcx.at(tcx.def_span(expr_did)),
463-
"constant evaluation of enum discriminant resulted in non-integer",
464-
)
465-
.emit();
461+
tcx.sess.emit_err(crate::error::ConstEvalNonIntError {
462+
span: tcx.def_span(expr_did),
463+
});
466464
None
467465
}
468466
}

Diff for: library/alloc/src/sync.rs

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
//! Thread-safe reference-counting pointers.
44
//!
55
//! See the [`Arc<T>`][Arc] documentation for more details.
6+
//!
7+
//! **Note**: This module is only available on platforms that support atomic
8+
//! loads and stores of pointers. This may be detected at compile time using
9+
//! `#[cfg(target_has_atomic = "ptr")]`.
610
711
use core::any::Any;
812
use core::borrow;
@@ -82,6 +86,11 @@ macro_rules! acquire {
8286
/// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic]
8387
/// types.
8488
///
89+
/// **Note**: This type is only available on platforms that support atomic
90+
/// loads and stores of pointers, which includes all platforms that support
91+
/// the `std` crate but not all those which only support [`alloc`](crate).
92+
/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`.
93+
///
8594
/// ## Thread Safety
8695
///
8796
/// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference

Diff for: library/alloc/src/task.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#![stable(feature = "wake_trait", since = "1.51.0")]
2+
23
//! Types and Traits for working with asynchronous tasks.
4+
//!
5+
//! **Note**: This module is only available on platforms that support atomic
6+
//! loads and stores of pointers. This may be detected at compile time using
7+
//! `#[cfg(target_has_atomic = "ptr")]`.
8+
39
use core::mem::ManuallyDrop;
410
use core::task::{RawWaker, RawWakerVTable, Waker};
511

Diff for: library/alloc/src/vec/mod.rs

+73-8
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,13 @@ impl<T> Vec<T> {
483483
Self::with_capacity_in(capacity, Global)
484484
}
485485

486-
/// Creates a `Vec<T>` directly from the raw components of another vector.
486+
/// Creates a `Vec<T>` directly from a pointer, a capacity, and a length.
487487
///
488488
/// # Safety
489489
///
490490
/// This is highly unsafe, due to the number of invariants that aren't
491491
/// checked:
492492
///
493-
/// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
494-
/// (at least, it's highly likely to be incorrect if it wasn't).
495493
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
496494
/// (`T` having a less strict alignment is not sufficient, the alignment really
497495
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
@@ -500,6 +498,14 @@ impl<T> Vec<T> {
500498
/// to be the same size as the pointer was allocated with. (Because similar to
501499
/// alignment, [`dealloc`] must be called with the same layout `size`.)
502500
/// * `length` needs to be less than or equal to `capacity`.
501+
/// * The first `length` values must be properly initialized values of type `T`.
502+
/// * `capacity` needs to be the capacity that the pointer was allocated with.
503+
/// * The allocated size in bytes must be no larger than `isize::MAX`.
504+
/// See the safety documentation of [`pointer::offset`].
505+
///
506+
/// These requirements are always upheld by any `ptr` that has been allocated
507+
/// via `Vec<T>`. Other allocation sources are allowed if the invariants are
508+
/// upheld.
503509
///
504510
/// Violating these may cause problems like corrupting the allocator's
505511
/// internal data structures. For example it is normally **not** safe
@@ -551,6 +557,32 @@ impl<T> Vec<T> {
551557
/// assert_eq!(rebuilt, [4, 5, 6]);
552558
/// }
553559
/// ```
560+
///
561+
/// Using memory that was allocated elsewhere:
562+
///
563+
/// ```rust
564+
/// #![feature(allocator_api)]
565+
///
566+
/// use std::alloc::{AllocError, Allocator, Global, Layout};
567+
///
568+
/// fn main() {
569+
/// let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
570+
///
571+
/// let vec = unsafe {
572+
/// let mem = match Global.allocate(layout) {
573+
/// Ok(mem) => mem.cast::<u32>().as_ptr(),
574+
/// Err(AllocError) => return,
575+
/// };
576+
///
577+
/// mem.write(1_000_000);
578+
///
579+
/// Vec::from_raw_parts_in(mem, 1, 16, Global)
580+
/// };
581+
///
582+
/// assert_eq!(vec, &[1_000_000]);
583+
/// assert_eq!(vec.capacity(), 16);
584+
/// }
585+
/// ```
554586
#[inline]
555587
#[stable(feature = "rust1", since = "1.0.0")]
556588
pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
@@ -641,21 +673,30 @@ impl<T, A: Allocator> Vec<T, A> {
641673
Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
642674
}
643675

644-
/// Creates a `Vec<T, A>` directly from the raw components of another vector.
676+
/// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
677+
/// and an allocator.
645678
///
646679
/// # Safety
647680
///
648681
/// This is highly unsafe, due to the number of invariants that aren't
649682
/// checked:
650683
///
651-
/// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
652-
/// (at least, it's highly likely to be incorrect if it wasn't).
653-
/// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
684+
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
654685
/// (`T` having a less strict alignment is not sufficient, the alignment really
655686
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
656687
/// allocated and deallocated with the same layout.)
688+
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
689+
/// to be the same size as the pointer was allocated with. (Because similar to
690+
/// alignment, [`dealloc`] must be called with the same layout `size`.)
657691
/// * `length` needs to be less than or equal to `capacity`.
658-
/// * `capacity` needs to be the capacity that the pointer was allocated with.
692+
/// * The first `length` values must be properly initialized values of type `T`.
693+
/// * `capacity` needs to [*fit*] the layout size that the pointer was allocated with.
694+
/// * The allocated size in bytes must be no larger than `isize::MAX`.
695+
/// See the safety documentation of [`pointer::offset`].
696+
///
697+
/// These requirements are always upheld by any `ptr` that has been allocated
698+
/// via `Vec<T, A>`. Other allocation sources are allowed if the invariants are
699+
/// upheld.
659700
///
660701
/// Violating these may cause problems like corrupting the allocator's
661702
/// internal data structures. For example it is **not** safe
@@ -673,6 +714,7 @@ impl<T, A: Allocator> Vec<T, A> {
673714
///
674715
/// [`String`]: crate::string::String
675716
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
717+
/// [*fit*]: crate::alloc::Allocator#memory-fitting
676718
///
677719
/// # Examples
678720
///
@@ -711,6 +753,29 @@ impl<T, A: Allocator> Vec<T, A> {
711753
/// assert_eq!(rebuilt, [4, 5, 6]);
712754
/// }
713755
/// ```
756+
///
757+
/// Using memory that was allocated elsewhere:
758+
///
759+
/// ```rust
760+
/// use std::alloc::{alloc, Layout};
761+
///
762+
/// fn main() {
763+
/// let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
764+
/// let vec = unsafe {
765+
/// let mem = alloc(layout).cast::<u32>();
766+
/// if mem.is_null() {
767+
/// return;
768+
/// }
769+
///
770+
/// mem.write(1_000_000);
771+
///
772+
/// Vec::from_raw_parts(mem, 1, 16)
773+
/// };
774+
///
775+
/// assert_eq!(vec, &[1_000_000]);
776+
/// assert_eq!(vec.capacity(), 16);
777+
/// }
778+
/// ```
714779
#[inline]
715780
#[unstable(feature = "allocator_api", issue = "32838")]
716781
pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self {

Diff for: library/core/src/char/methods.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,38 @@ impl char {
14441444
matches!(*self, '0'..='9')
14451445
}
14461446

1447+
/// Checks if the value is an ASCII octal digit:
1448+
/// U+0030 '0' ..= U+0037 '7'.
1449+
///
1450+
/// # Examples
1451+
///
1452+
/// ```
1453+
/// #![feature(is_ascii_octdigit)]
1454+
///
1455+
/// let uppercase_a = 'A';
1456+
/// let a = 'a';
1457+
/// let zero = '0';
1458+
/// let seven = '7';
1459+
/// let nine = '9';
1460+
/// let percent = '%';
1461+
/// let lf = '\n';
1462+
///
1463+
/// assert!(!uppercase_a.is_ascii_octdigit());
1464+
/// assert!(!a.is_ascii_octdigit());
1465+
/// assert!(zero.is_ascii_octdigit());
1466+
/// assert!(seven.is_ascii_octdigit());
1467+
/// assert!(!nine.is_ascii_octdigit());
1468+
/// assert!(!percent.is_ascii_octdigit());
1469+
/// assert!(!lf.is_ascii_octdigit());
1470+
/// ```
1471+
#[must_use]
1472+
#[unstable(feature = "is_ascii_octdigit", issue = "101288")]
1473+
#[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")]
1474+
#[inline]
1475+
pub const fn is_ascii_octdigit(&self) -> bool {
1476+
matches!(*self, '0'..='7')
1477+
}
1478+
14471479
/// Checks if the value is an ASCII hexadecimal digit:
14481480
///
14491481
/// - U+0030 '0' ..= U+0039 '9', or

0 commit comments

Comments
 (0)