From 3eb48a35c8ae8335da66dc2bdb4f60e6ae22e1dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 18 Dec 2023 17:55:55 +0100 Subject: [PATCH] Introduce `const Trait` (always-const trait bounds) --- compiler/rustc_ast/src/ast.rs | 12 +-- compiler/rustc_ast/src/token.rs | 9 -- compiler/rustc_ast_lowering/src/item.rs | 7 +- compiler/rustc_ast_lowering/src/lib.rs | 86 +++++++++++-------- compiler/rustc_ast_lowering/src/path.rs | 4 +- compiler/rustc_ast_passes/messages.ftl | 2 + .../rustc_ast_passes/src/ast_validation.rs | 7 +- compiler/rustc_ast_passes/src/errors.rs | 7 ++ compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_hir/src/hir.rs | 6 ++ compiler/rustc_hir_analysis/messages.ftl | 2 +- .../rustc_hir_analysis/src/astconv/bounds.rs | 3 + .../rustc_hir_analysis/src/astconv/mod.rs | 7 +- compiler/rustc_hir_analysis/src/errors.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 21 +++-- compiler/rustc_parse/messages.ftl | 9 +- compiler/rustc_parse/src/errors.rs | 18 +--- compiler/rustc_parse/src/parser/ty.rs | 35 +++++--- src/librustdoc/html/format.rs | 4 +- src/librustdoc/json/conversions.rs | 3 + tests/ui/consts/fn_trait_refs.stderr | 20 ++--- .../unstable-const-fn-in-libcore.stderr | 2 +- .../generic-const-items/const-trait-impl.rs | 18 ++-- .../const-trait-impl.stderr | 12 --- .../impl-trait/normalize-tait-in-const.stderr | 2 +- tests/ui/parser/bounds-type.rs | 1 + tests/ui/parser/bounds-type.stderr | 8 +- ...mbe-bare-trait-object-maybe-trait-bound.rs | 16 ++++ tests/ui/parser/trait-object-delimiters.rs | 2 +- .../ui/parser/trait-object-delimiters.stderr | 4 +- .../assoc-type.stderr | 2 +- .../const-bounds-non-const-trait.rs | 12 +++ .../const-bounds-non-const-trait.stderr | 14 +++ .../const-closure-parse-not-item.stderr | 2 +- .../const-closure-trait-method-fail.stderr | 2 +- .../const-closure-trait-method.stderr | 2 +- .../const-closures.stderr | 8 +- .../const-drop-fail-2.precise.stderr | 2 +- .../const-drop-fail-2.stock.stderr | 2 +- .../const-drop.precise.stderr | 17 ++-- .../rfc-2632-const-trait-impl/const-drop.rs | 5 +- .../const-drop.stock.stderr | 21 +++-- .../const-trait-bounds-trait-objects.rs | 9 ++ .../const-trait-bounds-trait-objects.stderr | 8 ++ .../const-trait-bounds.rs | 31 +++++++ .../ice-112822-expected-type-for-param.rs | 2 +- .../ice-112822-expected-type-for-param.stderr | 2 +- .../feature-gate.gated.stderr | 2 +- .../rfc-2632-const-trait-impl/feature-gate.rs | 8 ++ .../feature-gate.stock.stderr | 38 +++++++- ...e-bare-trait-objects-const-trait-bounds.rs | 20 +++++ ...onst-trait-bound-theoretical-regression.rs | 20 +++++ ...-trait-bound-theoretical-regression.stderr | 30 +++++++ .../mbe-dyn-const-2015.rs | 13 +++ ...utually-exclusive-trait-bound-modifiers.rs | 20 +++++ ...lly-exclusive-trait-bound-modifiers.stderr | 38 ++++++++ .../non-const-op-in-closure-in-const.stderr | 2 +- .../super-traits-fail-2.nn.stderr | 4 +- .../super-traits-fail-2.ny.stderr | 4 +- .../super-traits-fail-2.rs | 4 +- .../super-traits-fail-3.nn.stderr | 6 +- .../super-traits-fail-3.ny.stderr | 4 +- .../super-traits-fail-3.rs | 6 +- .../super-traits-fail-3.yn.stderr | 2 +- .../tilde-const-maybe-trait.rs | 6 -- .../tilde-const-maybe-trait.stderr | 8 -- .../without-tilde.rs | 6 -- .../without-tilde.stderr | 10 --- .../ui/specialization/const_trait_impl.stderr | 6 +- 69 files changed, 505 insertions(+), 223 deletions(-) delete mode 100644 tests/ui/generic-const-items/const-trait-impl.stderr create mode 100644 tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.rs delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.rs delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3496cfc38c8..9a9c769fd7c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2481,15 +2481,6 @@ pub enum Const { No, } -impl From for Const { - fn from(constness: BoundConstness) -> Self { - match constness { - BoundConstness::Maybe(span) => Self::Yes(span), - BoundConstness::Never => Self::No, - } - } -} - /// Item defaultness. /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532). #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] @@ -2543,6 +2534,8 @@ impl BoundPolarity { pub enum BoundConstness { /// `Type: Trait` Never, + /// `Type: const Trait` + Always(Span), /// `Type: ~const Trait` Maybe(Span), } @@ -2551,6 +2544,7 @@ impl BoundConstness { pub fn as_str(self) -> &'static str { match self { Self::Never => "", + Self::Always(_) => "const", Self::Maybe(_) => "~const", } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index b0cd2ec9815..d62462b1ae3 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -528,15 +528,6 @@ impl Token { } } - /// Returns `true` if the token can appear at the start of a generic bound. - pub fn can_begin_bound(&self) -> bool { - self.is_path_start() - || self.is_lifetime() - || self.is_keyword(kw::For) - || self == &Question - || self == &OpenDelim(Delimiter::Parenthesis) - } - /// Returns `true` if the token can appear at the start of an item. pub fn can_begin_item(&self) -> bool { match self.kind { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b70b9356226..3848f3b7782 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -339,9 +339,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let itctx = ImplTraitContext::Universal; let (generics, (trait_ref, lowered_ty)) = self.lower_generics(ast_generics, *constness, id, &itctx, |this| { + let constness = match *constness { + Const::Yes(span) => BoundConstness::Maybe(span), + Const::No => BoundConstness::Never, + }; + let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( - *constness, + constness, trait_ref, &ImplTraitContext::Disallowed(ImplTraitPosition::Trait), ) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e3954116288..4c4cf593bda 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1324,7 +1324,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: t.span, }, itctx, - ast::Const::No, + ast::BoundConstness::Never, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1435,7 +1435,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { polarity: BoundPolarity::Positive | BoundPolarity::Negative(_), constness, }, - ) => Some(this.lower_poly_trait_ref(ty, itctx, (*constness).into())), + ) => Some(this.lower_poly_trait_ref(ty, itctx, *constness)), // We can safely ignore constness here, since AST validation // will take care of invalid modifier combinations. GenericBound::Trait( @@ -2174,7 +2174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_trait_ref( &mut self, - constness: ast::Const, + constness: ast::BoundConstness, p: &TraitRef, itctx: &ImplTraitContext, ) -> hir::TraitRef<'hir> { @@ -2197,7 +2197,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: &ImplTraitContext, - constness: ast::Const, + constness: ast::BoundConstness, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); @@ -2322,9 +2322,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, modifiers: TraitBoundModifiers, ) -> hir::TraitBoundModifier { + // Invalid modifier combinations will cause an error during AST validation. + // Arbitrarily pick a placeholder for them to make compilation proceed. match (modifiers.constness, modifiers.polarity) { (BoundConstness::Never, BoundPolarity::Positive) => hir::TraitBoundModifier::None, - (BoundConstness::Never, BoundPolarity::Maybe(_)) => hir::TraitBoundModifier::Maybe, + (_, BoundPolarity::Maybe(_)) => hir::TraitBoundModifier::Maybe, (BoundConstness::Never, BoundPolarity::Negative(_)) => { if self.tcx.features().negative_bounds { hir::TraitBoundModifier::Negative @@ -2332,15 +2334,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TraitBoundModifier::None } } - (BoundConstness::Maybe(_), BoundPolarity::Positive) => { - hir::TraitBoundModifier::MaybeConst - } - // Invalid modifier combinations will cause an error during AST validation. - // Arbitrarily pick a placeholder for compilation to proceed. - (BoundConstness::Maybe(_), BoundPolarity::Maybe(_)) => hir::TraitBoundModifier::Maybe, - (BoundConstness::Maybe(_), BoundPolarity::Negative(_)) => { - hir::TraitBoundModifier::MaybeConst - } + (BoundConstness::Always(_), _) => hir::TraitBoundModifier::Const, + (BoundConstness::Maybe(_), _) => hir::TraitBoundModifier::MaybeConst, } } @@ -2558,45 +2553,62 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { - fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { + fn push_constness( + &mut self, + lcx: &mut LoweringContext<'_, 'hir>, + constness: ast::BoundConstness, + ) { if !lcx.tcx.features().effects { return; } - // if bound is non-const, don't add host effect param - let ast::Const::Yes(span) = constness else { return }; + let (span, body) = match constness { + BoundConstness::Never => return, + BoundConstness::Always(span) => { + let span = lcx.lower_span(span); - let span = lcx.lower_span(span); + let body = hir::ExprKind::Lit( + lcx.arena.alloc(hir::Lit { node: LitKind::Bool(false), span }), + ); - let id = lcx.next_node_id(); - let hir_id = lcx.next_id(); + (span, body) + } + BoundConstness::Maybe(span) => { + let span = lcx.lower_span(span); - let Some(host_param_id) = lcx.host_param_id else { - lcx.dcx().span_delayed_bug( - span, - "no host param id for call in const yet no errors reported", - ); - return; - }; + let Some(host_param_id) = lcx.host_param_id else { + lcx.dcx().span_delayed_bug( + span, + "no host param id for call in const yet no errors reported", + ); + return; + }; - let body = lcx.lower_body(|lcx| { - (&[], { let hir_id = lcx.next_id(); let res = Res::Def(DefKind::ConstParam, host_param_id.to_def_id()); - let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved( + let body = hir::ExprKind::Path(hir::QPath::Resolved( None, lcx.arena.alloc(hir::Path { span, res, - segments: arena_vec![lcx; hir::PathSegment::new(Ident { - name: sym::host, - span, - }, hir_id, res)], + segments: arena_vec![ + lcx; + hir::PathSegment::new( + Ident { name: sym::host, span }, + hir_id, + res + ) + ], }), )); - lcx.expr(span, expr_kind) - }) - }); + + (span, body) + } + }; + let body = lcx.lower_body(|lcx| (&[], lcx.expr(span, body))); + + let id = lcx.next_node_id(); + let hir_id = lcx.next_id(); let def_id = lcx.create_def( lcx.current_hir_id_owner.def_id, diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 130eb3521c3..c679ee56fcd 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -25,7 +25,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, itctx: &ImplTraitContext, // constness of the impl/bound if this is a trait path - constness: Option, + constness: Option, ) -> hir::QPath<'hir> { let qself_position = qself.as_ref().map(|q| q.position); let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); @@ -179,7 +179,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: &ImplTraitContext, - constness: Option, + constness: Option, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index ea3cd3e4bee..b5612c1820d 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -46,6 +46,8 @@ ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadi .const = `const` because of this .variadic = C-variadic because of this +ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types + ast_passes_const_without_body = free constant item without body .suggestion = provide a definition for the constant diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 3600e4960af..bc5cf463f12 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1207,6 +1207,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { (BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => { self.dcx().emit_err(errors::OptionalTraitObject { span: poly.span }); } + (BoundKind::TraitObject, BoundConstness::Always(_), BoundPolarity::Positive) => { + self.dcx().emit_err(errors::ConstBoundTraitObject { span: poly.span }); + } (_, BoundConstness::Maybe(span), BoundPolarity::Positive) if let Some(reason) = &self.disallow_tilde_const => { @@ -1237,8 +1240,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ( _, - BoundConstness::Maybe(_), - BoundPolarity::Maybe(_) | BoundPolarity::Negative(_), + BoundConstness::Always(_) | BoundConstness::Maybe(_), + BoundPolarity::Negative(_) | BoundPolarity::Maybe(_), ) => { self.dcx().emit_err(errors::IncompatibleTraitBoundModifiers { span: bound.span(), diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index a5b842b320e..0cec4374be2 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -540,6 +540,13 @@ pub struct OptionalTraitObject { pub span: Span, } +#[derive(Diagnostic)] +#[diag(ast_passes_const_bound_trait_object)] +pub struct ConstBoundTraitObject { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_tilde_const_disallowed)] pub struct TildeConstDisallowed { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 12d37cf5a7a..0543c8e1d44 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1561,7 +1561,7 @@ impl<'a> State<'a> { GenericBound::Trait(tref, modifier) => { match modifier.constness { ast::BoundConstness::Never => {} - ast::BoundConstness::Maybe(_) => { + ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { self.word_space(modifier.constness.as_str()); } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2b840860166..b76edd554f8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -420,9 +420,15 @@ pub enum GenericArgsParentheses { /// A modifier on a trait bound. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum TraitBoundModifier { + /// `Type: Trait` None, + /// `Type: !Trait` Negative, + /// `Type: ?Trait` Maybe, + /// `Type: const Trait` + Const, + /// `Type: ~const Trait` MaybeConst, } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 139e1c0ac5f..d8b6b9a1272 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -70,7 +70,7 @@ hir_analysis_coercion_between_struct_same_note = expected coercion between the s hir_analysis_coercion_between_struct_single_note = expected a single field to be coerced, none found hir_analysis_const_bound_for_non_const_trait = - ~const can only be applied to `#[const_trait]` traits + `{$modifier}` can only be applied to `#[const_trait]` traits hir_analysis_const_impl_for_non_const_trait = const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]` diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 6e71cf16ee8..91b3807d744 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -112,6 +112,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { match ast_bound { hir::GenericBound::Trait(poly_trait_ref, modifier) => { let (constness, polarity) = match modifier { + hir::TraitBoundModifier::Const => { + (ty::BoundConstness::Const, ty::ImplPolarity::Positive) + } hir::TraitBoundModifier::MaybeConst => { (ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive) } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8197fea5b29..092df257dbf 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -560,11 +560,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { inferred_params: vec![], infer_args, }; - if let ty::BoundConstness::ConstIfConst = constness + if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) { - let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { span }); + let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + span, + modifier: constness.as_str(), + }); arg_count.correct = Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] }); } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 41f30057902..75e7a5524a7 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -408,6 +408,7 @@ pub struct ConstImplForNonConstTrait { pub struct ConstBoundForNonConstTrait { #[primary_span] pub span: Span, + pub modifier: &'static str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9f1ff4538aa..0653796ec7f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -309,23 +309,22 @@ impl Visibility { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] pub enum BoundConstness { - /// `T: Trait` + /// `Type: Trait` NotConst, - /// `T: ~const Trait` + /// `Type: const Trait` + Const, + /// `Type: ~const Trait` /// /// Requires resolving to const only when we are in a const context. ConstIfConst, } impl BoundConstness { - /// Reduce `self` and `constness` to two possible combined states instead of four. - pub fn and(&mut self, constness: hir::Constness) -> hir::Constness { - match (constness, self) { - (hir::Constness::Const, BoundConstness::ConstIfConst) => hir::Constness::Const, - (_, this) => { - *this = BoundConstness::NotConst; - hir::Constness::NotConst - } + pub fn as_str(self) -> &'static str { + match self { + Self::NotConst => "", + Self::Const => "const", + Self::ConstIfConst => "~const", } } } @@ -334,7 +333,7 @@ impl fmt::Display for BoundConstness { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::NotConst => f.write_str("normal"), - Self::ConstIfConst => f.write_str("`~const`"), + _ => write!(f, "`{self}`"), } } } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 363b8f4bfb9..c6bddbfacd6 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -95,9 +95,6 @@ parse_compound_assignment_expression_in_let = can't reassign to an uninitialized .suggestion = initialize the variable .help = if you meant to overwrite, remove the `let` binding -parse_const_bounds_missing_tilde = const bounds must start with `~` - .suggestion = add `~` - parse_const_generic_without_braces = expressions must be enclosed in braces to be used as const generic arguments .suggestion = enclose the `const` expression in braces @@ -555,8 +552,8 @@ parse_missing_trait_in_trait_impl = missing trait in a trait impl .suggestion_add_trait = add a trait here .suggestion_remove_for = for an inherent impl, drop this `for` -parse_modifier_lifetime = `{$sigil}` may only modify trait bounds, not lifetime bounds - .suggestion = remove the `{$sigil}` +parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds + .suggestion = remove the `{$modifier}` parse_more_than_one_char = character literal may only contain one codepoint .followed_by = this `{$chr}` is followed by the combining {$len -> @@ -729,8 +726,6 @@ parse_switch_ref_box_order = switch the order of `ref` and `box` parse_ternary_operator = Rust has no ternary operator .help = use an `if-else` expression instead -parse_tilde_const_lifetime = `~const` may only modify trait bounds, not lifetime bounds - parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator .suggestion = use `!` to perform bitwise not diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 53cce9e2883..e276b34ca37 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2555,20 +2555,13 @@ pub(crate) struct AssocLifetime { pub lifetime: Span, } -#[derive(Diagnostic)] -#[diag(parse_tilde_const_lifetime)] -pub(crate) struct TildeConstLifetime { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(parse_modifier_lifetime)] pub(crate) struct ModifierLifetime { #[primary_span] #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")] pub span: Span, - pub sigil: &'static str, + pub modifier: &'static str, } #[derive(Diagnostic)] @@ -2581,15 +2574,6 @@ pub(crate) struct ParenthesizedLifetime { pub snippet: String, } -#[derive(Diagnostic)] -#[diag(parse_const_bounds_missing_tilde)] -pub(crate) struct ConstMissingTilde { - #[primary_span] - pub span: Span, - #[suggestion(code = "~", applicability = "machine-applicable")] - pub start: Span, -} - #[derive(Diagnostic)] #[diag(parse_underscore_literal_suffix)] pub(crate) struct UnderscoreLiteralSuffix { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 42ab23d6292..4be2c662d03 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -86,6 +86,18 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl) } +fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { + // `Not`, `Tilde` & `Const` are deliberately not part of this list to + // contain the number of potential regressions esp. in MBE code. + // `Const` would regress `rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs`. + // `Not` would regress `dyn!(...)` macro calls in Rust 2015. + t.is_path_start() + || t.is_lifetime() + || t == &TokenKind::Question + || t.is_keyword(kw::For) + || t == &TokenKind::OpenDelim(Delimiter::Parenthesis) +} + impl<'a> Parser<'a> { /// Parses a type. pub fn parse_ty(&mut self) -> PResult<'a, P> { @@ -665,7 +677,8 @@ impl<'a> Parser<'a> { self.check_keyword(kw::Dyn) && (self.token.uninterpolated_span().at_least_rust_2018() || self.look_ahead(1, |t| { - (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star)) + (can_begin_dyn_bound_in_edition_2015(t) + || t.kind == TokenKind::BinOp(token::Star)) && !can_continue_type_after_non_fn_ident(t) })) } @@ -758,12 +771,12 @@ impl<'a> Parser<'a> { /// Can the current token begin a bound? fn can_begin_bound(&mut self) -> bool { - // This needs to be synchronized with `TokenKind::can_begin_bound`. self.check_path() || self.check_lifetime() || self.check(&token::Not) || self.check(&token::Question) || self.check(&token::Tilde) + || self.check_keyword(kw::Const) || self.check_keyword(kw::For) || self.check(&token::OpenDelim(Delimiter::Parenthesis)) } @@ -812,8 +825,11 @@ impl<'a> Parser<'a> { fn error_lt_bound_with_modifiers(&self, modifiers: TraitBoundModifiers) { match modifiers.constness { BoundConstness::Never => {} - BoundConstness::Maybe(span) => { - self.dcx().emit_err(errors::TildeConstLifetime { span }); + BoundConstness::Always(span) | BoundConstness::Maybe(span) => { + self.dcx().emit_err(errors::ModifierLifetime { + span, + modifier: modifiers.constness.as_str(), + }); } } @@ -822,7 +838,7 @@ impl<'a> Parser<'a> { BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => { self.dcx().emit_err(errors::ModifierLifetime { span, - sigil: modifiers.polarity.as_str(), + modifier: modifiers.polarity.as_str(), }); } } @@ -848,7 +864,7 @@ impl<'a> Parser<'a> { /// If no modifiers are present, this does not consume any tokens. /// /// ```ebnf - /// TRAIT_BOUND_MODIFIERS = ["~const"] ["?" | "!"] + /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["?" | "!"] /// ``` fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> { let constness = if self.eat(&token::Tilde) { @@ -858,11 +874,8 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::const_trait_impl, span); BoundConstness::Maybe(span) } else if self.eat_keyword(kw::Const) { - let span = self.prev_token.span; - self.sess.gated_spans.gate(sym::const_trait_impl, span); - self.dcx().emit_err(errors::ConstMissingTilde { span, start: span.shrink_to_lo() }); - - BoundConstness::Maybe(span) + self.sess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span); + BoundConstness::Always(self.prev_token.span) } else { BoundConstness::Never }; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a9c0ab557cb..1923fc15119 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -449,8 +449,8 @@ impl clean::GenericBound { hir::TraitBoundModifier::None => "", hir::TraitBoundModifier::Maybe => "?", hir::TraitBoundModifier::Negative => "!", - // ~const is experimental; do not display those bounds in rustdoc - hir::TraitBoundModifier::MaybeConst => "", + // `const` and `~const` trait bounds are experimental; don't render them. + hir::TraitBoundModifier::Const | hir::TraitBoundModifier::MaybeConst => "", }; if f.alternate() { write!(f, "{modifier_str}{ty:#}", ty = ty.print(cx)) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 513e94afe29..32d7a80863d 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -547,6 +547,9 @@ pub(crate) fn from_trait_bound_modifier( None => TraitBoundModifier::None, Maybe => TraitBoundModifier::Maybe, MaybeConst => TraitBoundModifier::MaybeConst, + // FIXME(const_trait_impl): Create rjt::TBM::Const and map to it once always-const bounds + // are less experimental. + Const => TraitBoundModifier::None, // FIXME(negative-bounds): This bound should be rendered negative, but // since that's experimental, maybe let's not add it to the rustdoc json // API just now... diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index e5ebe1d8528..e6ea4108f40 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -4,13 +4,13 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls` LL | #![feature(const_fn_trait_ref_impls)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:15:15 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:15:15 | LL | T: ~const Fn<()> + ~const Destruct, @@ -18,13 +18,13 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:22:15 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:22:15 | LL | T: ~const FnMut<()> + ~const Destruct, @@ -32,13 +32,13 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:29:15 | LL | T: ~const FnOnce<()>, | ^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:29:15 | LL | T: ~const FnOnce<()>, @@ -46,13 +46,13 @@ LL | T: ~const FnOnce<()>, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:36:15 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:36:15 | LL | T: ~const Fn<()> + ~const Destruct, @@ -60,13 +60,13 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:50:15 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:50:15 | LL | T: ~const FnMut<()> + ~const Destruct, diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr index 4b649bf43ed..08147a4afaf 100644 --- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr +++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/unstable-const-fn-in-libcore.rs:19:39 | LL | const fn unwrap_or_else T>(self, f: F) -> T { diff --git a/tests/ui/generic-const-items/const-trait-impl.rs b/tests/ui/generic-const-items/const-trait-impl.rs index 43cdf818c46..04c3f3eb434 100644 --- a/tests/ui/generic-const-items/const-trait-impl.rs +++ b/tests/ui/generic-const-items/const-trait-impl.rs @@ -1,14 +1,12 @@ -// known-bug: #110395 -// FIXME check-pass +// check-pass // Test that we can call methods from const trait impls inside of generic const items. -#![feature(generic_const_items, const_trait_impl)] +#![feature(generic_const_items, const_trait_impl, effects)] #![allow(incomplete_features)] #![crate_type = "lib"] -// FIXME(generic_const_items, effects): Introduce `const` bounds to make this work. -const CREATE: T = T::create(); +const CREATE: T = T::create(); pub const K0: i32 = CREATE::; pub const K1: i32 = CREATE; // arg inferred @@ -23,3 +21,13 @@ impl const Create for i32 { 4096 } } + +trait Mod { // doesn't need to be a `#[const_trait]` + const CREATE: T; +} + +impl Mod for () { + const CREATE: T = T::create(); +} + +pub const K2: i32 = <() as Mod>::CREATE::; diff --git a/tests/ui/generic-const-items/const-trait-impl.stderr b/tests/ui/generic-const-items/const-trait-impl.stderr deleted file mode 100644 index cdcd24eceff..00000000000 --- a/tests/ui/generic-const-items/const-trait-impl.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0015]: cannot call non-const fn `::create` in constants - --> $DIR/const-trait-impl.rs:11:30 - | -LL | const CREATE: T = T::create(); - | ^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = help: add `#![feature(effects)]` to the crate attributes to enable - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index e0513433b8e..7fd2ec57b14 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/normalize-tait-in-const.rs:25:42 | LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { diff --git a/tests/ui/parser/bounds-type.rs b/tests/ui/parser/bounds-type.rs index 4ae4549ea58..bd5f6105f51 100644 --- a/tests/ui/parser/bounds-type.rs +++ b/tests/ui/parser/bounds-type.rs @@ -13,6 +13,7 @@ struct S< T: ~const ?Tr, // OK T: ~const Tr + 'a, // OK T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds + T: const 'a, //~ ERROR `const` may only modify trait bounds, not lifetime bounds >; fn main() {} diff --git a/tests/ui/parser/bounds-type.stderr b/tests/ui/parser/bounds-type.stderr index 005bc1e54bd..d1210e88d66 100644 --- a/tests/ui/parser/bounds-type.stderr +++ b/tests/ui/parser/bounds-type.stderr @@ -10,5 +10,11 @@ error: `~const` may only modify trait bounds, not lifetime bounds LL | T: ~const 'a, | ^^^^^^ -error: aborting due to 2 previous errors +error: `const` may only modify trait bounds, not lifetime bounds + --> $DIR/bounds-type.rs:16:8 + | +LL | T: const 'a, + | ^^^^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs b/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs new file mode 100644 index 00000000000..fe062d62e5a --- /dev/null +++ b/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs @@ -0,0 +1,16 @@ +// Check that `?Trait` matches the macro fragment specifier `ty`. +// Syntactically trait object types can be "bare" (i.e., lack the prefix `dyn`), +// even in newer editions like Rust 2021. +// Therefore the arm `?$Trait:path` shouldn't get reached. + +// edition: 2021 +// check-pass + +macro_rules! check { + ($Ty:ty) => {}; + (?$Trait:path) => { compile_error!("non-ty"); }; +} + +check! { ?Trait } + +fn main() {} diff --git a/tests/ui/parser/trait-object-delimiters.rs b/tests/ui/parser/trait-object-delimiters.rs index e9b13defe03..240ae3084d6 100644 --- a/tests/ui/parser/trait-object-delimiters.rs +++ b/tests/ui/parser/trait-object-delimiters.rs @@ -8,7 +8,7 @@ fn foo2(_: &dyn (Drop + AsRef)) {} //~ ERROR incorrect parentheses around t fn foo2_no_space(_: &dyn(Drop + AsRef)) {} //~ ERROR incorrect parentheses around trait bounds fn foo3(_: &dyn {Drop + AsRef}) {} //~ ERROR expected parameter name, found `{` -//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` +//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{` //~| ERROR at least one trait is required for an object type fn foo4(_: &dyn >) {} //~ ERROR expected identifier, found `<` diff --git a/tests/ui/parser/trait-object-delimiters.stderr b/tests/ui/parser/trait-object-delimiters.stderr index 51954675093..2ddb734cee0 100644 --- a/tests/ui/parser/trait-object-delimiters.stderr +++ b/tests/ui/parser/trait-object-delimiters.stderr @@ -34,11 +34,11 @@ error: expected parameter name, found `{` LL | fn foo3(_: &dyn {Drop + AsRef}) {} | ^ expected parameter name -error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` +error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{` --> $DIR/trait-object-delimiters.rs:10:17 | LL | fn foo3(_: &dyn {Drop + AsRef}) {} - | -^ expected one of 10 possible tokens + | -^ expected one of 11 possible tokens | | | help: missing `,` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 290ef6e2f5f..58ad1849d4f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -6,7 +6,7 @@ LL | type Bar: ~const std::ops::Add; | = note: this item cannot have `~const` trait bounds -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/assoc-type.rs:17:22 | LL | type Bar: ~const std::ops::Add; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs new file mode 100644 index 00000000000..3582e5e050c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs @@ -0,0 +1,12 @@ +// Regression test for issue #117244. +#![feature(const_trait_impl, effects)] + +trait NonConst {} + +const fn perform() {} +//~^ ERROR `~const` can only be applied to `#[const_trait]` traits + +fn operate() {} +//~^ ERROR `const` can only be applied to `#[const_trait]` traits + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr new file mode 100644 index 00000000000..08954987d31 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr @@ -0,0 +1,14 @@ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-bounds-non-const-trait.rs:6:28 + | +LL | const fn perform() {} + | ^^^^^^^^ + +error: `const` can only be applied to `#[const_trait]` traits + --> $DIR/const-bounds-non-const-trait.rs:9:21 + | +LL | fn operate() {} + | ^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr index fc9b5557a64..ace2e7e46c4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-parse-not-item.rs:7:32 | LL | const fn test() -> impl ~const Fn() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index 73ee0f2151a..d70b0d66177 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method-fail.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr index 33ae7131b92..1642de78692 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr index 6d61b23e4b7..2e448c64d7a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr @@ -1,22 +1,22 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:8:19 | LL | F: ~const FnOnce() -> u8, | ^^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:9:19 | LL | F: ~const FnMut() -> u8, | ^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:10:19 | LL | F: ~const Fn() -> u8, | ^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:23:27 | LL | const fn answer u8>(f: &F) -> u8 { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr index 13350a6d14a..7529af9293d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr @@ -7,7 +7,7 @@ LL | impl const Drop for ConstDropImplWithBounds { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail-2.rs:29:26 | LL | const fn check(_: T) {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr index 13350a6d14a..7529af9293d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr @@ -7,7 +7,7 @@ LL | impl const Drop for ConstDropImplWithBounds { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail-2.rs:29:26 | LL | const fn check(_: T) {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr index daaba08d7dd..f166bdf6cec 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr @@ -1,10 +1,15 @@ -error: `~const` is not allowed here - --> $DIR/const-drop.rs:67:38 +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> $DIR/const-drop.rs:19:32 | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^^ +LL | const fn a(_: T) {} + | ^ the destructor for this type cannot be evaluated in constant functions + +error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time + --> $DIR/const-drop.rs:24:13 | - = note: this item cannot have `~const` trait bounds +LL | let _ = S(&mut c); + | ^^^^^^^^^ the destructor for this type cannot be evaluated in constant functions -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs index 9da84cdb052..4836d2b02ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs @@ -4,7 +4,7 @@ #![feature(const_trait_impl)] #![feature(const_mut_refs)] #![feature(never_type)] -// #![cfg_attr(precise, feature(const_precise_live_drops))] +#![cfg_attr(precise, feature(const_precise_live_drops))] use std::marker::Destruct; @@ -63,8 +63,7 @@ mod t { fn foo() {} } - // FIXME(effects): This should be a `const` bound instead of a `~const` one. - pub struct ConstDropWithBound(pub core::marker::PhantomData); + pub struct ConstDropWithBound(pub core::marker::PhantomData); impl const Drop for ConstDropWithBound { fn drop(&mut self) { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr index daaba08d7dd..23e36887025 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr @@ -1,10 +1,19 @@ -error: `~const` is not allowed here - --> $DIR/const-drop.rs:67:38 +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> $DIR/const-drop.rs:19:32 | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^^ +LL | const fn a(_: T) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time + --> $DIR/const-drop.rs:24:13 | - = note: this item cannot have `~const` trait bounds +LL | let _ = S(&mut c); + | ^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs new file mode 100644 index 00000000000..86706671316 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs @@ -0,0 +1,9 @@ +#![feature(const_trait_impl)] +// edition: 2021 + +#[const_trait] +trait Trait {} + +fn main() { + let _: &dyn const Trait; //~ ERROR const trait bounds are not allowed in trait object types +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr new file mode 100644 index 00000000000..8b9ba94d099 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr @@ -0,0 +1,8 @@ +error: const trait bounds are not allowed in trait object types + --> $DIR/const-trait-bounds-trait-objects.rs:8:17 + | +LL | let _: &dyn const Trait; + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs new file mode 100644 index 00000000000..1ebebe632c7 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs @@ -0,0 +1,31 @@ +// check-pass + +#![feature(const_trait_impl, effects, generic_const_exprs)] +#![allow(incomplete_features)] + +fn main() { + let _ = process::<()>([()]); + let _ = Struct::<(), 4> { field: [1, 0] }; +} + +fn process(input: [(); T::make(2)]) -> [(); T::make(2)] { + input +} + +struct Struct +where + [u32; T::make(P)]:, +{ + field: [u32; T::make(P)], +} + +#[const_trait] +trait Trait { + fn make(input: usize) -> usize; +} + +impl const Trait for () { + fn make(input: usize) -> usize { + input / 2 + } +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs index 61e31fc9786..c6be75a6a2f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs @@ -1,6 +1,6 @@ #![feature(const_trait_impl, effects)] -const fn test() -> impl ~const Fn() { //~ ERROR ~const can only be applied to `#[const_trait]` traits +const fn test() -> impl ~const Fn() { //~ ERROR `~const` can only be applied to `#[const_trait]` traits const move || { //~ ERROR const closures are experimental let sl: &[u8] = b"foo"; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr index 65808212314..fe6b613d154 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr @@ -7,7 +7,7 @@ LL | const move || { = note: see issue #106003 for more information = help: add `#![feature(const_closures)]` to the crate attributes to enable -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/ice-112822-expected-type-for-param.rs:3:32 | LL | const fn test() -> impl ~const Fn() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr index 663cdd1fe57..12f9355e41d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/feature-gate.rs:14:1 + --> $DIR/feature-gate.rs:22:1 | LL | fn main() {} | ^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs index 0b409fbaac9..015d90aaf21 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs @@ -10,5 +10,13 @@ trait T {} impl const T for S {} //[stock]~^ ERROR const trait impls are experimental +const fn f() {} //[stock]~ ERROR const trait impls are experimental +fn g() {} //[stock]~ ERROR const trait impls are experimental + +macro_rules! discard { ($ty:ty) => {} } + +discard! { impl ~const T } //[stock]~ ERROR const trait impls are experimental +discard! { impl const T } //[stock]~ ERROR const trait impls are experimental + #[rustc_error] fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr index 0e938c1c55d..c9826aeb166 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr @@ -7,6 +7,42 @@ LL | impl const T for S {} = note: see issue #67792 for more information = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:13:15 + | +LL | const fn f() {} + | ^^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:14:9 + | +LL | fn g() {} + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:18:17 + | +LL | discard! { impl ~const T } + | ^^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:19:17 + | +LL | discard! { impl const T } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. --> $DIR/feature-gate.rs:8:1 | @@ -16,6 +52,6 @@ LL | #[const_trait] = note: see issue #67792 for more information = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs new file mode 100644 index 00000000000..2304a766aaf --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs @@ -0,0 +1,20 @@ +// Ensure that we don't consider `const Trait` and `~const Trait` to +// match the macro fragment specifier `ty` as that would be a breaking +// change theoretically speaking. Syntactically trait object types can +// be "bare", i.e., lack the prefix `dyn`. +// By contrast, `?Trait` *does* match `ty` and therefore an arm like +// `?$Trait:path` would never be reached. +// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`. + +// check-pass + +macro_rules! check { + ($Type:ty) => { compile_error!("ty"); }; + (const $Trait:path) => {}; + (~const $Trait:path) => {}; +} + +check! { const Trait } +check! { ~const Trait } + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs new file mode 100644 index 00000000000..9105cb6b043 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs @@ -0,0 +1,20 @@ +// Demonstrates and records a theoretical regressions / breaking changes caused by the +// introduction of const trait bounds. + +// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018. +// edition:2018 + +macro_rules! demo { + ($ty:ty) => { compile_error!("ty"); }; + (impl $c:ident) => {}; + (dyn $c:ident) => {}; +} + +demo! { impl const } +//~^ ERROR expected identifier, found `` + +demo! { dyn const } +//~^ ERROR const trait impls are experimental +//~| ERROR expected identifier, found `` + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr new file mode 100644 index 00000000000..254d31930b3 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr @@ -0,0 +1,30 @@ +error: expected identifier, found `` + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:13:14 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ------ while parsing argument for this `ty` macro fragment +... +LL | demo! { impl const } + | ^^^^^ expected identifier + +error: expected identifier, found `` + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ------ while parsing argument for this `ty` macro fragment +... +LL | demo! { dyn const } + | ^^^^^ expected identifier + +error[E0658]: const trait impls are experimental + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13 + | +LL | demo! { dyn const } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs new file mode 100644 index 00000000000..817e9ee5257 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs @@ -0,0 +1,13 @@ +// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015. +// See also `mbe-const-trait-bound-theoretical-regression.rs`. + +// check-pass + +macro_rules! check { + ($ty:ty) => { compile_error!("ty"); }; + (dyn $c:ident) => {}; +} + +check! { dyn const } + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs new file mode 100644 index 00000000000..37e285f2c65 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs @@ -0,0 +1,20 @@ +#![feature(const_trait_impl)] + +const fn maybe_const_maybe() {} +//~^ ERROR `~const` and `?` are mutually exclusive + +fn const_maybe() {} +//~^ ERROR `const` and `?` are mutually exclusive + +const fn maybe_const_negative() {} +//~^ ERROR `~const` and `!` are mutually exclusive +//~| ERROR negative bounds are not supported + +fn const_negative() {} +//~^ ERROR `const` and `!` are mutually exclusive +//~| ERROR negative bounds are not supported + +#[const_trait] +trait Trait {} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr new file mode 100644 index 00000000000..1938f740170 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr @@ -0,0 +1,38 @@ +error: `~const` and `?` are mutually exclusive + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31 + | +LL | const fn maybe_const_maybe() {} + | ^^^^^^^^^^^^^ + +error: `const` and `?` are mutually exclusive + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:19 + | +LL | fn const_maybe() {} + | ^^^^^^^^^^^^ + +error: `~const` and `!` are mutually exclusive + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:34 + | +LL | const fn maybe_const_negative() {} + | ^^^^^^^^^^^^^ + +error: `const` and `!` are mutually exclusive + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:22 + | +LL | fn const_negative() {} + | ^^^^^^^^^^^^ + +error: negative bounds are not supported + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41 + | +LL | const fn maybe_const_negative() {} + | ^ + +error: negative bounds are not supported + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + | +LL | fn const_negative() {} + | ^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr index b2e09d82a90..ae76cab2f2e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -1,4 +1,4 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/non-const-op-in-closure-in-const.rs:10:51 | LL | impl const Convert for A where B: ~const From { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index fd4d7ff3475..eae313ef087 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -10,13 +10,13 @@ note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bou LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index d2e3a5cec1d..be3153d6a08 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -1,10 +1,10 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 3820d069243..abdf0feee03 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -8,8 +8,8 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} -//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` -//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` +//[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[yn,nn]~^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index 199d2199c4a..834d6f4dcf3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -10,13 +10,13 @@ note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bou LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} @@ -24,7 +24,7 @@ LL | trait Bar: ~const Foo {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:17:24 | LL | const fn foo(x: &T) { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 46eedc333f1..4fdd2284c47 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,10 +1,10 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index 3e98e131930..30131d5849c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -10,12 +10,12 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} -//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` -//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` +//[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[yn,nn]~^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { - //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` + //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` x.a(); } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index dc08a899738..ab7c814eb49 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -10,7 +10,7 @@ note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bou LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:17:24 | LL | const fn foo(x: &T) { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.rs deleted file mode 100644 index ed911d965d6..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(const_trait_impl)] - -const fn tilde_question() {} -//~^ ERROR `~const` and `?` are mutually exclusive - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.stderr deleted file mode 100644 index 5850ab41c6b..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-maybe-trait.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `~const` and `?` are mutually exclusive - --> $DIR/tilde-const-maybe-trait.rs:3:28 - | -LL | const fn tilde_question() {} - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.rs deleted file mode 100644 index d63381b5f2c..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags: -Z parse-only - -#![feature(const_trait_impl)] - -struct S; -//~^ ERROR const bounds must start with `~` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.stderr deleted file mode 100644 index 646cdfc78f9..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/without-tilde.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: const bounds must start with `~` - --> $DIR/without-tilde.rs:5:13 - | -LL | struct S; - | -^^^^ - | | - | help: add `~`: `~` - -error: aborting due to 1 previous error - diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index d13cd8f5555..913d51875cd 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,16 +1,16 @@ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:34:16 | LL | impl const A for T { | ^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:40:16 | LL | impl const A for T { | ^^^^^^^ -error: ~const can only be applied to `#[const_trait]` traits +error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:46:16 | LL | impl const A for T {