Rollup merge of #119505 - fmease:no-host-param-for-trait-fns, r=fee1-dead
Don't synthesize host effect params for trait associated functions marked const Fixes #113378. r? fee1-dead or compiler
This commit is contained in:
commit
8bce6fc35e
@ -1241,11 +1241,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
coroutine_kind: Option<CoroutineKind>,
|
coroutine_kind: Option<CoroutineKind>,
|
||||||
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
||||||
let header = self.lower_fn_header(sig.header);
|
let header = self.lower_fn_header(sig.header);
|
||||||
|
// Don't pass along the user-provided constness of trait associated functions; we don't want to
|
||||||
|
// synthesize a host effect param for them. We reject `const` on them during AST validation.
|
||||||
|
let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
|
||||||
let itctx = ImplTraitContext::Universal;
|
let itctx = ImplTraitContext::Universal;
|
||||||
let (generics, decl) =
|
let (generics, decl) = self.lower_generics(generics, constness, id, &itctx, |this| {
|
||||||
self.lower_generics(generics, sig.header.constness, id, &itctx, |this| {
|
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
|
||||||
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
|
});
|
||||||
});
|
|
||||||
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +233,21 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
|
|||||||
.item = this item cannot have `~const` trait bounds
|
.item = this item cannot have `~const` trait bounds
|
||||||
|
|
||||||
ast_passes_trait_fn_const =
|
ast_passes_trait_fn_const =
|
||||||
functions in traits cannot be declared const
|
functions in {$in_impl ->
|
||||||
.label = functions in traits cannot be const
|
[true] trait impls
|
||||||
|
*[false] traits
|
||||||
|
} cannot be declared const
|
||||||
|
.label = functions in {$in_impl ->
|
||||||
|
[true] trait impls
|
||||||
|
*[false] traits
|
||||||
|
} cannot be const
|
||||||
|
.const_context_label = this declares all associated functions implicitly const
|
||||||
|
.remove_const_sugg = remove the `const`{$requires_multiple_changes ->
|
||||||
|
[true] {" ..."}
|
||||||
|
*[false] {""}
|
||||||
|
}
|
||||||
|
.make_impl_const_sugg = ... and declare the impl to be const instead
|
||||||
|
.make_trait_const_sugg = ... and declare the trait to be a `#[const_trait]` instead
|
||||||
|
|
||||||
ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
|
ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
|
||||||
|
|
||||||
|
@ -46,6 +46,21 @@ enum DisallowTildeConstContext<'a> {
|
|||||||
Item,
|
Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TraitOrTraitImpl<'a> {
|
||||||
|
Trait { span: Span, constness: Option<Span> },
|
||||||
|
TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: &'a TraitRef },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TraitOrTraitImpl<'a> {
|
||||||
|
fn constness(&self) -> Option<Span> {
|
||||||
|
match self {
|
||||||
|
Self::Trait { constness: Some(span), .. }
|
||||||
|
| Self::TraitImpl { constness: Const::Yes(span), .. } => Some(*span),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct AstValidator<'a> {
|
struct AstValidator<'a> {
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
features: &'a Features,
|
features: &'a Features,
|
||||||
@ -53,11 +68,7 @@ struct AstValidator<'a> {
|
|||||||
/// The span of the `extern` in an `extern { ... }` block, if any.
|
/// The span of the `extern` in an `extern { ... }` block, if any.
|
||||||
extern_mod: Option<&'a Item>,
|
extern_mod: Option<&'a Item>,
|
||||||
|
|
||||||
/// Are we inside a trait impl?
|
outer_trait_or_trait_impl: Option<TraitOrTraitImpl<'a>>,
|
||||||
in_trait_impl: bool,
|
|
||||||
|
|
||||||
/// Are we inside a const trait defn or impl?
|
|
||||||
in_const_trait_or_impl: bool,
|
|
||||||
|
|
||||||
has_proc_macro_decls: bool,
|
has_proc_macro_decls: bool,
|
||||||
|
|
||||||
@ -78,24 +89,28 @@ struct AstValidator<'a> {
|
|||||||
impl<'a> AstValidator<'a> {
|
impl<'a> AstValidator<'a> {
|
||||||
fn with_in_trait_impl(
|
fn with_in_trait_impl(
|
||||||
&mut self,
|
&mut self,
|
||||||
is_in: bool,
|
trait_: Option<(Const, ImplPolarity, &'a TraitRef)>,
|
||||||
constness: Option<Const>,
|
|
||||||
f: impl FnOnce(&mut Self),
|
f: impl FnOnce(&mut Self),
|
||||||
) {
|
) {
|
||||||
let old = mem::replace(&mut self.in_trait_impl, is_in);
|
let old = mem::replace(
|
||||||
let old_const = mem::replace(
|
&mut self.outer_trait_or_trait_impl,
|
||||||
&mut self.in_const_trait_or_impl,
|
trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl {
|
||||||
matches!(constness, Some(Const::Yes(_))),
|
constness,
|
||||||
|
polarity,
|
||||||
|
trait_ref,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
f(self);
|
f(self);
|
||||||
self.in_trait_impl = old;
|
self.outer_trait_or_trait_impl = old;
|
||||||
self.in_const_trait_or_impl = old_const;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_in_trait(&mut self, is_const: bool, f: impl FnOnce(&mut Self)) {
|
fn with_in_trait(&mut self, span: Span, constness: Option<Span>, f: impl FnOnce(&mut Self)) {
|
||||||
let old = mem::replace(&mut self.in_const_trait_or_impl, is_const);
|
let old = mem::replace(
|
||||||
|
&mut self.outer_trait_or_trait_impl,
|
||||||
|
Some(TraitOrTraitImpl::Trait { span, constness }),
|
||||||
|
);
|
||||||
f(self);
|
f(self);
|
||||||
self.in_const_trait_or_impl = old;
|
self.outer_trait_or_trait_impl = old;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
|
fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
|
||||||
@ -291,10 +306,48 @@ impl<'a> AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_fn_not_const(&self, constness: Const) {
|
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'a>) {
|
||||||
if let Const::Yes(span) = constness {
|
let Const::Yes(span) = constness else {
|
||||||
self.dcx().emit_err(errors::TraitFnConst { span });
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let make_impl_const_sugg = if self.features.const_trait_impl
|
||||||
|
&& let TraitOrTraitImpl::TraitImpl {
|
||||||
|
constness: Const::No,
|
||||||
|
polarity: ImplPolarity::Positive,
|
||||||
|
trait_ref,
|
||||||
|
} = parent
|
||||||
|
{
|
||||||
|
Some(trait_ref.path.span.shrink_to_lo())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let make_trait_const_sugg = if self.features.const_trait_impl
|
||||||
|
&& let TraitOrTraitImpl::Trait { span, constness: None } = parent
|
||||||
|
{
|
||||||
|
Some(span.shrink_to_lo())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let parent_constness = parent.constness();
|
||||||
|
self.dcx().emit_err(errors::TraitFnConst {
|
||||||
|
span,
|
||||||
|
in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
|
||||||
|
const_context_label: parent_constness,
|
||||||
|
remove_const_sugg: (
|
||||||
|
self.session.source_map().span_extend_while(span, |c| c == ' ').unwrap_or(span),
|
||||||
|
match parent_constness {
|
||||||
|
Some(_) => rustc_errors::Applicability::MachineApplicable,
|
||||||
|
None => rustc_errors::Applicability::MaybeIncorrect,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
requires_multiple_changes: make_impl_const_sugg.is_some()
|
||||||
|
|| make_trait_const_sugg.is_some(),
|
||||||
|
make_impl_const_sugg,
|
||||||
|
make_trait_const_sugg,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||||
@ -817,7 +870,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
self_ty,
|
self_ty,
|
||||||
items,
|
items,
|
||||||
}) => {
|
}) => {
|
||||||
self.with_in_trait_impl(true, Some(*constness), |this| {
|
self.with_in_trait_impl(Some((*constness, *polarity, t)), |this| {
|
||||||
this.visibility_not_permitted(
|
this.visibility_not_permitted(
|
||||||
&item.vis,
|
&item.vis,
|
||||||
errors::VisibilityNotPermittedNote::TraitImpl,
|
errors::VisibilityNotPermittedNote::TraitImpl,
|
||||||
@ -963,8 +1016,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
|
ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
|
||||||
let is_const_trait = attr::contains_name(&item.attrs, sym::const_trait);
|
let is_const_trait =
|
||||||
self.with_in_trait(is_const_trait, |this| {
|
attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span);
|
||||||
|
self.with_in_trait(item.span, is_const_trait, |this| {
|
||||||
if *is_auto == IsAuto::Yes {
|
if *is_auto == IsAuto::Yes {
|
||||||
// Auto traits cannot have generics, super traits nor contain items.
|
// Auto traits cannot have generics, super traits nor contain items.
|
||||||
this.deny_generic_params(generics, item.ident.span);
|
this.deny_generic_params(generics, item.ident.span);
|
||||||
@ -977,8 +1031,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
// context for the supertraits.
|
// context for the supertraits.
|
||||||
this.visit_vis(&item.vis);
|
this.visit_vis(&item.vis);
|
||||||
this.visit_ident(item.ident);
|
this.visit_ident(item.ident);
|
||||||
let disallowed =
|
let disallowed = is_const_trait
|
||||||
(!is_const_trait).then(|| DisallowTildeConstContext::Trait(item.span));
|
.is_none()
|
||||||
|
.then(|| DisallowTildeConstContext::Trait(item.span));
|
||||||
this.with_tilde_const(disallowed, |this| {
|
this.with_tilde_const(disallowed, |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
|
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
|
||||||
@ -1342,7 +1397,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
|
|
||||||
let tilde_const_allowed =
|
let tilde_const_allowed =
|
||||||
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
|
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
|
||||||
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
|
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)))
|
||||||
|
&& self
|
||||||
|
.outer_trait_or_trait_impl
|
||||||
|
.as_ref()
|
||||||
|
.and_then(TraitOrTraitImpl::constness)
|
||||||
|
.is_some();
|
||||||
|
|
||||||
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
|
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
|
||||||
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
|
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
|
||||||
@ -1353,7 +1413,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
self.check_nomangle_item_asciionly(item.ident, item.span);
|
self.check_nomangle_item_asciionly(item.ident, item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Trait || !self.in_trait_impl {
|
if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
|
||||||
self.check_defaultness(item.span, item.kind.defaultness());
|
self.check_defaultness(item.span, item.kind.defaultness());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1401,10 +1461,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
|
if let Some(parent) = &self.outer_trait_or_trait_impl {
|
||||||
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
|
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
|
||||||
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
|
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
|
||||||
self.check_trait_fn_not_const(sig.header.constness);
|
self.check_trait_fn_not_const(sig.header.constness, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1414,7 +1474,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
|
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
|
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
|
||||||
if self.in_const_trait_or_impl
|
if self
|
||||||
|
.outer_trait_or_trait_impl
|
||||||
|
.as_ref()
|
||||||
|
.and_then(TraitOrTraitImpl::constness)
|
||||||
|
.is_some()
|
||||||
|| ctxt == AssocCtxt::Trait
|
|| ctxt == AssocCtxt::Trait
|
||||||
|| matches!(sig.header.constness, Const::Yes(_)) =>
|
|| matches!(sig.header.constness, Const::Yes(_)) =>
|
||||||
{
|
{
|
||||||
@ -1430,8 +1494,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
);
|
);
|
||||||
self.visit_fn(kind, item.span, item.id);
|
self.visit_fn(kind, item.span, item.id);
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
|
||||||
.with_in_trait_impl(false, None, |this| visit::walk_assoc_item(this, item, ctxt)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1547,8 +1610,7 @@ pub fn check_crate(
|
|||||||
session,
|
session,
|
||||||
features,
|
features,
|
||||||
extern_mod: None,
|
extern_mod: None,
|
||||||
in_trait_impl: false,
|
outer_trait_or_trait_impl: None,
|
||||||
in_const_trait_or_impl: false,
|
|
||||||
has_proc_macro_decls: false,
|
has_proc_macro_decls: false,
|
||||||
outer_impl_trait: None,
|
outer_impl_trait: None,
|
||||||
disallow_tilde_const: Some(DisallowTildeConstContext::Item),
|
disallow_tilde_const: Some(DisallowTildeConstContext::Item),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Errors emitted by ast_passes.
|
//! Errors emitted by ast_passes.
|
||||||
|
|
||||||
use rustc_ast::ParamKindOrd;
|
use rustc_ast::ParamKindOrd;
|
||||||
use rustc_errors::AddToDiagnostic;
|
use rustc_errors::{AddToDiagnostic, Applicability};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||||
|
|
||||||
@ -49,6 +49,24 @@ pub struct TraitFnConst {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub in_impl: bool,
|
||||||
|
#[label(ast_passes_const_context_label)]
|
||||||
|
pub const_context_label: Option<Span>,
|
||||||
|
#[suggestion(ast_passes_remove_const_sugg, code = "")]
|
||||||
|
pub remove_const_sugg: (Span, Applicability),
|
||||||
|
pub requires_multiple_changes: bool,
|
||||||
|
#[suggestion(
|
||||||
|
ast_passes_make_impl_const_sugg,
|
||||||
|
code = "const ",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub make_impl_const_sugg: Option<Span>,
|
||||||
|
#[suggestion(
|
||||||
|
ast_passes_make_trait_const_sugg,
|
||||||
|
code = "#[const_trait]\n",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub make_trait_const_sugg: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -6,6 +6,10 @@ Erroneous code example:
|
|||||||
trait Foo {
|
trait Foo {
|
||||||
const fn bar() -> u32; // error!
|
const fn bar() -> u32; // error!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Foo for () {
|
||||||
|
const fn bar() -> u32 { 0 } // error!
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Trait methods cannot be declared `const` by design. For more information, see
|
Trait methods cannot be declared `const` by design. For more information, see
|
||||||
|
@ -315,7 +315,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
|
|
||||||
if is_host_effect {
|
if is_host_effect {
|
||||||
if let Some(idx) = host_effect_index {
|
if let Some(idx) = host_effect_index {
|
||||||
bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
|
tcx.dcx().span_delayed_bug(
|
||||||
|
param.span,
|
||||||
|
format!("parent also has host effect param? index: {idx}, def: {def_id:?}"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
host_effect_index = Some(index as usize);
|
host_effect_index = Some(index as usize);
|
||||||
|
@ -9,7 +9,7 @@ trait Foo {
|
|||||||
|
|
||||||
impl Foo for u32 {
|
impl Foo for u32 {
|
||||||
const fn f() -> u32 {
|
const fn f() -> u32 {
|
||||||
//~^ ERROR functions in traits cannot be declared const
|
//~^ ERROR functions in trait impls cannot be declared const
|
||||||
22
|
22
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
--> $DIR/const-fn-mismatch.rs:11:5
|
--> $DIR/const-fn-mismatch.rs:11:5
|
||||||
|
|
|
|
||||||
LL | const fn f() -> u32 {
|
LL | const fn f() -> u32 {
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -2,13 +2,19 @@ error[E0379]: functions in traits cannot be declared const
|
|||||||
--> $DIR/const-fn-not-in-trait.rs:5:5
|
--> $DIR/const-fn-not-in-trait.rs:5:5
|
||||||
|
|
|
|
||||||
LL | const fn f() -> u32;
|
LL | const fn f() -> u32;
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in traits cannot be declared const
|
||||||
--> $DIR/const-fn-not-in-trait.rs:7:5
|
--> $DIR/const-fn-not-in-trait.rs:7:5
|
||||||
|
|
|
|
||||||
LL | const fn g() -> u32 {
|
LL | const fn g() -> u32 {
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@ error[E0379]: functions in traits cannot be declared const
|
|||||||
--> $DIR/issue-54954.rs:5:5
|
--> $DIR/issue-54954.rs:5:5
|
||||||
|
|
|
|
||||||
LL | const fn const_val<T: Sized>() -> usize {
|
LL | const fn const_val<T: Sized>() -> usize {
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
|
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
|
||||||
--> $DIR/issue-54954.rs:1:24
|
--> $DIR/issue-54954.rs:1:24
|
||||||
|
@ -8,7 +8,7 @@ trait Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Foo for u32 {
|
impl Foo for u32 {
|
||||||
const fn foo() -> u32 { 0 } //~ ERROR functions in traits cannot be declared const
|
const fn foo() -> u32 { 0 } //~ ERROR functions in trait impls cannot be declared const
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Bar {}
|
trait Bar {}
|
||||||
|
@ -2,19 +2,28 @@ error[E0379]: functions in traits cannot be declared const
|
|||||||
--> $DIR/feature-gate-min_const_fn.rs:6:5
|
--> $DIR/feature-gate-min_const_fn.rs:6:5
|
||||||
|
|
|
|
||||||
LL | const fn foo() -> u32;
|
LL | const fn foo() -> u32;
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in traits cannot be declared const
|
||||||
--> $DIR/feature-gate-min_const_fn.rs:7:5
|
--> $DIR/feature-gate-min_const_fn.rs:7:5
|
||||||
|
|
|
|
||||||
LL | const fn bar() -> u32 { 0 }
|
LL | const fn bar() -> u32 { 0 }
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
--> $DIR/feature-gate-min_const_fn.rs:11:5
|
--> $DIR/feature-gate-min_const_fn.rs:11:5
|
||||||
|
|
|
|
||||||
LL | const fn foo() -> u32 { 0 }
|
LL | const fn foo() -> u32 { 0 }
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -2,13 +2,19 @@ error[E0379]: functions in traits cannot be declared const
|
|||||||
--> $DIR/const-fn-in-trait.rs:3:5
|
--> $DIR/const-fn-in-trait.rs:3:5
|
||||||
|
|
|
|
||||||
LL | const fn g();
|
LL | const fn g();
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
--> $DIR/const-fn-in-trait.rs:7:5
|
--> $DIR/const-fn-in-trait.rs:7:5
|
||||||
|
|
|
|
||||||
LL | const fn f() -> u32 { 22 }
|
LL | const fn f() -> u32 { 22 }
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@ fn main() {
|
|||||||
impl X for Y {
|
impl X for Y {
|
||||||
async fn ft1() {} // OK.
|
async fn ft1() {} // OK.
|
||||||
unsafe fn ft2() {} // OK.
|
unsafe fn ft2() {} // OK.
|
||||||
const fn ft3() {} //~ ERROR functions in traits cannot be declared const
|
const fn ft3() {} //~ ERROR functions in trait impls cannot be declared const
|
||||||
extern "C" fn ft4() {}
|
extern "C" fn ft4() {}
|
||||||
const async unsafe extern "C" fn ft5() {}
|
const async unsafe extern "C" fn ft5() {}
|
||||||
//~^ ERROR functions in traits cannot be declared const
|
//~^ ERROR functions in trait impls cannot be declared const
|
||||||
//~| ERROR functions cannot be both `const` and `async`
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,13 +11,19 @@ error[E0379]: functions in traits cannot be declared const
|
|||||||
--> $DIR/fn-header-semantic-fail.rs:18:9
|
--> $DIR/fn-header-semantic-fail.rs:18:9
|
||||||
|
|
|
|
||||||
LL | const fn ft3();
|
LL | const fn ft3();
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in traits cannot be declared const
|
||||||
--> $DIR/fn-header-semantic-fail.rs:20:9
|
--> $DIR/fn-header-semantic-fail.rs:20:9
|
||||||
|
|
|
|
||||||
LL | const async unsafe extern "C" fn ft5();
|
LL | const async unsafe extern "C" fn ft5();
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: functions cannot be both `const` and `async`
|
error: functions cannot be both `const` and `async`
|
||||||
--> $DIR/fn-header-semantic-fail.rs:20:9
|
--> $DIR/fn-header-semantic-fail.rs:20:9
|
||||||
@ -28,17 +34,23 @@ LL | const async unsafe extern "C" fn ft5();
|
|||||||
| | `async` because of this
|
| | `async` because of this
|
||||||
| `const` because of this
|
| `const` because of this
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
--> $DIR/fn-header-semantic-fail.rs:29:9
|
--> $DIR/fn-header-semantic-fail.rs:29:9
|
||||||
|
|
|
|
||||||
LL | const fn ft3() {}
|
LL | const fn ft3() {}
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error[E0379]: functions in traits cannot be declared const
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
--> $DIR/fn-header-semantic-fail.rs:31:9
|
--> $DIR/fn-header-semantic-fail.rs:31:9
|
||||||
|
|
|
|
||||||
LL | const async unsafe extern "C" fn ft5() {}
|
LL | const async unsafe extern "C" fn ft5() {}
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
error: functions cannot be both `const` and `async`
|
error: functions cannot be both `const` and `async`
|
||||||
--> $DIR/fn-header-semantic-fail.rs:31:9
|
--> $DIR/fn-header-semantic-fail.rs:31:9
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
// Regression test for issue #113378.
|
||||||
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Trait {
|
||||||
|
const fn fun(); //~ ERROR functions in traits cannot be declared const
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Trait for () {
|
||||||
|
const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u32 {
|
||||||
|
const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
|
||||||
|
}
|
||||||
|
|
||||||
|
trait NonConst {
|
||||||
|
const fn fun(); //~ ERROR functions in traits cannot be declared const
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,59 @@
|
|||||||
|
error[E0379]: functions in traits cannot be declared const
|
||||||
|
--> $DIR/trait-fn-const.rs:6:5
|
||||||
|
|
|
||||||
|
LL | #[const_trait]
|
||||||
|
| -------------- this declares all associated functions implicitly const
|
||||||
|
LL | trait Trait {
|
||||||
|
LL | const fn fun();
|
||||||
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in traits cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
|
--> $DIR/trait-fn-const.rs:10:5
|
||||||
|
|
|
||||||
|
LL | impl const Trait for () {
|
||||||
|
| ----- this declares all associated functions implicitly const
|
||||||
|
LL | const fn fun() {}
|
||||||
|
| ^^^^^-
|
||||||
|
| |
|
||||||
|
| functions in trait impls cannot be const
|
||||||
|
| help: remove the `const`
|
||||||
|
|
||||||
|
error[E0379]: functions in trait impls cannot be declared const
|
||||||
|
--> $DIR/trait-fn-const.rs:14:5
|
||||||
|
|
|
||||||
|
LL | const fn fun() {}
|
||||||
|
| ^^^^^ functions in trait impls cannot be const
|
||||||
|
|
|
||||||
|
help: remove the `const` ...
|
||||||
|
|
|
||||||
|
LL - const fn fun() {}
|
||||||
|
LL + fn fun() {}
|
||||||
|
|
|
||||||
|
help: ... and declare the impl to be const instead
|
||||||
|
|
|
||||||
|
LL | impl const Trait for u32 {
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error[E0379]: functions in traits cannot be declared const
|
||||||
|
--> $DIR/trait-fn-const.rs:18:5
|
||||||
|
|
|
||||||
|
LL | const fn fun();
|
||||||
|
| ^^^^^ functions in traits cannot be const
|
||||||
|
|
|
||||||
|
help: remove the `const` ...
|
||||||
|
|
|
||||||
|
LL - const fn fun();
|
||||||
|
LL + fn fun();
|
||||||
|
|
|
||||||
|
help: ... and declare the trait to be a `#[const_trait]` instead
|
||||||
|
|
|
||||||
|
LL + #[const_trait]
|
||||||
|
LL | trait NonConst {
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0379`.
|
Loading…
x
Reference in New Issue
Block a user