diff options
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0723.md | 16 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/active.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/slice/iter.rs | 29 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 3 | ||||
| -rw-r--r-- | src/test/codegen/slice-windows-no-bounds-check.rs | 35 | ||||
| -rw-r--r-- | src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/type-alias-impl-trait/issue-53096.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/type-alias-impl-trait/structural-match.rs | 2 |
16 files changed, 106 insertions, 49 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 492d5788fc0..8d9d4123c79 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -27,6 +27,7 @@ use crate::token::{self, CommentKind, DelimToken}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; use rustc_data_structures::thin_vec::ThinVec; use rustc_macros::HashStable_Generic; @@ -1864,7 +1865,7 @@ pub enum AssocTyConstraintKind { Bound { bounds: GenericBounds }, } -#[derive(Clone, Encodable, Decodable, Debug)] +#[derive(Encodable, Decodable, Debug)] pub struct Ty { pub id: NodeId, pub kind: TyKind, @@ -1872,6 +1873,17 @@ pub struct Ty { pub tokens: Option<TokenStream>, } +impl Clone for Ty { + fn clone(&self) -> Self { + ensure_sufficient_stack(|| Self { + id: self.id, + kind: self.kind.clone(), + span: self.span, + tokens: self.tokens.clone(), + }) + } +} + #[derive(Clone, Encodable, Decodable, Debug)] pub struct BareFnTy { pub unsafety: Unsafe, diff --git a/compiler/rustc_error_codes/src/error_codes/E0723.md b/compiler/rustc_error_codes/src/error_codes/E0723.md index 95d47ab21cb..bc224421915 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0723.md +++ b/compiler/rustc_error_codes/src/error_codes/E0723.md @@ -3,12 +3,8 @@ An unstable feature in `const` contexts was used. Erroneous code example: ```compile_fail,E0723 -trait T {} - -impl T for () {} - -const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable - () +const fn foo<T: Copy>(_: T) { // error! + // ... } ``` @@ -18,11 +14,7 @@ feature flag: ``` #![feature(const_fn)] -trait T {} - -impl T for () {} - -const fn foo() -> impl T { - () +const fn foo<T: Copy>(_: T) { // ok! + // ... } ``` diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index cd018ae1204..1982d098542 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -596,6 +596,9 @@ declare_features! ( /// Allows rustc to inject a default alloc_error_handler (active, default_alloc_error_handler, "1.48.0", Some(66741), None), + /// Allows argument and return position `impl Trait` in a `const fn`. + (active, const_impl_trait, "1.48.0", Some(77463), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 9a1b77e994d..63b20c7c027 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -558,12 +558,17 @@ pub mod ty { #[derive(Debug)] pub struct ImplTrait; impl NonConstOp for ImplTrait { - fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { - mcf_status_in_item(ccx) + fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { + Status::Unstable(sym::const_impl_trait) } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - mcf_build_error(ccx, span, "`impl Trait` in const fn is unstable") + feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_impl_trait, + span, + &format!("`impl Trait` is not allowed in {}s", ccx.const_kind()), + ) } } diff --git a/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs index a6bfa0c7409..87906e83ed5 100644 --- a/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs @@ -1,6 +1,7 @@ //! A pass that eliminates branches on uninhabited enum variants. use crate::transform::MirPass; +use rustc_data_structures::stable_set::FxHashSet; use rustc_middle::mir::{ BasicBlock, BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, TerminatorKind, }; @@ -52,9 +53,13 @@ fn variant_discriminants<'tcx>( layout: &TyAndLayout<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, -) -> Vec<u128> { +) -> FxHashSet<u128> { match &layout.variants { - Variants::Single { index } => vec![index.as_u32() as u128], + Variants::Single { index } => { + let mut res = FxHashSet::default(); + res.insert(index.as_u32() as u128); + res + } Variants::Multiple { variants, .. } => variants .iter_enumerated() .filter_map(|(idx, layout)| { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6309b00f5f5..a2184c00a28 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -359,6 +359,7 @@ symbols! { const_fn_union, const_generics, const_if_match, + const_impl_trait, const_in_array_repeat_expressions, const_indexing, const_let, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 49cec162762..3aa68aa1d8d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -83,6 +83,7 @@ #![feature(const_fn)] #![feature(const_fn_union)] #![feature(const_assume)] +#![cfg_attr(not(bootstrap), feature(const_impl_trait))] #![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))] #![cfg_attr(not(bootstrap), feature(const_fn_fn_ptr_basics))] #![feature(const_generics)] diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 793cbf99495..24f955a70b6 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -10,6 +10,7 @@ use crate::intrinsics::{assume, exact_div, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess}; use crate::marker::{PhantomData, Send, Sized, Sync}; use crate::mem; +use crate::num::NonZeroUsize; use crate::ptr::NonNull; use super::{from_raw_parts, from_raw_parts_mut}; @@ -1187,12 +1188,12 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } #[stable(feature = "rust1", since = "1.0.0")] pub struct Windows<'a, T: 'a> { v: &'a [T], - size: usize, + size: NonZeroUsize, } impl<'a, T: 'a> Windows<'a, T> { #[inline] - pub(super) fn new(slice: &'a [T], size: usize) -> Self { + pub(super) fn new(slice: &'a [T], size: NonZeroUsize) -> Self { Self { v: slice, size } } } @@ -1211,10 +1212,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn next(&mut self) -> Option<&'a [T]> { - if self.size > self.v.len() { + if self.size.get() > self.v.len() { None } else { - let ret = Some(&self.v[..self.size]); + let ret = Some(&self.v[..self.size.get()]); self.v = &self.v[1..]; ret } @@ -1222,10 +1223,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - if self.size > self.v.len() { + if self.size.get() > self.v.len() { (0, Some(0)) } else { - let size = self.v.len() - self.size + 1; + let size = self.v.len() - self.size.get() + 1; (size, Some(size)) } } @@ -1237,7 +1238,7 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn nth(&mut self, n: usize) -> Option<Self::Item> { - let (end, overflow) = self.size.overflowing_add(n); + let (end, overflow) = self.size.get().overflowing_add(n); if end > self.v.len() || overflow { self.v = &[]; None @@ -1250,10 +1251,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn last(self) -> Option<Self::Item> { - if self.size > self.v.len() { + if self.size.get() > self.v.len() { None } else { - let start = self.v.len() - self.size; + let start = self.v.len() - self.size.get(); Some(&self.v[start..]) } } @@ -1264,7 +1265,7 @@ impl<'a, T> Iterator for Windows<'a, T> { // which means that `i` cannot overflow an `isize`, and the // slice created by `from_raw_parts` is a subslice of `self.v` // thus is guaranteed to be valid for the lifetime `'a` of `self.v`. - unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size) } + unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) } } } @@ -1272,10 +1273,10 @@ impl<'a, T> Iterator for Windows<'a, T> { impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { - if self.size > self.v.len() { + if self.size.get() > self.v.len() { None } else { - let ret = Some(&self.v[self.v.len() - self.size..]); + let ret = Some(&self.v[self.v.len() - self.size.get()..]); self.v = &self.v[..self.v.len() - 1]; ret } @@ -1284,11 +1285,11 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[inline] fn nth_back(&mut self, n: usize) -> Option<Self::Item> { let (end, overflow) = self.v.len().overflowing_sub(n); - if end < self.size || overflow { + if end < self.size.get() || overflow { self.v = &[]; None } else { - let ret = &self.v[end - self.size..end]; + let ret = &self.v[end - self.size.get()..end]; self.v = &self.v[..end - 1]; Some(ret) } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 9373c6feccd..73d085c3fb2 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -11,6 +11,7 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::marker::Copy; use crate::mem; +use crate::num::NonZeroUsize; use crate::ops::{FnMut, Range, RangeBounds}; use crate::option::Option; use crate::option::Option::{None, Some}; @@ -751,7 +752,7 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn windows(&self, size: usize) -> Windows<'_, T> { - assert_ne!(size, 0); + let size = NonZeroUsize::new(size).expect("size is zero"); Windows::new(self, size) } diff --git a/src/test/codegen/slice-windows-no-bounds-check.rs b/src/test/codegen/slice-windows-no-bounds-check.rs new file mode 100644 index 00000000000..4f5f4425c27 --- /dev/null +++ b/src/test/codegen/slice-windows-no-bounds-check.rs @@ -0,0 +1,35 @@ +#![crate_type = "lib"] + +// compile-flags: -O + +use std::slice::Windows; + +// CHECK-LABEL: @naive_string_search +#[no_mangle] +pub fn naive_string_search(haystack: &str, needle: &str) -> Option<usize> { + if needle.is_empty() { + return Some(0); + } + // CHECK-NOT: panic + // CHECK-NOT: fail + haystack + .as_bytes() + .windows(needle.len()) + .position(|sub| sub == needle.as_bytes()) +} + +// CHECK-LABEL: @next +#[no_mangle] +pub fn next<'a>(w: &mut Windows<'a, u32>) -> Option<&'a [u32]> { + // CHECK-NOT: panic + // CHECK-NOT: fail + w.next() +} + +// CHECK-LABEL: @next_back +#[no_mangle] +pub fn next_back<'a>(w: &mut Windows<'a, u32>) -> Option<&'a [u32]> { + // CHECK-NOT: panic + // CHECK-NOT: fail + w.next_back() +} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.rs b/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.rs index 9cc9b69ac0b..e062c9f0aa3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.rs @@ -1,9 +1,10 @@ +// gate-test-const_impl_trait + struct AlanTuring<T>(T); -const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { - //~^ ERROR `impl Trait` in const fn is unstable +const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { //~ `impl Trait` AlanTuring(0) } -const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable +const fn no_rpit() -> impl std::fmt::Debug {} //~ `impl Trait` fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.stderr index a62a340332d..01c797cd96b 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_impl_trait.stderr @@ -1,21 +1,21 @@ -error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn_impl_trait.rs:2:24 +error[E0658]: `impl Trait` is not allowed in constant functions + --> $DIR/min_const_fn_impl_trait.rs:4:24 | LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information - = help: add `#![feature(const_fn)]` to the crate attributes to enable + = note: see issue #77463 <https://github.com/rust-lang/rust/issues/77463> for more information + = help: add `#![feature(const_impl_trait)]` to the crate attributes to enable -error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn_impl_trait.rs:7:23 +error[E0658]: `impl Trait` is not allowed in constant functions + --> $DIR/min_const_fn_impl_trait.rs:8:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} | ^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information - = help: add `#![feature(const_fn)]` to the crate attributes to enable + = note: see issue #77463 <https://github.com/rust-lang/rust/issues/77463> for more information + = help: add `#![feature(const_impl_trait)]` to the crate attributes to enable error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0723`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.rs b/src/test/ui/type-alias-impl-trait/issue-53096.rs index bdf426bbd37..6e1973bd18a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53096.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53096.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(const_fn, const_fn_fn_ptr_basics)] +#![feature(const_impl_trait, const_fn_fn_ptr_basics)] #![feature(type_alias_impl_trait)] type Foo = impl Fn() -> usize; diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs index e7f93732430..4582d5386f0 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(const_fn, generators, generator_trait, type_alias_impl_trait)] +#![feature(const_impl_trait, generators, generator_trait, type_alias_impl_trait)] use std::ops::Generator; diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs index d50835608fa..58f0f5b2f65 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -1,4 +1,4 @@ -#![feature(const_fn, type_alias_impl_trait)] +#![feature(const_impl_trait, type_alias_impl_trait)] type Bar = impl Send; diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs index a3ff4ad1d47..74ffa608426 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match.rs @@ -1,4 +1,4 @@ -#![feature(const_fn, type_alias_impl_trait)] +#![feature(const_impl_trait, type_alias_impl_trait)] type Foo = impl Send; |
