diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index a7e019a53ee13..32c02033dc9b9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,5 +1,6 @@ use crate::infer::type_variable::TypeVariableOriginKind; use crate::infer::InferCtxt; +use crate::rustc_middle::ty::TypeFoldable; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; @@ -400,36 +401,75 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } GenericArgKind::Const(ct) => { - if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val { - let origin = - self.inner.borrow_mut().const_unification_table().probe_value(vid).origin; - if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = - origin.kind - { - return InferenceDiagnosticsData { - name: name.to_string(), + match ct.val { + ty::ConstKind::Infer(InferConst::Var(vid)) => { + let origin = self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .origin; + if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = + origin.kind + { + return InferenceDiagnosticsData { + name: name.to_string(), + span: Some(origin.span), + kind: UnderspecifiedArgKind::Const { is_parameter: true }, + parent: InferenceDiagnosticsParentData::for_def_id( + self.tcx, def_id, + ), + }; + } + + debug_assert!(!origin.span.is_dummy()); + let mut s = String::new(); + let mut printer = + ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS); + if let Some(highlight) = highlight { + printer.region_highlight_mode = highlight; + } + let _ = ct.print(printer); + InferenceDiagnosticsData { + name: s, span: Some(origin.span), - kind: UnderspecifiedArgKind::Const { is_parameter: true }, - parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), - }; + kind: UnderspecifiedArgKind::Const { is_parameter: false }, + parent: None, + } } - - debug_assert!(!origin.span.is_dummy()); - let mut s = String::new(); - let mut printer = - ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS); - if let Some(highlight) = highlight { - printer.region_highlight_mode = highlight; + ty::ConstKind::Unevaluated(ty::Unevaluated { + substs_: Some(substs), .. + }) => { + assert!(substs.has_infer_types_or_consts()); + + // FIXME: We only use the first inference variable we encounter in + // `substs` here, this gives insufficiently informative diagnostics + // in case there are multiple inference variables + for s in substs.iter() { + match s.unpack() { + GenericArgKind::Type(t) => match t.kind() { + ty::Infer(_) => { + return self.extract_inference_diagnostics_data(s, None); + } + _ => {} + }, + GenericArgKind::Const(c) => match c.val { + ty::ConstKind::Infer(InferConst::Var(_)) => { + return self.extract_inference_diagnostics_data(s, None); + } + _ => {} + }, + _ => {} + } + } + bug!( + "expected an inference variable in substs of unevaluated const {:?}", + ct + ); } - let _ = ct.print(printer); - InferenceDiagnosticsData { - name: s, - span: Some(origin.span), - kind: UnderspecifiedArgKind::Const { is_parameter: false }, - parent: None, + _ => { + bug!("unexpect const: {:?}", ct); } - } else { - bug!("unexpect const: {:?}", ct); } } GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2fd01c2d595fa..48dfa0b6342d9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -21,6 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::EvalToConstValueResult; use rustc_middle::traits::select; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -1584,13 +1585,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { unevaluated: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - let mut original_values = OriginalQueryValues::default(); - let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values); + let mut substs = unevaluated.substs(self.tcx); + substs = self.resolve_vars_if_possible(substs); + + // Postpone the evaluation of constants whose substs depend on inference + // variables + if substs.has_infer_types_or_consts() { + return Err(ErrorHandled::TooGeneric); + } + + let param_env_erased = self.tcx.erase_regions(param_env); + let substs_erased = self.tcx.erase_regions(substs); + + let unevaluated = ty::Unevaluated { + def: unevaluated.def, + substs_: Some(substs_erased), + promoted: unevaluated.promoted, + }; - let (param_env, unevaluated) = canonical.value; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. - self.tcx.const_eval_resolve(param_env, unevaluated, span) + self.tcx.const_eval_resolve(param_env_erased, unevaluated, span) } /// If `typ` is a type variable of some kind, resolve it one level diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index b67ad8b770ea1..66d1ae1420a14 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -51,7 +51,6 @@ #![feature(control_flow_enum)] #![feature(associated_type_defaults)] #![feature(iter_zip)] -#![feature(thread_local_const_init)] #![feature(trusted_step)] #![feature(try_blocks)] #![feature(try_reserve_kind)] diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index a9ab2cd3f68ef..07887a7a59c1d 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -92,6 +92,19 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; let param = self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { + if this.eat_keyword_noexpect(kw::SelfUpper) { + // `Self` as a generic param is invalid. Here we emit the diagnostic and continue parsing + // as if `Self` never existed. + this.struct_span_err( + this.prev_token.span, + "unexpected keyword `Self` in generic parameters", + ) + .note("you cannot use `Self` as a generic parameter because it is reserved for associated items") + .emit(); + + this.eat(&token::Comma); + } + let param = if this.check_lifetime() { let lifetime = this.expect_lifetime(); // Parse lifetime parameter. diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index b1295ba48ccb9..0da141f6836f6 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -5,7 +5,6 @@ #![feature(iter_zip)] #![feature(let_else)] #![feature(min_specialization)] -#![feature(thread_local_const_init)] #![feature(extern_types)] #[macro_use] diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 98478cf5dec69..ea3d3363b8065 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -20,7 +20,6 @@ #![feature(negative_impls)] #![feature(nll)] #![feature(min_specialization)] -#![feature(thread_local_const_init)] #[macro_use] extern crate rustc_macros; diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 00862615c3c7a..42eae6a54b531 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2148,6 +2148,37 @@ impl VecDeque { pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool, + { + self.retain_mut(|elem| f(elem)); + } + + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` such that `f(&e)` returns false. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_retain_mut)] + /// + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::new(); + /// buf.extend(1..5); + /// buf.retain_mut(|x| if *x % 2 == 0 { + /// *x += 1; + /// true + /// } else { + /// false + /// }); + /// assert_eq!(buf, [3, 5]); + /// ``` + #[unstable(feature = "vec_retain_mut", issue = "90829")] + pub fn retain_mut(&mut self, mut f: F) + where + F: FnMut(&mut T) -> bool, { let len = self.len(); let mut idx = 0; @@ -2155,7 +2186,7 @@ impl VecDeque { // Stage 1: All values are retained. while cur < len { - if !f(&self[cur]) { + if !f(&mut self[cur]) { cur += 1; break; } @@ -2164,7 +2195,7 @@ impl VecDeque { } // Stage 2: Swap retained value into current idx. while cur < len { - if !f(&self[cur]) { + if !f(&mut self[cur]) { cur += 1; continue; } @@ -2173,7 +2204,7 @@ impl VecDeque { cur += 1; idx += 1; } - // Stage 3: Trancate all values after idx. + // Stage 3: Truncate all values after idx. if cur != idx { self.truncate(idx); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 41b94cb294cfe..67846e7883570 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -216,10 +216,7 @@ // std may use features in a platform-specific way #![allow(unused_features)] #![feature(rustc_allow_const_fn_unstable)] -#![cfg_attr( - test, - feature(internal_output_capture, print_internals, update_panic_count, thread_local_const_init) -)] +#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))] #![cfg_attr( all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform) diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index e48b589f7d8f5..8a028d99306db 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -473,10 +473,7 @@ impl Iterator for Env { #[cfg(target_os = "macos")] pub unsafe fn environ() -> *mut *const *const c_char { - extern "C" { - fn _NSGetEnviron() -> *mut *const *const c_char; - } - _NSGetEnviron() + libc::_NSGetEnviron() as *mut *const *const c_char } #[cfg(not(target_os = "macos"))] diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 64c8416b61c79..c03fe116320aa 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -178,7 +178,6 @@ macro_rules! __thread_local_inner { (@key $t:ty, const $init:expr) => {{ #[cfg_attr(not(windows), inline)] // see comments below unsafe fn __getit() -> $crate::option::Option<&'static $t> { - const _REQUIRE_UNSTABLE: () = $crate::thread::require_unstable_const_init_thread_local(); const INIT_EXPR: $t = $init; // wasm without atomics maps directly to `static mut`, and dtors diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 343d3ef8dc538..64f6c7fa022fc 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -204,13 +204,6 @@ pub use self::local::os::Key as __OsLocalKeyInner; #[doc(hidden)] pub use self::local::statik::Key as __StaticLocalKeyInner; -// This is only used to make thread locals with `const { .. }` initialization -// expressions unstable. If and/or when that syntax is stabilized with thread -// locals this will simply be removed. -#[doc(hidden)] -#[unstable(feature = "thread_local_const_init", issue = "84223")] -pub const fn require_unstable_const_init_thread_local() {} - //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// diff --git a/src/llvm-project b/src/llvm-project index 01c8b654f9a01..2b9078f4afae8 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 01c8b654f9a01371414d1fd69cba38b289510a9e +Subproject commit 2b9078f4afae82f60c5ac0fdb4af42d269e2f2f3 diff --git a/src/test/codegen/auxiliary/thread_local_aux.rs b/src/test/codegen/auxiliary/thread_local_aux.rs index 29b5e3ca244bf..bebaa7754dd5a 100644 --- a/src/test/codegen/auxiliary/thread_local_aux.rs +++ b/src/test/codegen/auxiliary/thread_local_aux.rs @@ -1,5 +1,4 @@ #![crate_type = "lib"] -#![feature(thread_local_const_init)] use std::cell::Cell; diff --git a/src/test/codegen/thread-local.rs b/src/test/codegen/thread-local.rs index f14368e39902d..5ac30d949fa4e 100644 --- a/src/test/codegen/thread-local.rs +++ b/src/test/codegen/thread-local.rs @@ -6,7 +6,6 @@ // ignore-android does not use #[thread_local] #![crate_type = "lib"] -#![feature(thread_local_const_init)] extern crate thread_local_aux as aux; diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs index b79bc262d2bac..18f33acaabbba 100644 --- a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs +++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs @@ -1,4 +1,3 @@ -// run-pass #![feature(generic_const_exprs)] #![allow(incomplete_features)] @@ -22,8 +21,11 @@ where } fn main() { - // Test that we can correctly infer `T` which requires evaluating - // `{ N + 1 }` which has substs containing an inference var + // FIXME(generic_const_exprs): We can't correctly infer `T` which requires + // evaluating `{ N + 1 }` which has substs containing an inference var let mut _q = Default::default(); + //~^ ERROR type annotations needed + _q = foo::<_, 2>(_q); + //~^ ERROR type annotations needed } diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr new file mode 100644 index 0000000000000..e59f1ac8027de --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr @@ -0,0 +1,33 @@ +error[E0282]: type annotations needed + --> $DIR/const_eval_resolve_canonical.rs:26:9 + | +LL | let mut _q = Default::default(); + | ^^^^^^ consider giving `_q` a type + +error[E0283]: type annotations needed + --> $DIR/const_eval_resolve_canonical.rs:29:10 + | +LL | _q = foo::<_, 2>(_q); + | ^^^^^^^^^^^ cannot infer type + | +note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found + --> $DIR/const_eval_resolve_canonical.rs:8:1 + | +LL | impl Foo<0> for () { + | ^^^^^^^^^^^^^^^^^^ +... +LL | impl Foo<3> for () { + | ^^^^^^^^^^^^^^^^^^ +note: required by a bound in `foo` + --> $DIR/const_eval_resolve_canonical.rs:18:9 + | +LL | fn foo(_: T) -> <() as Foo<{ N + 1 }>>::Assoc + | --- required by a bound in this +LL | where +LL | (): Foo<{ N + 1 }>, + | ^^^^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/issues/issue-83249.rs b/src/test/ui/const-generics/issues/issue-83249.rs new file mode 100644 index 0000000000000..65148c55ee541 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-83249.rs @@ -0,0 +1,23 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +trait Foo { + const N: usize; +} + +impl Foo for u8 { + const N: usize = 1; +} + +fn foo(_: [u8; T::N]) -> T { + todo!() +} + +pub fn bar() { + let _: u8 = foo([0; 1]); + + let _ = foo([0; 1]); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr new file mode 100644 index 0000000000000..402b3aa2d61dc --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed + --> $DIR/issue-83249.rs:19:13 + | +LL | let _ = foo([0; 1]); + | - ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | | + | consider giving this pattern a type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/issues/issue-83288.rs b/src/test/ui/const-generics/issues/issue-83288.rs new file mode 100644 index 0000000000000..a24596d242e0d --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-83288.rs @@ -0,0 +1,69 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +use std::{marker::PhantomData, ops::Mul}; + +pub enum Nil {} +pub struct Cons { + _phantom: PhantomData<(T, L)>, +} + +pub trait Indices { + const RANK: usize; + const NUM_ELEMS: usize; +} + +impl Indices for Nil { + const RANK: usize = 0; + const NUM_ELEMS: usize = 1; +} + +impl, const N: usize> Indices for Cons { + const RANK: usize = I::RANK + 1; + const NUM_ELEMS: usize = I::NUM_ELEMS * N; +} + +pub trait Concat { + type Output; +} + +impl Concat for Nil { + type Output = J; +} + +impl Concat for Cons +where + I: Concat, +{ + type Output = Cons>::Output>; +} + +pub struct Tensor, const N: usize> +where + [u8; I::NUM_ELEMS]: Sized, +{ + pub data: [u8; I::NUM_ELEMS], + _phantom: PhantomData, +} + +impl, J: Indices, const N: usize> Mul> for Tensor +where + I: Concat, + >::Output: Indices, + [u8; I::NUM_ELEMS]: Sized, + [u8; J::NUM_ELEMS]: Sized, + [u8; >::Output::NUM_ELEMS]: Sized, +{ + type Output = Tensor<>::Output, N>; + + fn mul(self, _rhs: Tensor) -> Self::Output { + Tensor { + data: [0u8; >::Output::NUM_ELEMS], + _phantom: PhantomData, + } + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-87470.rs b/src/test/ui/const-generics/issues/issue-87470.rs new file mode 100644 index 0000000000000..d60181a418a15 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-87470.rs @@ -0,0 +1,24 @@ +// build-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub trait TraitWithConst { + const SOME_CONST: usize; +} + +pub trait OtherTrait: TraitWithConst { + fn some_fn(self) -> [u8 ; ::SOME_CONST]; +} + +impl TraitWithConst for f32 { + const SOME_CONST: usize = 32; +} + +impl OtherTrait for f32 { + fn some_fn(self) -> [u8 ; ::SOME_CONST] { + [0; 32] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-87964.rs b/src/test/ui/const-generics/issues/issue-87964.rs new file mode 100644 index 0000000000000..116686abb9e3d --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-87964.rs @@ -0,0 +1,29 @@ +// build-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub trait Target { + const LENGTH: usize; +} + + +pub struct Container +where + [(); T::LENGTH]: Sized, +{ + _target: T, +} + +impl Container +where + [(); T::LENGTH]: Sized, +{ + pub fn start( + _target: T, + ) -> Container { + Container { _target } + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-89146.rs b/src/test/ui/const-generics/issues/issue-89146.rs new file mode 100644 index 0000000000000..e3540f46f1e81 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-89146.rs @@ -0,0 +1,26 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +pub trait Foo { + const SIZE: usize; + + fn to_bytes(&self) -> [u8; Self::SIZE]; +} + +pub fn bar(a: &G) -> u8 +where + [(); G::SIZE]: Sized, +{ + deeper_bar(a) +} + +fn deeper_bar(a: &G) -> u8 +where + [(); G::SIZE]: Sized, +{ + a.to_bytes()[0] +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-89320.rs b/src/test/ui/const-generics/issues/issue-89320.rs new file mode 100644 index 0000000000000..afa5c8fab74e8 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-89320.rs @@ -0,0 +1,19 @@ +// build-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub trait Enumerable { + const N: usize; +} + +#[derive(Clone)] +pub struct SymmetricGroup +where + S: Enumerable, + [(); S::N]: Sized, +{ + _phantom: std::marker::PhantomData, +} + +fn main() {} diff --git a/src/test/ui/feature-gates/thread-local-const-init.rs b/src/test/ui/feature-gates/thread-local-const-init.rs deleted file mode 100644 index 6584ffa7cf949..0000000000000 --- a/src/test/ui/feature-gates/thread-local-const-init.rs +++ /dev/null @@ -1,4 +0,0 @@ -thread_local!(static X: u32 = const { 0 }); -//~^ ERROR: use of unstable library feature 'thread_local_const_init' - -fn main() {} diff --git a/src/test/ui/feature-gates/thread-local-const-init.stderr b/src/test/ui/feature-gates/thread-local-const-init.stderr deleted file mode 100644 index f80506831b4e8..0000000000000 --- a/src/test/ui/feature-gates/thread-local-const-init.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: use of unstable library feature 'thread_local_const_init' - --> $DIR/thread-local-const-init.rs:1:1 - | -LL | thread_local!(static X: u32 = const { 0 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #84223 for more information - = help: add `#![feature(thread_local_const_init)]` to the crate attributes to enable - = note: this error originates in the macro `$crate::__thread_local_inner` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/keyword/keyword-self-as-type-param.rs b/src/test/ui/keyword/keyword-self-as-type-param.rs index 785d64ec8ea22..55c7ac128ffde 100644 --- a/src/test/ui/keyword/keyword-self-as-type-param.rs +++ b/src/test/ui/keyword/keyword-self-as-type-param.rs @@ -1,10 +1,10 @@ // Regression test of #36638. struct Foo(Self); -//~^ ERROR expected identifier, found keyword `Self` -//~^^ ERROR E0392 +//~^ ERROR unexpected keyword `Self` in generic parameters +//~| ERROR recursive type `Foo` has infinite size trait Bar {} -//~^ ERROR expected identifier, found keyword `Self` +//~^ ERROR unexpected keyword `Self` in generic parameters fn main() {} diff --git a/src/test/ui/keyword/keyword-self-as-type-param.stderr b/src/test/ui/keyword/keyword-self-as-type-param.stderr index cc3df2e36f7f5..fd101b32b4c9c 100644 --- a/src/test/ui/keyword/keyword-self-as-type-param.stderr +++ b/src/test/ui/keyword/keyword-self-as-type-param.stderr @@ -1,24 +1,33 @@ -error: expected identifier, found keyword `Self` +error: unexpected keyword `Self` in generic parameters --> $DIR/keyword-self-as-type-param.rs:3:12 | LL | struct Foo(Self); - | ^^^^ expected identifier, found keyword + | ^^^^ + | + = note: you cannot use `Self` as a generic parameter because it is reserved for associated items -error: expected identifier, found keyword `Self` +error: unexpected keyword `Self` in generic parameters --> $DIR/keyword-self-as-type-param.rs:7:11 | LL | trait Bar {} - | ^^^^ expected identifier, found keyword + | ^^^^ + | + = note: you cannot use `Self` as a generic parameter because it is reserved for associated items -error[E0392]: parameter `Self` is never used - --> $DIR/keyword-self-as-type-param.rs:3:12 +error[E0072]: recursive type `Foo` has infinite size + --> $DIR/keyword-self-as-type-param.rs:3:1 | LL | struct Foo(Self); - | ^^^^ unused parameter + | ^^^^^^^^^^^^^^^^^----^^ + | | | + | | recursive without indirection + | recursive type has infinite size + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | - = help: consider removing `Self`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `Self` to be a const parameter, use `const Self: usize` instead +LL | struct Foo(Box); + | ++++ + error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0072`.