diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 591abdaa26839..c2960cd271564 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3237,6 +3237,13 @@ impl FnRetTy { FnRetTy::Ty(ty) => ty.span, } } + + pub fn as_non_default(&self) -> Option<&Ty> { + match self { + Self::Default(_) => None, + Self::Ty(ty) => Some(&*ty), + } + } } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)] @@ -3872,7 +3879,7 @@ pub struct ConstItem { pub defaultness: Defaultness, pub ident: Ident, pub generics: Generics, - pub ty: Box, + pub ty: FnRetTy, pub rhs: Option, pub define_opaque: Option>, } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 2e494b968b6bd..1ccb836587729 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -314,10 +314,7 @@ fn path_return_type(path: &ast::Path) -> Option<&ast::Ty> { let last_segment = path.segments.last()?; let args = last_segment.args.as_ref()?; match &**args { - ast::GenericArgs::Parenthesized(args) => match &args.output { - ast::FnRetTy::Default(_) => None, - ast::FnRetTy::Ty(ret) => Some(ret), - }, + ast::GenericArgs::Parenthesized(args) => args.output.as_non_default(), ast::GenericArgs::AngleBracketed(_) | ast::GenericArgs::ParenthesizedElided(_) => None, } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b497c6beeb984..62bb345b56ec2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -297,7 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> { id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this.lower_ty_alloc( + let ty = this.lower_fn_ret_ty_or_unit( ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); @@ -942,7 +942,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this.lower_ty_alloc( + let ty = this.lower_fn_ret_ty_or_unit( ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); @@ -1156,7 +1156,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this.lower_ty_alloc( + let ty = this.lower_fn_ret_ty_or_unit( ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8c6ee9d6bc630..d03787ee8ba0b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1833,6 +1833,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::FnRetTy::Return(self.arena.alloc(opaque_ty)) } + fn lower_fn_ret_ty_or_unit( + &mut self, + fn_ret_ty: &FnRetTy, + ictxt: ImplTraitContext, + ) -> &'hir hir::Ty<'hir> { + match fn_ret_ty { + FnRetTy::Ty(ty) => self.lower_ty_alloc(ty, ictxt), + FnRetTy::Default(span) => self.arena.alloc(self.ty_tup(*span, &[])), + } + } + /// Transforms `-> T` into `Future`. fn lower_coroutine_fn_output_type_to_bound( &mut self, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 6376cab364db1..7ed34627ba206 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -506,6 +506,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(generic_const_items, "generic const items are experimental"); gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards"); gate_all!(default_field_values, "default values on fields are experimental"); + gate_all!( + const_items_unit_type_default, + "omitting type on const item declaration is experimental", + "consider specifying the type explicitly" + ); gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); gate_all!(postfix_match, "postfix match is experimental"); gate_all!(mut_ref, "mutable by-reference bindings are experimental"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 68054b06e39ff..240b9e89d8980 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -47,7 +47,7 @@ impl<'a> State<'a> { *ident, Some(*mutability), &ast::Generics::default(), - ty, + Some(ty), expr.as_deref(), vis, *safety, @@ -87,7 +87,7 @@ impl<'a> State<'a> { ident: Ident, mutbl: Option, generics: &ast::Generics, - ty: &ast::Ty, + ty: Option<&ast::Ty>, body: Option<&ast::Expr>, vis: &ast::Visibility, safety: ast::Safety, @@ -107,8 +107,10 @@ impl<'a> State<'a> { self.word_space(leading); self.print_ident(ident); self.print_generic_params(&generics.params); - self.word_space(":"); - self.print_type(ty); + if let Some(ty) = ty { + self.word_space(":"); + self.print_type(ty); + } if body.is_some() { self.space(); } @@ -197,7 +199,7 @@ impl<'a> State<'a> { *ident, Some(*mutbl), &ast::Generics::default(), - ty, + Some(ty), body.as_deref(), &item.vis, ast::Safety::Default, @@ -228,7 +230,7 @@ impl<'a> State<'a> { *ident, None, generics, - ty, + ty.as_non_default(), rhs.as_ref().map(|ct| ct.expr()), &item.vis, ast::Safety::Default, @@ -580,7 +582,7 @@ impl<'a> State<'a> { *ident, None, generics, - ty, + ty.as_non_default(), rhs.as_ref().map(|ct| ct.expr()), vis, ast::Safety::Default, diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 12ccc4a6de043..acf58d068fa92 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -4,7 +4,7 @@ use rustc_ast::{ }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, kw, sym}; -use thin_vec::{ThinVec, thin_vec}; +use thin_vec::thin_vec; use crate::errors; use crate::util::check_builtin_macro_attribute; @@ -42,9 +42,14 @@ pub(crate) fn expand( let stmts = thin_vec![generate_handler(ecx, ident, span, sig_span)]; // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); + let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); - let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); + let const_item = ecx.item_const( + span, + Ident::new(kw::Underscore, span), + ast::FnRetTy::Default(sig_span), + const_body, + ); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) } else { @@ -90,7 +95,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span contract: None, body, define_opaque: None, - eii_impls: ThinVec::new(), + eii_impls: thin_vec![], })); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 538f5afae5fc4..0615903904f46 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -231,7 +231,7 @@ fn generate_default_impl( ecx.item_const( span, underscore, - unit, + ast::FnRetTy::Ty(unit), ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))), ) }; diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index bb031dafdcfd5..bb036e2d1266e 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -46,9 +46,13 @@ pub(crate) fn expand( let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect(); // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); - let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); + let const_item = ecx.item_const( + span, + Ident::new(kw::Underscore, span), + ast::FnRetTy::Default(ty_span), + const_body, + ); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) } else { diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index e30d506a31b9e..fa1e815fcb87a 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -389,12 +389,8 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), )); - let anon_constant = cx.item_const( - span, - Ident::new(kw::Underscore, span), - cx.ty(span, ast::TyKind::Tup(ThinVec::new())), - block, - ); + let anon_constant = + cx.item_const(span, Ident::new(kw::Underscore, span), ast::FnRetTy::Default(span), block); // Integrate the new item into existing module structures. let items = AstFragment::Items(smallvec![anon_constant]); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index d5f774865a9e1..afa7d2392986f 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -286,7 +286,9 @@ pub(crate) fn expand_test_or_bench( defaultness: ast::Defaultness::Final, ident: Ident::new(fn_.ident.name, sp), generics: ast::Generics::default(), - ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), + ty: ast::FnRetTy::Ty( + cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), + ), define_opaque: None, // test::TestDescAndFn { rhs: Some(ast::ConstItemRhs::Body( diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index e5c06889f3e06..17d9c21ec4b3a 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -726,7 +726,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, ident: Ident, - ty: Box, + ty: ast::FnRetTy, rhs: ast::ConstItemRhs, ) -> Box { let defaultness = ast::Defaultness::Final; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 22db43b7ee644..f04c00038d28d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -422,6 +422,8 @@ declare_features! ( (unstable, const_destruct, "1.85.0", Some(133214)), /// Allows `for _ in _` loops in const contexts. (unstable, const_for, "1.56.0", Some(87575)), + /// Allows to omit `: ()` type in `const FOO: () = ...` similarly to `-> ()` in functions. + (unstable, const_items_unit_type_default, "CURRENT_RUSTC_VERSION", Some(149226)), /// Be more precise when looking for live drops in a const context. (unstable, const_precise_live_drops, "1.46.0", Some(73255)), /// Allows `impl const Trait for T` syntax. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4c1bcffa1cf4c..cbfd68a868e6b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1372,6 +1372,7 @@ impl AttributeExt for Attribute { Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span, Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) => cfgs[0].1, + Attribute::Parsed(AttributeKind::Coroutine(span)) => *span, a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), } } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6b61504f23273..5ca5f032e4193 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1118,7 +1118,7 @@ impl<'a> Parser<'a> { defaultness: Defaultness::Final, ident, generics: Generics::default(), - ty, + ty: FnRetTy::Ty(ty), rhs, define_opaque, })) @@ -1369,7 +1369,12 @@ impl<'a> Parser<'a> { }); ForeignItemKind::Static(Box::new(StaticItem { ident, - ty, + ty: match ty { + FnRetTy::Default(span) => { + Self::default_ty_for_static_items(span) + } + FnRetTy::Ty(ty) => ty, + }, mutability: Mutability::Not, expr: rhs.map(|b| match b { ConstItemRhs::TypeConst(anon_const) => anon_const.value, @@ -1479,6 +1484,10 @@ impl<'a> Parser<'a> { Ok(ConstBlockItem { id: DUMMY_NODE_ID, span: const_span.to(block.span), block }) } + fn default_ty_for_static_items(span: Span) -> Box { + Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None }) + } + /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in /// `mutability`. /// @@ -1497,13 +1506,29 @@ impl<'a> Parser<'a> { self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span }); } - // Parse the type of a static item. That is, the `":" $ty` fragment. - // FIXME: This could maybe benefit from `.may_recover()`? - let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) { - (true, false) => self.parse_ty()?, - // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing - // type. - (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)), + let ty = match self.parse_global_item_type(false)? { + Ok(ty) => ty, + Err((span, colon_present)) => { + // Construct the error and stash it away with the hope + // that typeck will later enrich the error with a type. + self.dcx() + .create_err(errors::MissingConstType { + span, + colon: match colon_present { + true => "", + false => ":", + }, + kind: match mutability { + Mutability::Mut => "static mut", + Mutability::Not => "static", + }, + }) + .stash(span, StashKey::ItemNoType); + + // The user intended that the type be inferred, + // so treat this as if the user wrote e.g. `static A: _ = expr;`. + Self::default_ty_for_static_items(span) + } }; let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None }; @@ -1522,7 +1547,7 @@ impl<'a> Parser<'a> { fn parse_const_item( &mut self, attrs: &[Attribute], - ) -> PResult<'a, (Ident, Generics, Box, Option)> { + ) -> PResult<'a, (Ident, Generics, FnRetTy, Option)> { let ident = self.parse_ident_or_underscore()?; let mut generics = self.parse_generics()?; @@ -1533,15 +1558,12 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::generic_const_items, generics.span); } - // Parse the type of a constant item. That is, the `":" $ty` fragment. - // FIXME: This could maybe benefit from `.may_recover()`? - let ty = match ( - self.eat(exp!(Colon)), - self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)), - ) { - (true, false) => self.parse_ty()?, - // If there wasn't a `:` or the colon was followed by a `=`, `;` or `where`, recover a missing type. - (colon, _) => self.recover_missing_global_item_type(colon, None), + let ty = match self.parse_global_item_type(true)? { + Ok(ty) => FnRetTy::Ty(ty), + Err((span, _)) => { + self.psess.gated_spans.gate(sym::const_items_unit_type_default, span); + FnRetTy::Default(span) + } }; // Proactively parse a where-clause to be able to provide a good error message in case we @@ -1617,33 +1639,24 @@ impl<'a> Parser<'a> { Ok((ident, generics, ty, rhs)) } - /// We were supposed to parse `":" $ty` but the `:` or the type was missing. - /// This means that the type is missing. - fn recover_missing_global_item_type( + // Parse the type of a constant item. That is, the `":" $ty` fragment. + // FIXME: This could maybe benefit from `.may_recover()`? + fn parse_global_item_type( &mut self, - colon_present: bool, - m: Option, - ) -> Box { - // Construct the error and stash it away with the hope - // that typeck will later enrich the error with a type. - let kind = match m { - Some(Mutability::Mut) => "static mut", - Some(Mutability::Not) => "static", - None => "const", - }; - - let colon = match colon_present { - true => "", - false => ":", - }; - - let span = self.prev_token.span.shrink_to_hi(); - let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind }); - err.stash(span, StashKey::ItemNoType); - - // The user intended that the type be inferred, - // so treat this as if the user wrote e.g. `const A: _ = expr;`. - Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None }) + allow_where: bool, + ) -> PResult<'a, Result, (Span, bool)>> { + Ok( + match ( + self.eat(exp!(Colon)), + self.check(exp!(Eq)) + | self.check(exp!(Semi)) + | (allow_where && self.check_keyword(exp!(Where))), + ) { + (true, false) => Ok(self.parse_ty()?), + // If there wasn't a `:` or the colon was followed by a `=`, `;` or `where`, recover a missing type. + (colon_present, _) => Err((self.prev_token.span.shrink_to_hi(), colon_present)), + }, + ) } /// Parses an enum declaration. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7a7261cf7b95b..1ecc3d801b385 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2878,12 +2878,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { this.with_lifetime_rib( LifetimeRibKind::ConstParamTy, - |this| this.visit_ty(ty), + |this| this.visit_fn_ret_ty(ty), ) }) }); } else { - this.visit_ty(ty); + this.visit_fn_ret_ty(ty) } }, ); @@ -3268,12 +3268,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { this.with_lifetime_rib( LifetimeRibKind::ConstParamTy, - |this| this.visit_ty(ty), + |this| this.visit_fn_ret_ty(ty), ) }) }); } else { - this.visit_ty(ty); + this.visit_fn_ret_ty(ty) } // Only impose the restrictions of `ConstRibKind` for an @@ -3519,13 +3519,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this| { this.with_lifetime_rib( LifetimeRibKind::ConstParamTy, - |this| this.visit_ty(ty), + |this| this.visit_fn_ret_ty(ty), ) }, ) }); } else { - this.visit_ty(ty); + this.visit_fn_ret_ty(ty); } if let Some(rhs) = rhs { // We allow arbitrary const expressions inside of associated consts, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 90a22c6bb67c0..b331cc3c5222c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -757,6 +757,7 @@ symbols! { const_impl_trait, const_in_array_repeat_expressions, const_indexing, + const_items_unit_type_default, const_let, const_loop, const_make_global, diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index b4e1f70d1535b..feb2cab2a0df5 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -2,7 +2,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::source::snippet; -use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind}; +use rustc_ast::ast::{ConstItem, FnRetTy, Item, ItemKind, StaticItem, Ty, TyKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; @@ -103,7 +103,9 @@ impl EarlyLintPass for RedundantStaticLifetimes { } if !item.span.from_expansion() { - if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind { + if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind + && let FnRetTy::Ty(var_type) = var_type + { Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime"); // Don't check associated consts because `'static` cannot be elided on those (issue // #2438) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index cf8716398efb3..7b86f33e86c06 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -370,7 +370,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { eq_defaultness(*ld, *rd) && eq_id(*li, *ri) && eq_generics(lg, rg) - && eq_ty(lt, rt) + && eq_fn_ret_ty(lt, rt) && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) }, ( @@ -630,7 +630,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { eq_defaultness(*ld, *rd) && eq_id(*li, *ri) && eq_generics(lg, rg) - && eq_ty(lt, rt) + && eq_fn_ret_ty(lt, rt) && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) }, ( diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index c9e32492c50b0..d411f9b3e51f9 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2005,7 +2005,7 @@ pub(crate) struct StaticParts<'a> { vis: &'a ast::Visibility, ident: symbol::Ident, generics: Option<&'a ast::Generics>, - ty: &'a ast::Ty, + ty: Option<&'a ast::Ty>, mutability: ast::Mutability, expr_opt: Option<&'a ast::Expr>, defaultness: Option, @@ -2021,7 +2021,7 @@ impl<'a> StaticParts<'a> { "static", s.safety, s.ident, - &s.ty, + Some(&*s.ty), s.mutability, s.expr.as_deref(), None, @@ -2031,7 +2031,7 @@ impl<'a> StaticParts<'a> { "const", ast::Safety::Default, c.ident, - &c.ty, + c.ty.as_non_default(), ast::Mutability::Not, c.rhs.as_ref().map(|rhs| rhs.expr()), Some(&c.generics), @@ -2056,7 +2056,7 @@ impl<'a> StaticParts<'a> { let (defaultness, ty, expr_opt, generics) = match &ti.kind { ast::AssocItemKind::Const(c) => ( c.defaultness, - &c.ty, + c.ty.as_non_default(), c.rhs.as_ref().map(|rhs| rhs.expr()), Some(&c.generics), ), @@ -2080,7 +2080,7 @@ impl<'a> StaticParts<'a> { let (defaultness, ty, expr_opt, generics) = match &ii.kind { ast::AssocItemKind::Const(c) => ( c.defaultness, - &c.ty, + c.ty.as_non_default(), c.rhs.as_ref().map(|rhs| rhs.expr()), Some(&c.generics), ), @@ -2114,35 +2114,38 @@ fn rewrite_static( return None; } - let colon = colon_spaces(context.config); let mut prefix = format!( - "{}{}{}{} {}{}{}", + "{}{}{}{} {}{}", format_visibility(context, static_parts.vis), static_parts.defaultness.map_or("", format_defaultness), format_safety(static_parts.safety), static_parts.prefix, format_mutability(static_parts.mutability), rewrite_ident(context, static_parts.ident), - colon, ); - // 2 = " =".len() - let ty_shape = - Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?; - let ty_str = match static_parts.ty.rewrite(context, ty_shape) { - Some(ty_str) => ty_str, - None => { - if prefix.ends_with(' ') { - prefix.pop(); + let ty_str = match static_parts.ty { + Some(ty) => { + prefix.push_str(colon_spaces(context.config)); + let ty_shape = Shape::indented(offset.block_only(), context.config) + .offset_left(prefix.len() + const { " =".len() })?; + match ty.rewrite(context, ty_shape) { + Some(ty_str) => ty_str, + None => { + if prefix.ends_with(' ') { + prefix.pop(); + } + let nested_indent = offset.block_indent(context.config); + let nested_shape = Shape::indented(nested_indent, context.config); + let ty_str = ty.rewrite(context, nested_shape)?; + format!( + "{}{}", + nested_indent.to_string_with_newline(context.config), + ty_str + ) + } } - let nested_indent = offset.block_indent(context.config); - let nested_shape = Shape::indented(nested_indent, context.config); - let ty_str = static_parts.ty.rewrite(context, nested_shape)?; - format!( - "{}{}", - nested_indent.to_string_with_newline(context.config), - ty_str - ) } + None => "".to_string(), }; if let Some(expr) = static_parts.expr_opt { diff --git a/src/tools/rustfmt/tests/source/const-no-type.rs b/src/tools/rustfmt/tests/source/const-no-type.rs new file mode 100644 index 0000000000000..5944f5250e2ad --- /dev/null +++ b/src/tools/rustfmt/tests/source/const-no-type.rs @@ -0,0 +1,29 @@ +#![feature(const_items_unit_type_default)] + + const FOO = { + + + assert!(true) + }; + + #[cfg(false)] const BAR = assert!(false); + + + #[cfg(false)] +// foo + const +// foo 2 +BAZ +// baz += +// baz 2 + + { + // bar + assert!(false) + // baz + } ; + + + #[expect(unused)] +const _ = { let a = 1; assert!(true); } ; diff --git a/src/tools/rustfmt/tests/target/const-no-type.rs b/src/tools/rustfmt/tests/target/const-no-type.rs new file mode 100644 index 0000000000000..002f262be1948 --- /dev/null +++ b/src/tools/rustfmt/tests/target/const-no-type.rs @@ -0,0 +1,27 @@ +#![feature(const_items_unit_type_default)] + +const FOO = { assert!(true) }; + +#[cfg(false)] +const BAR = assert!(false); + +#[cfg(false)] +// foo +const +// foo 2 +BAZ +// baz += +// baz 2 + + { + // bar + assert!(false) + // baz + } ; + +#[expect(unused)] +const _ = { + let a = 1; + assert!(true); +}; diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs index b2c7340980091..84f0bec36f5e5 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs @@ -6,7 +6,8 @@ struct A; impl A { #[type_const] const B = 4; - //~^ ERROR: missing type for `const` item + //~^ ERROR: omitting type on const item declaration is experimental [E0658] + //~| ERROR: mismatched types [E0308] } fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr index b44e47cd7e611..ccb61267bce17 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr @@ -1,13 +1,21 @@ -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/type_const-inherent-const-omitted-type.rs:8:12 | LL | const B = 4; | ^ | -help: provide a type for the item + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0308]: mismatched types + --> $DIR/type_const-inherent-const-omitted-type.rs:8:15 | -LL | const B: = 4; - | ++++++++ +LL | const B = 4; + | ^ expected `()`, found integer -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs index ab613859aa5c6..735b964bfcf85 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs @@ -10,8 +10,9 @@ struct GoodS; impl BadTr for GoodS { #[type_const] const NUM: = 84; - //~^ ERROR: missing type for `const` item - + //~^ ERROR: omitting type on const item declaration is experimental [E0658] + //~| ERROR: mismatched types [E0308] + //~| ERROR: implemented const `NUM` has an incompatible type for trait [E0326] } fn accept_bad_tr>(_x: &T) {} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr index 16f312454ed28..d8f64c0c865a4 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr @@ -1,16 +1,41 @@ -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/type_const-only-in-impl-omitted-type.rs:12:15 | LL | const NUM: = 84; - | ^ help: provide a type for the associated constant: `usize` + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0326]: implemented const `NUM` has an incompatible type for trait + --> $DIR/type_const-only-in-impl-omitted-type.rs:12:15 + | +LL | const NUM: = 84; + | ^ expected `usize`, found `()` + | +note: type in trait + --> $DIR/type_const-only-in-impl-omitted-type.rs:5:16 + | +LL | const NUM: usize; + | ^^^^^ error: use of trait associated const without `#[type_const]` - --> $DIR/type_const-only-in-impl-omitted-type.rs:17:43 + --> $DIR/type_const-only-in-impl-omitted-type.rs:18:43 | LL | fn accept_bad_tr>(_x: &T) {} | ^^^^^^^^^^^ | = note: the declaration in the trait must be marked with `#[type_const]` -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/type_const-only-in-impl-omitted-type.rs:12:18 + | +LL | const NUM: = 84; + | ^^ expected `()`, found integer + +error: aborting due to 4 previous errors +Some errors have detailed explanations: E0308, E0326, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs index fe8dc45346186..1ba6b82f0981c 100644 --- a/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs +++ b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs @@ -1,6 +1,6 @@ fn main() { - const FOO = "hello" + 1; + const FOO: _ = "hello" + 1; //~^ ERROR cannot add `{integer}` to `&str` - //~| ERROR missing type for `const` item + //~| ERROR the placeholder `_` is not allowed within types on item signatures for constants [E0121] println!("{}", FOO); } diff --git a/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr index 8f1fcc645b9c0..6035054ffba0e 100644 --- a/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr +++ b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr @@ -1,22 +1,18 @@ error[E0369]: cannot add `{integer}` to `&str` - --> $DIR/dont-suggest-type-error.rs:2:25 + --> $DIR/dont-suggest-type-error.rs:2:28 | -LL | const FOO = "hello" + 1; - | ------- ^ - {integer} - | | - | &str +LL | const FOO: _ = "hello" + 1; + | ------- ^ - {integer} + | | + | &str -error: missing type for `const` item - --> $DIR/dont-suggest-type-error.rs:2:14 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/dont-suggest-type-error.rs:2:16 | -LL | const FOO = "hello" + 1; - | ^ - | -help: provide a type for the item - | -LL | const FOO: = "hello" + 1; - | ++++++++ +LL | const FOO: _ = "hello" + 1; + | ^ not allowed in type signatures error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0369`. +Some errors have detailed explanations: E0121, E0369. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/consts/const-item-no-type/empty-array.rs b/tests/ui/consts/const-item-no-type/empty-array.rs index 4d28ad051dfaf..3915b25d39eee 100644 --- a/tests/ui/consts/const-item-no-type/empty-array.rs +++ b/tests/ui/consts/const-item-no-type/empty-array.rs @@ -1,5 +1,5 @@ fn main() { - const EMPTY_ARRAY = []; - //~^ ERROR missing type for `const` item + const EMPTY_ARRAY: _ = []; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants [E0121] //~| ERROR type annotations needed } diff --git a/tests/ui/consts/const-item-no-type/empty-array.stderr b/tests/ui/consts/const-item-no-type/empty-array.stderr index fe307d50353e4..1605047c8d680 100644 --- a/tests/ui/consts/const-item-no-type/empty-array.stderr +++ b/tests/ui/consts/const-item-no-type/empty-array.stderr @@ -1,20 +1,16 @@ error[E0282]: type annotations needed - --> $DIR/empty-array.rs:2:25 + --> $DIR/empty-array.rs:2:28 | -LL | const EMPTY_ARRAY = []; - | ^^ cannot infer type +LL | const EMPTY_ARRAY: _ = []; + | ^^ cannot infer type -error: missing type for `const` item - --> $DIR/empty-array.rs:2:22 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/empty-array.rs:2:24 | -LL | const EMPTY_ARRAY = []; - | ^ - | -help: provide a type for the item - | -LL | const EMPTY_ARRAY: = []; - | ++++++++ +LL | const EMPTY_ARRAY: _ = []; + | ^ not allowed in type signatures error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0121, E0282. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/consts/const-item-no-type/in-macro.rs b/tests/ui/consts/const-item-no-type/in-macro.rs index c200a1fd0b41e..0a56b900eac41 100644 --- a/tests/ui/consts/const-item-no-type/in-macro.rs +++ b/tests/ui/consts/const-item-no-type/in-macro.rs @@ -3,8 +3,10 @@ macro_rules! suite { $( const A = "A".$fn(); //~^ ERROR the name `A` is defined multiple times - //~| ERROR missing type for `const` item - //~| ERROR missing type for item + //~| ERROR: omitting type on const item declaration is experimental [E0658] + //~| ERROR: mismatched types [E0308] + //~| ERROR: omitting type on const item declaration is experimental [E0658] + //~| ERROR: mismatched types [E0308] )* } } diff --git a/tests/ui/consts/const-item-no-type/in-macro.stderr b/tests/ui/consts/const-item-no-type/in-macro.stderr index d6182aa114270..647be4df5bc0f 100644 --- a/tests/ui/consts/const-item-no-type/in-macro.stderr +++ b/tests/ui/consts/const-item-no-type/in-macro.stderr @@ -13,11 +13,11 @@ LL | | } = note: `A` must be defined only once in the value namespace of this module = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); - | ^ help: provide a type for the constant: `: usize` + | ^ ... LL | / suite! { LL | | len; @@ -25,13 +25,17 @@ LL | | is_empty; LL | | } | |_- in this macro invocation | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0121]: missing type for item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); - | ^ not allowed in type signatures + | ^ ... LL | / suite! { LL | | len; @@ -39,9 +43,42 @@ LL | | is_empty; LL | | } | |_- in this macro invocation | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/in-macro.rs:4:23 + | +LL | const A = "A".$fn(); + | ^^^^^^^^^ expected `()`, found `usize` +... +LL | / suite! { +LL | | len; +LL | | is_empty; +LL | | } + | |_- in this macro invocation + | + = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/in-macro.rs:4:23 + | +LL | const A = "A".$fn(); + | ^^^^^^^^^ expected `()`, found `bool` +... +LL | / suite! { +LL | | len; +LL | | is_empty; +LL | | } + | |_- in this macro invocation + | + = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0121, E0428. -For more information about an error, try `rustc --explain E0121`. +Some errors have detailed explanations: E0308, E0428, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-item-no-type/with-colon.fixed b/tests/ui/consts/const-item-no-type/with-colon.fixed deleted file mode 100644 index 4af32cfa3f1a2..0000000000000 --- a/tests/ui/consts/const-item-no-type/with-colon.fixed +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-rustfix - -const _A: i32 = 123; -//~^ ERROR: missing type for `const` item - -fn main() { - const _B: i32 = 123; - //~^ ERROR: missing type for `const` item -} diff --git a/tests/ui/consts/const-item-no-type/with-colon.rs b/tests/ui/consts/const-item-no-type/with-colon.rs index 46ec1dea0c038..893c4cb8322dd 100644 --- a/tests/ui/consts/const-item-no-type/with-colon.rs +++ b/tests/ui/consts/const-item-no-type/with-colon.rs @@ -1,9 +1,11 @@ -//@ run-rustfix +//@ check-fail const _A: = 123; -//~^ ERROR: missing type for `const` item +//~^ ERROR: omitting type on const item declaration is experimental [E0658] +//~| ERROR: mismatched types [E0308] fn main() { const _B: = 123; - //~^ ERROR: missing type for `const` item + //~^ ERROR: omitting type on const item declaration is experimental [E0658] + //~| ERROR: mismatched types [E0308] } diff --git a/tests/ui/consts/const-item-no-type/with-colon.stderr b/tests/ui/consts/const-item-no-type/with-colon.stderr index adbea1f355a0b..7b1e812fb8654 100644 --- a/tests/ui/consts/const-item-no-type/with-colon.stderr +++ b/tests/ui/consts/const-item-no-type/with-colon.stderr @@ -1,14 +1,38 @@ -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/with-colon.rs:3:10 | LL | const _A: = 123; - | ^ help: provide a type for the constant: `i32` + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/with-colon.rs:8:14 + | +LL | const _B: = 123; + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0308]: mismatched types + --> $DIR/with-colon.rs:3:13 + | +LL | const _A: = 123; + | ^^^ expected `()`, found integer -error: missing type for `const` item - --> $DIR/with-colon.rs:7:14 +error[E0308]: mismatched types + --> $DIR/with-colon.rs:8:17 | LL | const _B: = 123; - | ^ help: provide a type for the constant: `i32` + | ^^^ expected `()`, found integer -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-item-without-ty/assert-fail.rs b/tests/ui/consts/const-item-without-ty/assert-fail.rs new file mode 100644 index 0000000000000..3528ee3f920d6 --- /dev/null +++ b/tests/ui/consts/const-item-without-ty/assert-fail.rs @@ -0,0 +1,10 @@ +//@ check-fail + +#![feature(const_items_unit_type_default)] + +const _ = assert!(false); +//~^ ERROR: evaluation panicked: assertion failed: false [E0080] +const _ = assert!(2 + 2 == 5); +//~^ ERROR: evaluation panicked: assertion failed: 2 + 2 == 5 [E0080] + +fn main() {} diff --git a/tests/ui/consts/const-item-without-ty/assert-fail.stderr b/tests/ui/consts/const-item-without-ty/assert-fail.stderr new file mode 100644 index 0000000000000..1eb534397c1a1 --- /dev/null +++ b/tests/ui/consts/const-item-without-ty/assert-fail.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation panicked: assertion failed: false + --> $DIR/assert-fail.rs:5:11 + | +LL | const _ = assert!(false); + | ^^^^^^^^^^^^^^ evaluation of `_` failed here + +error[E0080]: evaluation panicked: assertion failed: 2 + 2 == 5 + --> $DIR/assert-fail.rs:7:11 + | +LL | const _ = assert!(2 + 2 == 5); + | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-item-without-ty/assert-pass.rs b/tests/ui/consts/const-item-without-ty/assert-pass.rs new file mode 100644 index 0000000000000..d911a6250f726 --- /dev/null +++ b/tests/ui/consts/const-item-without-ty/assert-pass.rs @@ -0,0 +1,7 @@ +//@ check-pass +#![feature(const_items_unit_type_default)] + +const _ = assert!(true); +const _ = assert!(2 + 2 == 4); + +fn main() {} diff --git a/tests/ui/consts/const-item-without-ty/typecheck.rs b/tests/ui/consts/const-item-without-ty/typecheck.rs new file mode 100644 index 0000000000000..4f0f7ce7cb549 --- /dev/null +++ b/tests/ui/consts/const-item-without-ty/typecheck.rs @@ -0,0 +1,19 @@ +//@ check-fail + +#![feature(const_items_unit_type_default)] + +const _ = { + assert!(true); + 2 + 2 //~ ERROR: mismatched types [E0308] +}; + +const fn id(t: T) -> T { + t +} + +const _ = id(2); +//~^ ERROR: mismatched types [E0308] +const _ = id(()); + + +fn main() {} diff --git a/tests/ui/consts/const-item-without-ty/typecheck.stderr b/tests/ui/consts/const-item-without-ty/typecheck.stderr new file mode 100644 index 0000000000000..f19383a0451e9 --- /dev/null +++ b/tests/ui/consts/const-item-without-ty/typecheck.stderr @@ -0,0 +1,30 @@ +error[E0308]: mismatched types + --> $DIR/typecheck.rs:7:5 + | +LL | 2 + 2 + | ^^^^^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/typecheck.rs:14:14 + | +LL | const _ = id(2); + | -- ^ expected `()`, found integer + | | + | arguments to this function are incorrect + | +help: the return type of this call is `{integer}` due to the type of the argument passed + --> $DIR/typecheck.rs:14:11 + | +LL | const _ = id(2); + | ^^^-^ + | | + | this argument influences the return type of `id` +note: function defined here + --> $DIR/typecheck.rs:10:10 + | +LL | const fn id(t: T) -> T { + | ^^ ---- + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs index 61042bfa96d08..653c2f5b6b89d 100644 --- a/tests/ui/consts/missing_assoc_const_type.rs +++ b/tests/ui/consts/missing_assoc_const_type.rs @@ -9,7 +9,8 @@ trait Range { struct TwoDigits; impl Range for TwoDigits { - const FIRST: = 10; //~ ERROR missing type for `const` item + const FIRST: _ = 10; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] const LAST: u8 = 99; } diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr index 28af1f0f321e6..e8dec67139908 100644 --- a/tests/ui/consts/missing_assoc_const_type.stderr +++ b/tests/ui/consts/missing_assoc_const_type.stderr @@ -1,8 +1,15 @@ -error: missing type for `const` item - --> $DIR/missing_assoc_const_type.rs:12:17 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/missing_assoc_const_type.rs:12:18 + | +LL | const FIRST: _ = 10; + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL - const FIRST: _ = 10; +LL + const FIRST: u8 = 10; | -LL | const FIRST: = 10; - | ^ help: provide a type for the associated constant: `u8` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/consts/missing_assoc_const_type2.rs b/tests/ui/consts/missing_assoc_const_type2.rs index baf236700a396..7b8c31950c298 100644 --- a/tests/ui/consts/missing_assoc_const_type2.rs +++ b/tests/ui/consts/missing_assoc_const_type2.rs @@ -9,8 +9,8 @@ trait Range { struct TwoDigits; impl Range for TwoDigits { - const FIRST: = 10; - //~^ ERROR: missing type + const FIRST: _ = 10; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] const LAST: u8 = 99; } diff --git a/tests/ui/consts/missing_assoc_const_type2.stderr b/tests/ui/consts/missing_assoc_const_type2.stderr index 1255ca2d102b5..1c5f6044c88f9 100644 --- a/tests/ui/consts/missing_assoc_const_type2.stderr +++ b/tests/ui/consts/missing_assoc_const_type2.stderr @@ -1,8 +1,15 @@ -error: missing type for `const` item - --> $DIR/missing_assoc_const_type2.rs:12:17 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/missing_assoc_const_type2.rs:12:18 + | +LL | const FIRST: _ = 10; + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL - const FIRST: _ = 10; +LL + const FIRST: u8 = 10; | -LL | const FIRST: = 10; - | ^ help: provide a type for the associated constant: `u8` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.rs b/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.rs new file mode 100644 index 0000000000000..6a4f7aef67379 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.rs @@ -0,0 +1,3 @@ +const _ = {}; +//~^ ERROR omitting type on const item declaration is experimental +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.stderr b/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.stderr new file mode 100644 index 0000000000000..853c765c607de --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-const-items-unit-type-default.stderr @@ -0,0 +1,14 @@ +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/feature-gate-const-items-unit-type-default.rs:1:8 + | +LL | const _ = {}; + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs index 2b7167ad067e2..87c381539b982 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.rs +++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs @@ -10,11 +10,12 @@ trait Trait { impl Trait for () { const K = (); - //~^ ERROR missing type for `const` item - //~| ERROR mismatched types + //~^ ERROR omitting type on const item declaration is experimental [E0658] + //~| ERROR implemented const `K` has an incompatible type for trait [E0326] const Q = ""; - //~^ ERROR missing type for `const` item - //~| ERROR lifetime parameters or bounds on associated constant `Q` do not match the trait declaration + //~^ ERROR omitting type on const item declaration is experimental [E0658] + //~| ERROR mismatched types [E0308] + //~| ERROR lifetime parameters or bounds on associated constant `Q` do not match the trait declaration [E0195] } fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr index 7c79133d64ec3..319f344fcb44f 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr +++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr @@ -1,19 +1,40 @@ -error[E0308]: mismatched types - --> $DIR/assoc-const-missing-type.rs:12:18 +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/assoc-const-missing-type.rs:12:15 | LL | const K = (); - | - ^^ expected type parameter `T`, found `()` - | | - | expected this type parameter + | ^ | - = note: expected type parameter `T` - found unit type `()` + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/assoc-const-missing-type.rs:15:12 + | +LL | const Q = ""; + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0326]: implemented const `K` has an incompatible type for trait --> $DIR/assoc-const-missing-type.rs:12:15 | LL | const K = (); - | ^ help: provide a type for the associated constant: `()` + | - ^ expected type parameter `T`, found `()` + | | + | expected this type parameter + | +note: type in trait + --> $DIR/assoc-const-missing-type.rs:7:17 + | +LL | const K: T; + | ^ + = note: expected type parameter `T` + found unit type `()` error[E0195]: lifetime parameters or bounds on associated constant `Q` do not match the trait declaration --> $DIR/assoc-const-missing-type.rs:15:12 @@ -24,13 +45,13 @@ LL | const Q<'a>: &'a str; LL | const Q = ""; | ^ lifetimes do not match associated constant in trait -error: missing type for `const` item - --> $DIR/assoc-const-missing-type.rs:15:12 +error[E0308]: mismatched types + --> $DIR/assoc-const-missing-type.rs:15:15 | LL | const Q = ""; - | ^ help: provide a type for the associated constant: `: &str` + | ^^ expected `()`, found `&str` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0195, E0308. +Some errors have detailed explanations: E0195, E0308, E0326, E0658. For more information about an error, try `rustc --explain E0195`. diff --git a/tests/ui/parser/const-item-without-ty/attrs.rs b/tests/ui/parser/const-item-without-ty/attrs.rs new file mode 100644 index 0000000000000..098d97cf70e7a --- /dev/null +++ b/tests/ui/parser/const-item-without-ty/attrs.rs @@ -0,0 +1,13 @@ +//@ check-pass +#![feature(const_items_unit_type_default)] + +#[cfg(false)] +const _ = assert!(false); + +#[expect(unused)] +const _ = { + let a = 1; + assert!(true); +}; + +fn main() {} diff --git a/tests/ui/parser/const-item-without-ty/macro.rs b/tests/ui/parser/const-item-without-ty/macro.rs new file mode 100644 index 0000000000000..36f449985b9a3 --- /dev/null +++ b/tests/ui/parser/const-item-without-ty/macro.rs @@ -0,0 +1,14 @@ +//@ check-pass +#![feature(const_items_unit_type_default)] + +macro_rules! foo { + ($item:item) => { + $item + }; +} + +foo!(const _ = {};); + +fn main() { + foo!(const _ = {};); +} diff --git a/tests/ui/parser/item-free-const-no-body-semantic-fail.rs b/tests/ui/parser/item-free-const-no-body-semantic-fail.rs index 613b3c9856171..2438c9a49d820 100644 --- a/tests/ui/parser/item-free-const-no-body-semantic-fail.rs +++ b/tests/ui/parser/item-free-const-no-body-semantic-fail.rs @@ -4,4 +4,4 @@ fn main() {} const A: u8; //~ ERROR free constant item without body const B; //~ ERROR free constant item without body -//~^ ERROR missing type for `const` item +//~^ ERROR omitting type on const item declaration is experimental [E0658] diff --git a/tests/ui/parser/item-free-const-no-body-semantic-fail.stderr b/tests/ui/parser/item-free-const-no-body-semantic-fail.stderr index 1ecf9912e9b11..c071867d8e3e9 100644 --- a/tests/ui/parser/item-free-const-no-body-semantic-fail.stderr +++ b/tests/ui/parser/item-free-const-no-body-semantic-fail.stderr @@ -14,16 +14,17 @@ LL | const B; | | | help: provide a definition for the constant: `= ;` -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/item-free-const-no-body-semantic-fail.rs:6:8 | LL | const B; | ^ | -help: provide a type for the item - | -LL | const B: ; - | ++++++++ + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/proc-macro/quote/debug.stdout b/tests/ui/proc-macro/quote/debug.stdout index 896c809fedaba..529746d637911 100644 --- a/tests/ui/proc-macro/quote/debug.stdout +++ b/tests/ui/proc-macro/quote/debug.stdout @@ -62,7 +62,7 @@ fn main() { ts } } -const _: () = +const _ = { extern crate proc_macro; #[rustc_proc_macro_decls] diff --git a/tests/ui/suggestions/const-no-type.rs b/tests/ui/suggestions/const-no-type.rs index b72ace95213ce..cc2a0fa5bfb85 100644 --- a/tests/ui/suggestions/const-no-type.rs +++ b/tests/ui/suggestions/const-no-type.rs @@ -12,9 +12,9 @@ fn main() {} #[cfg(false)] const C2 = 42; -//~^ ERROR missing type for `const` item -//~| HELP provide a type for the item -//~| SUGGESTION : +//~^ ERROR: omitting type on const item declaration is experimental [E0658] +//~| HELP: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable +//~| HELP: consider specifying the type explicitly #[cfg(false)] static S2 = "abc"; @@ -31,14 +31,16 @@ static mut SM2 = "abc"; // These will, so the diagnostics should be stolen by typeck: const C = 42; -//~^ ERROR missing type for `const` item -//~| HELP provide a type for the constant -//~| SUGGESTION : i32 +//~^ ERROR: omitting type on const item declaration is experimental [E0658] +//~| HELP: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable +//~| HELP: consider specifying the type explicitly +//~| ERROR: mismatched types [E0308] const D = &&42; -//~^ ERROR missing type for `const` item -//~| HELP provide a type for the constant -//~| SUGGESTION : &&i32 +//~^ ERROR: omitting type on const item declaration is experimental [E0658] +//~| HELP: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable +//~| HELP: consider specifying the type explicitly +//~| ERROR: mismatched types [E0308] static S = Vec::::new(); //~^ ERROR missing type for `static` item diff --git a/tests/ui/suggestions/const-no-type.stderr b/tests/ui/suggestions/const-no-type.stderr index c85c58989073d..ae5c92bb85cbe 100644 --- a/tests/ui/suggestions/const-no-type.stderr +++ b/tests/ui/suggestions/const-no-type.stderr @@ -1,37 +1,59 @@ -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/const-no-type.rs:14:9 + | +LL | const C2 = 42; + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly + +error[E0658]: omitting type on const item declaration is experimental --> $DIR/const-no-type.rs:33:8 | LL | const C = 42; - | ^ help: provide a type for the constant: `: i32` + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly -error: missing type for `const` item - --> $DIR/const-no-type.rs:38:8 +error[E0658]: omitting type on const item declaration is experimental + --> $DIR/const-no-type.rs:39:8 | LL | const D = &&42; - | ^ help: provide a type for the constant: `: &&i32` + | ^ + | + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly error: missing type for `static` item - --> $DIR/const-no-type.rs:43:9 + --> $DIR/const-no-type.rs:45:9 | LL | static S = Vec::::new(); | ^ help: provide a type for the static variable: `: Vec` error: missing type for `static mut` item - --> $DIR/const-no-type.rs:48:14 + --> $DIR/const-no-type.rs:50:14 | LL | static mut SM = "abc"; | ^ help: provide a type for the static variable: `: &str` -error: missing type for `const` item - --> $DIR/const-no-type.rs:14:9 - | -LL | const C2 = 42; - | ^ +error[E0308]: mismatched types + --> $DIR/const-no-type.rs:33:11 | -help: provide a type for the item +LL | const C = 42; + | ^^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/const-no-type.rs:39:11 | -LL | const C2: = 42; - | ++++++++ +LL | const D = &&42; + | ^^^^ expected `()`, found `&&{integer}` error: missing type for `static` item --> $DIR/const-no-type.rs:20:10 @@ -55,5 +77,7 @@ help: provide a type for the item LL | static mut SM2: = "abc"; | ++++++++ -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/suggestions/unnamable-types.rs b/tests/ui/suggestions/unnamable-types.rs index 6772217a2f6ff..cae8237fa3a96 100644 --- a/tests/ui/suggestions/unnamable-types.rs +++ b/tests/ui/suggestions/unnamable-types.rs @@ -3,9 +3,9 @@ #![crate_type="lib"] #![feature(coroutines, stmt_expr_attributes, const_async_blocks)] -const A = 5; -//~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the constant +static A = 5; +//~^ ERROR: missing type for `static` item +//~| HELP: provide a type for the static variable static B: _ = "abc"; //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static variables @@ -14,26 +14,26 @@ static B: _ = "abc"; // FIXME: this should also suggest a function pointer, as the closure is non-capturing -const C: _ = || 42; -//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for constants +static C: _ = || 42; +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static variables //~| NOTE: not allowed in type signatures //~| NOTE: however, the inferred type struct S { t: T } -const D = S { t: { let i = 0; move || -> i32 { i } } }; -//~^ ERROR: missing type for `const` item +static D = S { t: { let i = 0; move || -> i32 { i } } }; +//~^ ERROR: missing type for `static` item //~| NOTE: however, the inferred type fn foo() -> i32 { 42 } -const E = foo; -//~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the constant -const F = S { t: foo }; -//~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the constant +static E = foo; +//~^ ERROR: missing type for `static` item +//~| HELP: provide a type for the static variable +static F = S { t: foo }; +//~^ ERROR: missing type for `static` item +//~| HELP: provide a type for the static variable -const G = #[coroutine] || -> i32 { yield 0; return 1; }; -//~^ ERROR: missing type for `const` item +static G = #[coroutine] || -> i32 { yield 0; return 1; }; +//~^ ERROR: missing type for `static` item //~| NOTE: however, the inferred type diff --git a/tests/ui/suggestions/unnamable-types.stderr b/tests/ui/suggestions/unnamable-types.stderr index bcd1a905194ef..7c0032da0d4e1 100644 --- a/tests/ui/suggestions/unnamable-types.stderr +++ b/tests/ui/suggestions/unnamable-types.stderr @@ -1,8 +1,8 @@ -error: missing type for `const` item - --> $DIR/unnamable-types.rs:6:8 +error: missing type for `static` item + --> $DIR/unnamable-types.rs:6:9 | -LL | const A = 5; - | ^ help: provide a type for the constant: `: i32` +LL | static A = 5; + | ^ help: provide a type for the static variable: `: i32` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/unnamable-types.rs:10:11 @@ -16,53 +16,53 @@ LL - static B: _ = "abc"; LL + static B: &str = "abc"; | -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/unnamable-types.rs:17:10 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/unnamable-types.rs:17:11 | -LL | const C: _ = || 42; - | ^ not allowed in type signatures +LL | static C: _ = || 42; + | ^ not allowed in type signatures | -note: however, the inferred type `{closure@unnamable-types.rs:17:14}` cannot be named - --> $DIR/unnamable-types.rs:17:14 +note: however, the inferred type `{closure@unnamable-types.rs:17:15}` cannot be named + --> $DIR/unnamable-types.rs:17:15 | -LL | const C: _ = || 42; - | ^^^^^ +LL | static C: _ = || 42; + | ^^^^^ -error: missing type for `const` item - --> $DIR/unnamable-types.rs:23:8 +error: missing type for `static` item + --> $DIR/unnamable-types.rs:23:9 | -LL | const D = S { t: { let i = 0; move || -> i32 { i } } }; - | ^ +LL | static D = S { t: { let i = 0; move || -> i32 { i } } }; + | ^ | -note: however, the inferred type `S<{closure@unnamable-types.rs:23:31}>` cannot be named - --> $DIR/unnamable-types.rs:23:11 +note: however, the inferred type `S<{closure@unnamable-types.rs:23:32}>` cannot be named + --> $DIR/unnamable-types.rs:23:12 | -LL | const D = S { t: { let i = 0; move || -> i32 { i } } }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | static D = S { t: { let i = 0; move || -> i32 { i } } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: missing type for `const` item - --> $DIR/unnamable-types.rs:29:8 +error: missing type for `static` item + --> $DIR/unnamable-types.rs:29:9 | -LL | const E = foo; - | ^ help: provide a type for the constant: `: fn() -> i32` +LL | static E = foo; + | ^ help: provide a type for the static variable: `: fn() -> i32` -error: missing type for `const` item - --> $DIR/unnamable-types.rs:32:8 +error: missing type for `static` item + --> $DIR/unnamable-types.rs:32:9 | -LL | const F = S { t: foo }; - | ^ help: provide a type for the constant: `: S i32>` +LL | static F = S { t: foo }; + | ^ help: provide a type for the static variable: `: S i32>` -error: missing type for `const` item - --> $DIR/unnamable-types.rs:37:8 +error: missing type for `static` item + --> $DIR/unnamable-types.rs:37:9 | -LL | const G = #[coroutine] || -> i32 { yield 0; return 1; }; - | ^ +LL | static G = #[coroutine] || -> i32 { yield 0; return 1; }; + | ^ | -note: however, the inferred type `{coroutine@$DIR/unnamable-types.rs:37:24: 37:33}` cannot be named - --> $DIR/unnamable-types.rs:37:24 +note: however, the inferred type `{coroutine@$DIR/unnamable-types.rs:37:25: 37:34}` cannot be named + --> $DIR/unnamable-types.rs:37:25 | -LL | const G = #[coroutine] || -> i32 { yield 0; return 1; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | static G = #[coroutine] || -> i32 { yield 0; return 1; }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs b/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs index 97e0b213f2e79..1e7586c0934cf 100644 --- a/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs +++ b/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs @@ -1,5 +1,5 @@ trait Foo { - const A; //~ ERROR missing type for `const` item + const A; //~ ERROR omitting type on const item declaration is experimental [E0658] static B; //~^ ERROR associated `static` items are not allowed //~| ERROR missing type for `static` item diff --git a/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr b/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr index 4450aa66c1322..a9ef7d3f00cf8 100644 --- a/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr +++ b/tests/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr @@ -4,16 +4,16 @@ error: associated `static` items are not allowed LL | static B; | ^^^^^^^^^ -error: missing type for `const` item +error[E0658]: omitting type on const item declaration is experimental --> $DIR/do-not-suggest-placeholder-to-const-static-without-type.rs:2:12 | LL | const A; | ^ | -help: provide a type for the item - | -LL | const A: ; - | ++++++++ + = note: see issue #149226 for more information + = help: add `#![feature(const_items_unit_type_default)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider specifying the type explicitly error: missing type for `static` item --> $DIR/do-not-suggest-placeholder-to-const-static-without-type.rs:3:13 @@ -28,3 +28,4 @@ LL | static B: ; error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0658`.