parser: move restrictions re. self
to ast_validation
.
This commit is contained in:
parent
cdd41ea5fc
commit
8674efdb7c
@ -23,6 +23,12 @@ use syntax::print::pprust;
|
||||
use syntax::visit::{self, Visitor};
|
||||
use syntax::walk_list;
|
||||
|
||||
/// Is `self` allowed semantically as the first parameter in an `FnDecl`?
|
||||
enum SelfSemantic {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
/// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`).
|
||||
#[derive(Clone, Copy)]
|
||||
enum BoundContext {
|
||||
@ -302,7 +308,13 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn_decl(&self, fn_decl: &FnDecl) {
|
||||
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
self.check_decl_cvaradic_pos(fn_decl);
|
||||
self.check_decl_attrs(fn_decl);
|
||||
self.check_decl_self_param(fn_decl, self_semantic);
|
||||
}
|
||||
|
||||
fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
|
||||
match &*fn_decl.inputs {
|
||||
[Param { ty, span, .. }] => {
|
||||
if let TyKind::CVarArgs = ty.kind {
|
||||
@ -324,7 +336,9 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_decl_attrs(&self, fn_decl: &FnDecl) {
|
||||
fn_decl
|
||||
.inputs
|
||||
.iter()
|
||||
@ -352,6 +366,21 @@ impl<'a> AstValidator<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
|
||||
if param.is_self() {
|
||||
self.err_handler()
|
||||
.struct_span_err(
|
||||
param.span,
|
||||
"`self` parameter only allowed in associated `fn`s",
|
||||
)
|
||||
.span_label(param.span, "not semantically valid as function parameter")
|
||||
.note("associated `fn`s are those in `impl` or `trait` definitions")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
|
||||
if let Defaultness::Default = defaultness {
|
||||
self.err_handler()
|
||||
@ -504,7 +533,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match &expr.kind {
|
||||
ExprKind::Closure(_, _, _, fn_decl, _, _) => {
|
||||
self.check_fn_decl(fn_decl);
|
||||
self.check_fn_decl(fn_decl, SelfSemantic::No);
|
||||
}
|
||||
ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
|
||||
struct_span_err!(
|
||||
@ -524,7 +553,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
match ty.kind {
|
||||
TyKind::BareFn(ref bfty) => {
|
||||
self.check_fn_decl(&bfty.decl);
|
||||
self.check_fn_decl(&bfty.decl, SelfSemantic::No);
|
||||
Self::check_decl_no_pat(&bfty.decl, |span, _| {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
@ -685,7 +714,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
ItemKind::Fn(ref sig, ref generics, _) => {
|
||||
self.visit_fn_header(&sig.header);
|
||||
self.check_fn_decl(&sig.decl);
|
||||
self.check_fn_decl(&sig.decl, SelfSemantic::No);
|
||||
// We currently do not permit const generics in `const fn`, as
|
||||
// this is tantamount to allowing compile-time dependent typing.
|
||||
if sig.header.constness.node == Constness::Const {
|
||||
@ -793,7 +822,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||
match fi.kind {
|
||||
ForeignItemKind::Fn(ref decl, _) => {
|
||||
self.check_fn_decl(decl);
|
||||
self.check_fn_decl(decl, SelfSemantic::No);
|
||||
Self::check_decl_no_pat(decl, |span, _| {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
@ -987,9 +1016,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
AssocItemKind::Const(_, body) => {
|
||||
self.check_impl_item_provided(ii.span, body, "constant", " = <expr>;");
|
||||
}
|
||||
AssocItemKind::Fn(sig, body) => {
|
||||
AssocItemKind::Fn(_, body) => {
|
||||
self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
|
||||
self.check_fn_decl(&sig.decl);
|
||||
}
|
||||
AssocItemKind::TyAlias(bounds, body) => {
|
||||
self.check_impl_item_provided(ii.span, body, "type", " = <type>;");
|
||||
@ -1005,7 +1033,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.check_defaultness(ti.span, ti.defaultness);
|
||||
|
||||
if let AssocItemKind::Fn(sig, block) = &ti.kind {
|
||||
self.check_fn_decl(&sig.decl);
|
||||
self.check_trait_fn_not_async(ti.span, sig.header.asyncness.node);
|
||||
self.check_trait_fn_not_const(sig.header.constness);
|
||||
if block.is_none() {
|
||||
@ -1035,6 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a AssocItem) {
|
||||
if let AssocItemKind::Fn(sig, _) = &item.kind {
|
||||
self.check_fn_decl(&sig.decl, SelfSemantic::Yes);
|
||||
self.check_c_varadic_type(&sig.decl);
|
||||
}
|
||||
visit::walk_assoc_item(self, item);
|
||||
|
@ -1336,8 +1336,8 @@ impl<'a> Parser<'a> {
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
pat: P<ast::Pat>,
|
||||
require_name: bool,
|
||||
is_self_allowed: bool,
|
||||
is_trait_item: bool,
|
||||
is_self_semantic: bool,
|
||||
in_assoc_item: bool,
|
||||
) -> Option<Ident> {
|
||||
// If we find a pattern followed by an identifier, it could be an (incorrect)
|
||||
// C-style parameter declaration.
|
||||
@ -1357,13 +1357,13 @@ impl<'a> Parser<'a> {
|
||||
return Some(ident);
|
||||
} else if let PatKind::Ident(_, ident, _) = pat.kind {
|
||||
if require_name
|
||||
&& (is_trait_item
|
||||
&& (in_assoc_item
|
||||
|| self.token == token::Comma
|
||||
|| self.token == token::Lt
|
||||
|| self.token == token::CloseDelim(token::Paren))
|
||||
{
|
||||
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if is_self_allowed {
|
||||
if is_self_semantic {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a `self` type, give it a parameter name",
|
||||
@ -1423,12 +1423,12 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn recover_bad_self_param(
|
||||
&mut self,
|
||||
mut param: ast::Param,
|
||||
is_trait_item: bool,
|
||||
in_assoc_item: bool,
|
||||
) -> PResult<'a, ast::Param> {
|
||||
let sp = param.pat.span;
|
||||
param.ty.kind = TyKind::Err;
|
||||
let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
|
||||
if is_trait_item {
|
||||
if in_assoc_item {
|
||||
err.span_label(sp, "must be the first associated function parameter");
|
||||
} else {
|
||||
err.span_label(sp, "not valid as function parameter");
|
||||
|
@ -1715,8 +1715,9 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
|
||||
pub(super) struct ParamCfg {
|
||||
/// Is `self` is allowed as the first parameter?
|
||||
pub is_self_allowed: bool,
|
||||
/// Is `self` is *semantically* allowed as the first parameter?
|
||||
/// This is only used for diagnostics.
|
||||
pub in_assoc_item: bool,
|
||||
/// `is_name_required` decides if, per-parameter,
|
||||
/// the parameter must have a pattern or just a type.
|
||||
pub is_name_required: fn(&token::Token) -> bool,
|
||||
@ -1732,8 +1733,8 @@ impl<'a> Parser<'a> {
|
||||
attrs: Vec<Attribute>,
|
||||
header: FnHeader,
|
||||
) -> PResult<'a, Option<P<Item>>> {
|
||||
let (ident, decl, generics) =
|
||||
self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?;
|
||||
let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
|
||||
let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
|
||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
|
||||
self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
|
||||
@ -1747,20 +1748,13 @@ impl<'a> Parser<'a> {
|
||||
attrs: Vec<Attribute>,
|
||||
extern_sp: Span,
|
||||
) -> PResult<'a, P<ForeignItem>> {
|
||||
let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
|
||||
self.expect_keyword(kw::Fn)?;
|
||||
let (ident, decl, generics) =
|
||||
self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?;
|
||||
let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
|
||||
let span = lo.to(self.token.span);
|
||||
self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
|
||||
Ok(P(ast::ForeignItem {
|
||||
ident,
|
||||
attrs,
|
||||
kind: ForeignItemKind::Fn(decl, generics),
|
||||
id: DUMMY_NODE_ID,
|
||||
span,
|
||||
vis,
|
||||
tokens: None,
|
||||
}))
|
||||
let kind = ForeignItemKind::Fn(decl, generics);
|
||||
Ok(P(ast::ForeignItem { ident, attrs, kind, id: DUMMY_NODE_ID, span, vis, tokens: None }))
|
||||
}
|
||||
|
||||
fn parse_assoc_fn(
|
||||
@ -1769,9 +1763,9 @@ impl<'a> Parser<'a> {
|
||||
attrs: &mut Vec<Attribute>,
|
||||
is_name_required: fn(&token::Token) -> bool,
|
||||
) -> PResult<'a, (Ident, AssocItemKind, Generics)> {
|
||||
let cfg = ParamCfg { in_assoc_item: true, is_name_required };
|
||||
let header = self.parse_fn_front_matter()?;
|
||||
let (ident, decl, generics) =
|
||||
self.parse_fn_sig(ParamCfg { is_self_allowed: true, is_name_required })?;
|
||||
let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
|
||||
let sig = FnSig { header, decl };
|
||||
let body = self.parse_assoc_fn_body(at_end, attrs)?;
|
||||
Ok((ident, AssocItemKind::Fn(sig, body), generics))
|
||||
@ -1847,7 +1841,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parse the "signature", including the identifier, parameters, and generics of a function.
|
||||
fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
|
||||
fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
let decl = self.parse_fn_decl(cfg, true)?;
|
||||
@ -1858,7 +1852,7 @@ impl<'a> Parser<'a> {
|
||||
/// Parses the parameter list and result type of a function declaration.
|
||||
pub(super) fn parse_fn_decl(
|
||||
&mut self,
|
||||
cfg: ParamCfg,
|
||||
cfg: &ParamCfg,
|
||||
ret_allow_plus: bool,
|
||||
) -> PResult<'a, P<FnDecl>> {
|
||||
Ok(P(FnDecl {
|
||||
@ -1868,11 +1862,11 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
|
||||
fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
|
||||
let is_trait_item = cfg.is_self_allowed;
|
||||
// Parse the arguments, starting out with `self` being possibly allowed...
|
||||
fn parse_fn_params(&mut self, cfg: &ParamCfg) -> PResult<'a, Vec<Param>> {
|
||||
let mut first_param = true;
|
||||
// Parse the arguments, starting out with `self` being allowed...
|
||||
let (mut params, _) = self.parse_paren_comma_seq(|p| {
|
||||
let param = p.parse_param_general(&cfg, is_trait_item).or_else(|mut e| {
|
||||
let param = p.parse_param_general(&cfg, first_param).or_else(|mut e| {
|
||||
e.emit();
|
||||
let lo = p.prev_span;
|
||||
// Skip every token until next possible arg or end.
|
||||
@ -1881,7 +1875,7 @@ impl<'a> Parser<'a> {
|
||||
Ok(dummy_arg(Ident::new(kw::Invalid, lo.to(p.prev_span))))
|
||||
});
|
||||
// ...now that we've parsed the first argument, `self` is no longer allowed.
|
||||
cfg.is_self_allowed = false;
|
||||
first_param = false;
|
||||
param
|
||||
})?;
|
||||
// Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
|
||||
@ -1889,20 +1883,20 @@ impl<'a> Parser<'a> {
|
||||
Ok(params)
|
||||
}
|
||||
|
||||
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
|
||||
/// error.
|
||||
/// This version of parse param doesn't necessarily require identifier names.
|
||||
fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
|
||||
/// Parses a single function parameter.
|
||||
///
|
||||
/// - `self` is syntactically allowed when `first_param` holds.
|
||||
fn parse_param_general(&mut self, cfg: &ParamCfg, first_param: bool) -> PResult<'a, Param> {
|
||||
let lo = self.token.span;
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
|
||||
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
|
||||
if let Some(mut param) = self.parse_self_param()? {
|
||||
param.attrs = attrs.into();
|
||||
return if cfg.is_self_allowed {
|
||||
return if first_param {
|
||||
Ok(param)
|
||||
} else {
|
||||
self.recover_bad_self_param(param, is_trait_item)
|
||||
self.recover_bad_self_param(param, cfg.in_assoc_item)
|
||||
};
|
||||
}
|
||||
|
||||
@ -1919,8 +1913,8 @@ impl<'a> Parser<'a> {
|
||||
&mut err,
|
||||
pat,
|
||||
is_name_required,
|
||||
cfg.is_self_allowed,
|
||||
is_trait_item,
|
||||
first_param && cfg.in_assoc_item,
|
||||
cfg.in_assoc_item,
|
||||
) {
|
||||
err.emit();
|
||||
Ok(dummy_arg(ident))
|
||||
@ -1975,8 +1969,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Returns the parsed optional self parameter and whether a self shortcut was used.
|
||||
///
|
||||
/// See `parse_self_param_with_attrs` to collect attributes.
|
||||
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
|
||||
// Extract an identifier *after* having confirmed that the token is one.
|
||||
let expect_self_ident = |this: &mut Self| {
|
||||
|
@ -288,8 +288,8 @@ impl<'a> Parser<'a> {
|
||||
let unsafety = self.parse_unsafety();
|
||||
let ext = self.parse_extern()?;
|
||||
self.expect_keyword(kw::Fn)?;
|
||||
let cfg = ParamCfg { is_self_allowed: false, is_name_required: |_| false };
|
||||
let decl = self.parse_fn_decl(cfg, false)?;
|
||||
let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| false };
|
||||
let decl = self.parse_fn_decl(&cfg, false)?;
|
||||
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
fn a(&self) { }
|
||||
//~^ ERROR unexpected `self` parameter in function
|
||||
//~| NOTE not valid as function parameter
|
||||
//~| NOTE `self` is only valid as the first parameter of an associated function
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
//~| NOTE not semantically valid as function parameter
|
||||
//~| NOTE associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
fn main() { }
|
||||
|
@ -1,10 +1,10 @@
|
||||
error: unexpected `self` parameter in function
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/bare-fn-start.rs:1:6
|
||||
|
|
||||
LL | fn a(&self) { }
|
||||
| ^^^^^ not valid as function parameter
|
||||
| ^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: `self` is only valid as the first parameter of an associated function
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
64
src/test/ui/parser/self-param-semantic-fail.rs
Normal file
64
src/test/ui/parser/self-param-semantic-fail.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// This test ensures that `self` is semantically rejected
|
||||
// in contexts with `FnDecl` but outside of associated `fn`s.
|
||||
// FIXME(Centril): For now closures are an exception.
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn free() {
|
||||
fn f1(self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f2(mut self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f3(&self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f4(&mut self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f5<'a>(&'a self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f6<'a>(&'a mut self) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f7(self: u8) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f8(mut self: u8) {}
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
}
|
||||
|
||||
extern {
|
||||
fn f1(self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f2(mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
//~| ERROR patterns aren't allowed in
|
||||
fn f3(&self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f4(&mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f5<'a>(&'a self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f6<'a>(&'a mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f7(self: u8);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
fn f8(mut self: u8);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
//~| ERROR patterns aren't allowed in
|
||||
}
|
||||
|
||||
type X1 = fn(self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X2 = fn(mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
//~| ERROR patterns aren't allowed in
|
||||
type X3 = fn(&self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X4 = fn(&mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X5 = for<'a> fn(&'a self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X6 = for<'a> fn(&'a mut self);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X7 = fn(self: u8);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
type X8 = fn(mut self: u8);
|
||||
//~^ ERROR `self` parameter only allowed in associated `fn`s
|
||||
//~| ERROR patterns aren't allowed in
|
220
src/test/ui/parser/self-param-semantic-fail.stderr
Normal file
220
src/test/ui/parser/self-param-semantic-fail.stderr
Normal file
@ -0,0 +1,220 @@
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:8:11
|
||||
|
|
||||
LL | fn f1(self) {}
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:10:11
|
||||
|
|
||||
LL | fn f2(mut self) {}
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:12:11
|
||||
|
|
||||
LL | fn f3(&self) {}
|
||||
| ^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:14:11
|
||||
|
|
||||
LL | fn f4(&mut self) {}
|
||||
| ^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:16:15
|
||||
|
|
||||
LL | fn f5<'a>(&'a self) {}
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:18:15
|
||||
|
|
||||
LL | fn f6<'a>(&'a mut self) {}
|
||||
| ^^^^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:20:11
|
||||
|
|
||||
LL | fn f7(self: u8) {}
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:22:11
|
||||
|
|
||||
LL | fn f8(mut self: u8) {}
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:27:11
|
||||
|
|
||||
LL | fn f1(self);
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:29:11
|
||||
|
|
||||
LL | fn f2(mut self);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error[E0130]: patterns aren't allowed in foreign function declarations
|
||||
--> $DIR/self-param-semantic-fail.rs:29:11
|
||||
|
|
||||
LL | fn f2(mut self);
|
||||
| ^^^^^^^^ pattern not allowed in foreign function
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:32:11
|
||||
|
|
||||
LL | fn f3(&self);
|
||||
| ^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:34:11
|
||||
|
|
||||
LL | fn f4(&mut self);
|
||||
| ^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:36:15
|
||||
|
|
||||
LL | fn f5<'a>(&'a self);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:38:15
|
||||
|
|
||||
LL | fn f6<'a>(&'a mut self);
|
||||
| ^^^^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:40:11
|
||||
|
|
||||
LL | fn f7(self: u8);
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:42:11
|
||||
|
|
||||
LL | fn f8(mut self: u8);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error[E0130]: patterns aren't allowed in foreign function declarations
|
||||
--> $DIR/self-param-semantic-fail.rs:42:11
|
||||
|
|
||||
LL | fn f8(mut self: u8);
|
||||
| ^^^^^^^^ pattern not allowed in foreign function
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:47:14
|
||||
|
|
||||
LL | type X1 = fn(self);
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:49:14
|
||||
|
|
||||
LL | type X2 = fn(mut self);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error[E0561]: patterns aren't allowed in function pointer types
|
||||
--> $DIR/self-param-semantic-fail.rs:49:14
|
||||
|
|
||||
LL | type X2 = fn(mut self);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:52:14
|
||||
|
|
||||
LL | type X3 = fn(&self);
|
||||
| ^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:54:14
|
||||
|
|
||||
LL | type X4 = fn(&mut self);
|
||||
| ^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:56:22
|
||||
|
|
||||
LL | type X5 = for<'a> fn(&'a self);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:58:22
|
||||
|
|
||||
LL | type X6 = for<'a> fn(&'a mut self);
|
||||
| ^^^^^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:60:14
|
||||
|
|
||||
LL | type X7 = fn(self: u8);
|
||||
| ^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error: `self` parameter only allowed in associated `fn`s
|
||||
--> $DIR/self-param-semantic-fail.rs:62:14
|
||||
|
|
||||
LL | type X8 = fn(mut self: u8);
|
||||
| ^^^^^^^^ not semantically valid as function parameter
|
||||
|
|
||||
= note: associated `fn`s are those in `impl` or `trait` definitions
|
||||
|
||||
error[E0561]: patterns aren't allowed in function pointer types
|
||||
--> $DIR/self-param-semantic-fail.rs:62:14
|
||||
|
|
||||
LL | type X8 = fn(mut self: u8);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 28 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0130, E0561.
|
||||
For more information about an error, try `rustc --explain E0130`.
|
66
src/test/ui/parser/self-param-syntactic-pass.rs
Normal file
66
src/test/ui/parser/self-param-syntactic-pass.rs
Normal file
@ -0,0 +1,66 @@
|
||||
// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed.
|
||||
// FIXME(Centril): For now closures are an exception.
|
||||
|
||||
// check-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn free() {
|
||||
fn f(self) {}
|
||||
fn f(mut self) {}
|
||||
fn f(&self) {}
|
||||
fn f(&mut self) {}
|
||||
fn f(&'a self) {}
|
||||
fn f(&'a mut self) {}
|
||||
fn f(self: u8) {}
|
||||
fn f(mut self: u8) {}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
extern {
|
||||
fn f(self);
|
||||
fn f(mut self);
|
||||
fn f(&self);
|
||||
fn f(&mut self);
|
||||
fn f(&'a self);
|
||||
fn f(&'a mut self);
|
||||
fn f(self: u8);
|
||||
fn f(mut self: u8);
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
trait X {
|
||||
fn f(self) {}
|
||||
fn f(mut self) {}
|
||||
fn f(&self) {}
|
||||
fn f(&mut self) {}
|
||||
fn f(&'a self) {}
|
||||
fn f(&'a mut self) {}
|
||||
fn f(self: u8) {}
|
||||
fn f(mut self: u8) {}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
impl X for Y {
|
||||
fn f(self) {}
|
||||
fn f(mut self) {}
|
||||
fn f(&self) {}
|
||||
fn f(&mut self) {}
|
||||
fn f(&'a self) {}
|
||||
fn f(&'a mut self) {}
|
||||
fn f(self: u8) {}
|
||||
fn f(mut self: u8) {}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
impl X for Y {
|
||||
type X = fn(self);
|
||||
type X = fn(mut self);
|
||||
type X = fn(&self);
|
||||
type X = fn(&mut self);
|
||||
type X = fn(&'a self);
|
||||
type X = fn(&'a mut self);
|
||||
type X = fn(self: u8);
|
||||
type X = fn(mut self: u8);
|
||||
}
|
Loading…
Reference in New Issue
Block a user