Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,27 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
})
}
}

pub(crate) struct NoCoreParser;

impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
const PATH: &[Symbol] = &[sym::no_core];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
// because it's a crate-level attribute, we already warn about it.
// Putting target limitations here would give duplicate warnings
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
const TYPE: AttributeType = AttributeType::CrateLevel;
}

pub(crate) struct NoStdParser;

impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
const PATH: &[Symbol] = &[sym::no_std];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
// because it's a crate-level attribute, we already warn about it.
// Putting target limitations here would give duplicate warnings
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
const TYPE: AttributeType = AttributeType::CrateLevel;
}
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use crate::attributes::codegen_attrs::{
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser,
TypeLengthLimitParser,
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
RecursionLimitParser, TypeLengthLimitParser,
};
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
Expand Down Expand Up @@ -223,8 +223,10 @@ attribute_parsers!(
Single<WithoutArgs<MacroEscapeParser>>,
Single<WithoutArgs<MarkerParser>>,
Single<WithoutArgs<MayDangleParser>>,
Single<WithoutArgs<NoCoreParser>>,
Single<WithoutArgs<NoImplicitPreludeParser>>,
Single<WithoutArgs<NoMangleParser>>,
Single<WithoutArgs<NoStdParser>>,
Single<WithoutArgs<NonExhaustiveParser>>,
Single<WithoutArgs<ParenSugarParser>>,
Single<WithoutArgs<PassByValueParser>>,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,18 @@ pub enum AttributeKind {
/// Represents `#[naked]`
Naked(Span),

/// Represents `#[no_core]`
NoCore(Span),

/// Represents `#[no_implicit_prelude]`
NoImplicitPrelude(Span),

/// Represents `#[no_mangle]`
NoMangle(Span),

/// Represents `#[no_std]`
NoStd(Span),

/// Represents `#[non_exhaustive]`
NonExhaustive(Span),

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ impl AttributeKind {
MoveSizeLimit { .. } => No,
MustUse { .. } => Yes,
Naked(..) => No,
NoCore(..) => No,
NoImplicitPrelude(..) => No,
NoMangle(..) => Yes, // Needed for rustdoc
NoMangle(..) => Yes, // Needed for rustdoc
NoStd(..) => No,
NonExhaustive(..) => Yes, // Needed for rustdoc
Optimize(..) => No,
ParenSugar(..) => No,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MoveSizeLimit { .. }
| AttributeKind::TypeLengthLimit { .. }
| AttributeKind::PatternComplexityLimit { .. }
| AttributeKind::NoCore { .. }
| AttributeKind::NoStd { .. }
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
Expand Down
24 changes: 24 additions & 0 deletions library/coretests/tests/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ fn layout_array_edge_cases() {
}
}

#[test]
fn layout_errors() {
let layout = Layout::new::<[u8; 2]>();
// Should error if the alignment is not a power of two.
assert!(layout.align_to(3).is_err());

// The remaining assertions ensure that the methods error on arithmetic overflow as the
// alignment cannot overflow `isize`.
let size = layout.size();
let size_max = isize::MAX as usize;
let align_max = size_max / size;

assert!(layout.align_to(size_max + 1).is_err());

assert!(layout.repeat(align_max).is_ok());
assert!(layout.repeat(align_max + 1).is_err());

assert!(layout.repeat_packed(align_max).is_ok());
assert!(layout.repeat_packed(align_max + 1).is_err());

let next = Layout::from_size_align(size_max, 1).unwrap();
assert!(layout.extend(next).is_err());
}

#[test]
fn layout_debug_shows_log2_of_alignment() {
// `Debug` is not stable, but here's what it does right now
Expand Down
43 changes: 43 additions & 0 deletions library/coretests/tests/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ fn test_escape_default() {
}
assert_eq!(string('\n'), "\\n");
assert_eq!(string('\r'), "\\r");
assert_eq!(string('\t'), "\\t");
assert_eq!(string('\''), "\\'");
assert_eq!(string('"'), "\\\"");
assert_eq!(string(' '), " ");
Expand Down Expand Up @@ -417,3 +418,45 @@ fn eu_iterator_specializations() {
check('\u{12340}');
check('\u{10FFFF}');
}

#[test]
#[should_panic]
fn test_from_digit_radix_too_high() {
let _ = char::from_digit(0, 37);
}

#[test]
fn test_from_digit_invalid_radix() {
assert!(char::from_digit(10, 9).is_none());
}

#[test]
#[should_panic]
fn test_to_digit_radix_too_low() {
let _ = 'a'.to_digit(1);
}

#[test]
#[should_panic]
fn test_to_digit_radix_too_high() {
let _ = 'a'.to_digit(37);
}

#[test]
fn test_as_ascii_invalid() {
assert!('❤'.as_ascii().is_none());
}

#[test]
#[should_panic]
fn test_encode_utf8_raw_buffer_too_small() {
let mut buf = [0u8; 1];
let _ = char::encode_utf8_raw('ß'.into(), &mut buf);
}

#[test]
#[should_panic]
fn test_encode_utf16_raw_buffer_too_small() {
let mut buf = [0u16; 1];
let _ = char::encode_utf16_raw('𐐷'.into(), &mut buf);
}
1 change: 1 addition & 0 deletions library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![feature(bool_to_result)]
#![feature(bstr)]
#![feature(cfg_target_has_reliable_f16_f128)]
#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]
#![feature(const_cmp)]
Expand Down
5 changes: 0 additions & 5 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@
#![feature(core_float_math)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(derive_const)]
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
#![feature(doc_masked)]
Expand Down Expand Up @@ -332,11 +331,7 @@
#![feature(cfg_select)]
#![feature(char_internals)]
#![feature(clone_to_uninit)]
#![feature(const_cmp)]
#![feature(const_convert)]
#![feature(const_ops)]
#![feature(const_option_ops)]
#![feature(const_try)]
#![feature(core_intrinsics)]
#![feature(core_io_borrowed_buf)]
#![feature(drop_guard)]
Expand Down
32 changes: 10 additions & 22 deletions library/std/src/sys/pal/hermit/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,8 @@ impl Timespec {
Timespec { t: timespec { tv_sec, tv_nsec } }
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
// FIXME: const PartialOrd
let mut cmp = self.t.tv_sec - other.t.tv_sec;
if cmp == 0 {
cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
}

if cmp >= 0 {
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
if self >= other {
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
Duration::new(
(self.t.tv_sec - other.t.tv_sec) as u64,
Expand All @@ -53,22 +46,20 @@ impl Timespec {
}
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;

// Nano calculations can't overflow because nanos are <1B which fit
// in a u32.
let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
if nsec >= NSEC_PER_SEC as u32 {
nsec -= NSEC_PER_SEC as u32;
let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
if nsec >= NSEC_PER_SEC.try_into().unwrap() {
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
secs = secs.checked_add(1)?;
}
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;

// Similar to above, nanos can't overflow.
Expand Down Expand Up @@ -222,18 +213,15 @@ impl SystemTime {
SystemTime(time)
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.sub_timespec(&other.0)
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add_duration(other)?))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub_duration(other)?))
}
}
15 changes: 4 additions & 11 deletions library/std/src/sys/pal/sgx/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,15 @@ impl SystemTime {
SystemTime(usercalls::insecure_time())
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}
9 changes: 3 additions & 6 deletions library/std/src/sys/pal/solid/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,19 @@ impl SystemTime {
Self(t)
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
if self.0 >= other.0 {
Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
} else {
Err(Duration::from_secs((other.0 as u64).wrapping_sub(self.0 as u64)))
}
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
}
}
27 changes: 7 additions & 20 deletions library/std/src/sys/pal/uefi/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,32 +80,19 @@ impl SystemTime {
.unwrap_or_else(|| panic!("time not implemented on this platform"))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
let temp = self.0.checked_add(*other)?;
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
let temp = Self(self.0.checked_add(*other)?);

// Check if can be represented in UEFI
// FIXME: const PartialOrd
let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
if cmp == 0 {
cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64;
}

if cmp <= 0 { Some(SystemTime(temp)) } else { None }
if temp <= MAX_UEFI_TIME { Some(temp) } else { None }
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
self.0.checked_sub(*other).map(Self)
}
}

Expand Down
Loading
Loading