Remove ExplicitSelf from AST
This commit is contained in:
parent
5229e0efb3
commit
5660a00486
@ -788,10 +788,10 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
|
||||
// Check for `self: _` and `self: &_`
|
||||
if let SelfKind::Explicit(ref ty, _) = sig.explicit_self.node {
|
||||
match sig.decl.inputs.get(0).and_then(Arg::to_self).map(|eself| eself.node) {
|
||||
if !sig.self_shortcut {
|
||||
match sig.decl.get_self().map(|eself| eself.node) {
|
||||
Some(SelfKind::Value(..)) | Some(SelfKind::Region(..)) => {
|
||||
self.id_assigner.diagnostic().span_err(ty.span,
|
||||
self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].ty.span,
|
||||
"the type placeholder `_` is not allowed within types on item signatures");
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1175,6 +1175,9 @@ pub struct FnDecl {
|
||||
}
|
||||
|
||||
impl FnDecl {
|
||||
pub fn get_self(&self) -> Option<ExplicitSelf> {
|
||||
self.inputs.get(0).and_then(Arg::to_self)
|
||||
}
|
||||
pub fn has_self(&self) -> bool {
|
||||
self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
|
||||
}
|
||||
|
@ -1043,11 +1043,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
||||
run_lints!(self, check_lifetime_def, early_passes, lt);
|
||||
}
|
||||
|
||||
fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) {
|
||||
run_lints!(self, check_explicit_self, early_passes, es);
|
||||
ast_visit::walk_explicit_self(self, es);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
|
||||
run_lints!(self, check_path, early_passes, p, id);
|
||||
ast_visit::walk_path(self, p);
|
||||
|
@ -167,7 +167,6 @@ pub trait LateLintPass: LintPass {
|
||||
fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
|
||||
fn check_lifetime(&mut self, _: &LateContext, _: &hir::Lifetime) { }
|
||||
fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
|
||||
fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
|
||||
fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
|
||||
fn check_path_list_item(&mut self, _: &LateContext, _: &hir::PathListItem) { }
|
||||
fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }
|
||||
@ -218,7 +217,6 @@ pub trait EarlyLintPass: LintPass {
|
||||
fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
|
||||
fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
|
||||
fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
|
||||
fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
|
||||
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
|
||||
fn check_path_list_item(&mut self, _: &EarlyContext, _: &ast::PathListItem) { }
|
||||
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
|
||||
|
@ -35,7 +35,7 @@ use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::ast::{Block, Crate, DeclKind};
|
||||
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
|
||||
use syntax::ast::{Mutability, PathListItemKind};
|
||||
use syntax::ast::{SelfKind, Stmt, StmtKind, TraitItemKind};
|
||||
use syntax::ast::{Stmt, StmtKind, TraitItemKind};
|
||||
use syntax::ast::{Variant, ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::visit::{self, Visitor};
|
||||
|
||||
@ -335,7 +335,7 @@ impl<'b> Resolver<'b> {
|
||||
let (def, ns) = match item.node {
|
||||
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
|
||||
TraitItemKind::Method(ref sig, _) => {
|
||||
is_static_method = sig.explicit_self.node == SelfKind::Static;
|
||||
is_static_method = !sig.decl.has_self();
|
||||
(Def::Method(item_def_id), ValueNS)
|
||||
}
|
||||
TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
|
||||
|
@ -1833,8 +1833,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// lifetime elision, we can determine it in two ways. First (determined
|
||||
// here), if self is by-reference, then the implied output region is the
|
||||
// region of the self parameter.
|
||||
let explicit_self = decl.inputs.get(0).and_then(hir::Arg::to_self);
|
||||
let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, explicit_self) {
|
||||
let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, decl.get_self()) {
|
||||
(Some(untransformed_self_ty), Some(explicit_self)) => {
|
||||
let self_type = self.determine_self_type(&rb, untransformed_self_ty,
|
||||
&explicit_self);
|
||||
|
@ -1387,7 +1387,8 @@ pub struct MethodSig {
|
||||
pub abi: Abi,
|
||||
pub decl: P<FnDecl>,
|
||||
pub generics: Generics,
|
||||
pub explicit_self: ExplicitSelf,
|
||||
/// A short form of self argument was used (`self`, `&self` etc, but not `self: TYPE`).
|
||||
pub self_shortcut: bool,
|
||||
}
|
||||
|
||||
/// Represents an item declaration within a trait declaration,
|
||||
@ -1677,81 +1678,65 @@ pub struct Arg {
|
||||
pub id: NodeId,
|
||||
}
|
||||
|
||||
/// Represents the kind of 'self' associated with a method.
|
||||
/// String representation of `Ident` here is always "self", but hygiene contexts may differ.
|
||||
/// Alternative representation for `Arg`s describing `self` parameter of methods.
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum SelfKind {
|
||||
/// No self
|
||||
Static,
|
||||
/// `self`, `mut self`
|
||||
Value(Ident),
|
||||
Value(Mutability),
|
||||
/// `&'lt self`, `&'lt mut self`
|
||||
Region(Option<Lifetime>, Mutability, Ident),
|
||||
Region(Option<Lifetime>, Mutability),
|
||||
/// `self: TYPE`, `mut self: TYPE`
|
||||
Explicit(P<Ty>, Ident),
|
||||
Explicit(P<Ty>, Mutability),
|
||||
}
|
||||
|
||||
pub type ExplicitSelf = Spanned<SelfKind>;
|
||||
|
||||
impl Arg {
|
||||
#[unstable(feature = "rustc_private", issue = "27812")]
|
||||
#[rustc_deprecated(since = "1.10.0", reason = "use `from_self` instead")]
|
||||
pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
|
||||
let path = Spanned{span:span,node:self_ident};
|
||||
Arg {
|
||||
// HACK(eddyb) fake type for the self argument.
|
||||
ty: P(Ty {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: TyKind::Infer,
|
||||
span: DUMMY_SP,
|
||||
}),
|
||||
pat: P(Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(BindingMode::ByValue(mutability), path, None),
|
||||
span: span
|
||||
}),
|
||||
id: DUMMY_NODE_ID
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_self(&self) -> Option<ExplicitSelf> {
|
||||
if let PatKind::Ident(_, ident, _) = self.pat.node {
|
||||
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
|
||||
if ident.node.name == keywords::SelfValue.name() {
|
||||
return match self.ty.node {
|
||||
TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(ident.node))),
|
||||
TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
||||
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => {
|
||||
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl, ident.node)))
|
||||
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
||||
}
|
||||
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
|
||||
SelfKind::Explicit(self.ty.clone(), ident.node))),
|
||||
SelfKind::Explicit(self.ty.clone(), mutbl))),
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn from_self(eself: ExplicitSelf, ident_sp: Span, mutbl: Mutability) -> Arg {
|
||||
let pat = |ident, span| P(Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(BindingMode::ByValue(mutbl), respan(ident_sp, ident), None),
|
||||
span: span,
|
||||
});
|
||||
pub fn is_self(&self) -> bool {
|
||||
if let PatKind::Ident(_, ident, _) = self.pat.node {
|
||||
ident.node.name == keywords::SelfValue.name()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
|
||||
let infer_ty = P(Ty {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: TyKind::Infer,
|
||||
span: DUMMY_SP,
|
||||
});
|
||||
let arg = |ident, ty, span| Arg {
|
||||
pat: pat(ident, span),
|
||||
let arg = |mutbl, ty, span| Arg {
|
||||
pat: P(Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
|
||||
span: span,
|
||||
}),
|
||||
ty: ty,
|
||||
id: DUMMY_NODE_ID,
|
||||
};
|
||||
match eself.node {
|
||||
SelfKind::Static => panic!("bug: `Arg::from_self` is called \
|
||||
with `SelfKind::Static` argument"),
|
||||
SelfKind::Explicit(ty, ident) => arg(ident, ty, mk_sp(eself.span.lo, ident_sp.hi)),
|
||||
SelfKind::Value(ident) => arg(ident, infer_ty, eself.span),
|
||||
SelfKind::Region(lt, mutbl, ident) => arg(ident, P(Ty {
|
||||
SelfKind::Explicit(ty, mutbl) => {
|
||||
arg(mutbl, ty, mk_sp(eself.span.lo, eself_ident.span.hi))
|
||||
}
|
||||
SelfKind::Value(mutbl) => arg(mutbl, infer_ty, eself.span),
|
||||
SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }),
|
||||
span: DUMMY_SP,
|
||||
@ -1768,6 +1753,15 @@ pub struct FnDecl {
|
||||
pub variadic: bool
|
||||
}
|
||||
|
||||
impl FnDecl {
|
||||
pub fn get_self(&self) -> Option<ExplicitSelf> {
|
||||
self.inputs.get(0).and_then(Arg::to_self)
|
||||
}
|
||||
pub fn has_self(&self) -> bool {
|
||||
self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Unsafety {
|
||||
Unsafe,
|
||||
|
@ -1128,7 +1128,7 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
|
||||
(ast::MethodSig {
|
||||
generics: fld.fold_generics(sig.generics),
|
||||
abi: sig.abi,
|
||||
explicit_self: fld.fold_explicit_self(sig.explicit_self),
|
||||
self_shortcut: sig.self_shortcut,
|
||||
unsafety: sig.unsafety,
|
||||
constness: sig.constness,
|
||||
decl: rewritten_fn_decl
|
||||
|
@ -179,14 +179,6 @@ pub trait Folder : Sized {
|
||||
// fold::noop_fold_mac(_mac, self)
|
||||
}
|
||||
|
||||
fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf {
|
||||
noop_fold_explicit_self(es, self)
|
||||
}
|
||||
|
||||
fn fold_explicit_self_kind(&mut self, es: SelfKind) -> SelfKind {
|
||||
noop_fold_explicit_self_kind(es, self)
|
||||
}
|
||||
|
||||
fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
|
||||
noop_fold_lifetime(l, self)
|
||||
}
|
||||
@ -523,28 +515,6 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attr
|
||||
})
|
||||
}
|
||||
|
||||
pub fn noop_fold_explicit_self_kind<T: Folder>(es: SelfKind, fld: &mut T)
|
||||
-> SelfKind {
|
||||
match es {
|
||||
SelfKind::Static | SelfKind::Value(_) => es,
|
||||
SelfKind::Region(lifetime, m, ident) => {
|
||||
SelfKind::Region(fld.fold_opt_lifetime(lifetime), m, ident)
|
||||
}
|
||||
SelfKind::Explicit(typ, ident) => {
|
||||
SelfKind::Explicit(fld.fold_ty(typ), ident)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_explicit_self<T: Folder>(Spanned {span, node}: ExplicitSelf, fld: &mut T)
|
||||
-> ExplicitSelf {
|
||||
Spanned {
|
||||
node: fld.fold_explicit_self_kind(node),
|
||||
span: fld.new_span(span)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
|
||||
Spanned {
|
||||
node: Mac_ {
|
||||
@ -1096,7 +1066,7 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
|
||||
MethodSig {
|
||||
generics: folder.fold_generics(sig.generics),
|
||||
abi: sig.abi,
|
||||
explicit_self: folder.fold_explicit_self(sig.explicit_self),
|
||||
self_shortcut: sig.self_shortcut,
|
||||
unsafety: sig.unsafety,
|
||||
constness: sig.constness,
|
||||
decl: folder.fold_fn_decl(sig.decl)
|
||||
|
@ -17,7 +17,7 @@ use ast::Block;
|
||||
use ast::{BlockCheckMode, CaptureBy};
|
||||
use ast::{Constness, Crate, CrateConfig};
|
||||
use ast::{Decl, DeclKind, Defaultness};
|
||||
use ast::{EMPTY_CTXT, EnumDef, ExplicitSelf};
|
||||
use ast::{EMPTY_CTXT, EnumDef};
|
||||
use ast::{Expr, ExprKind, RangeLimits};
|
||||
use ast::{Field, FnDecl};
|
||||
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
|
||||
@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> {
|
||||
let ident = p.parse_ident()?;
|
||||
let mut generics = p.parse_generics()?;
|
||||
|
||||
let (explicit_self, d) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
|
||||
let (d, self_shortcut) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
|
||||
// This is somewhat dubious; We don't want to allow
|
||||
// argument names to be left off if there is a
|
||||
// definition...
|
||||
@ -1324,7 +1324,7 @@ impl<'a> Parser<'a> {
|
||||
decl: d,
|
||||
generics: generics,
|
||||
abi: abi,
|
||||
explicit_self: explicit_self,
|
||||
self_shortcut: self_shortcut,
|
||||
};
|
||||
|
||||
let body = match p.token {
|
||||
@ -4616,25 +4616,19 @@ impl<'a> Parser<'a> {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parse the parameter list and result type of a function that may have a `self` parameter.
|
||||
fn parse_fn_decl_with_self<F>(&mut self,
|
||||
parse_arg_fn: F)
|
||||
-> PResult<'a, (ExplicitSelf, P<FnDecl>)>
|
||||
where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
|
||||
{
|
||||
/// Returns the parsed optional self argument and whether a self shortcut was used.
|
||||
fn parse_self_arg(&mut self) -> PResult<'a, (Option<Arg>, bool)> {
|
||||
let expect_ident = |this: &mut Self| match this.token {
|
||||
token::Ident(ident) => { this.bump(); ident } // Preserve hygienic context.
|
||||
// Preserve hygienic context.
|
||||
token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) }
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
|
||||
// Parse optional self parameter of a method.
|
||||
// Only a limited set of initial token sequences is considered self parameters, anything
|
||||
// else is parsed as a normal function parameter list, so some lookahead is required.
|
||||
let eself_lo = self.span.lo;
|
||||
let mut eself_mutbl = Mutability::Immutable;
|
||||
let (eself, eself_ident_sp) = match self.token {
|
||||
let (eself, eself_ident) = match self.token {
|
||||
token::BinOp(token::And) => {
|
||||
// &self
|
||||
// &mut self
|
||||
@ -4643,30 +4637,26 @@ impl<'a> Parser<'a> {
|
||||
// ¬_self
|
||||
if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
(SelfKind::Region(None, Mutability::Immutable, expect_ident(self)),
|
||||
self.last_span)
|
||||
(SelfKind::Region(None, Mutability::Immutable), expect_ident(self))
|
||||
} else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
|
||||
self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
self.bump();
|
||||
(SelfKind::Region(None, Mutability::Mutable, expect_ident(self)),
|
||||
self.last_span)
|
||||
(SelfKind::Region(None, Mutability::Mutable), expect_ident(self))
|
||||
} else if self.look_ahead(1, |t| t.is_lifetime()) &&
|
||||
self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
let lt = self.parse_lifetime()?;
|
||||
(SelfKind::Region(Some(lt), Mutability::Immutable, expect_ident(self)),
|
||||
self.last_span)
|
||||
(SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self))
|
||||
} else if self.look_ahead(1, |t| t.is_lifetime()) &&
|
||||
self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) &&
|
||||
self.look_ahead(3, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
let lt = self.parse_lifetime()?;
|
||||
self.bump();
|
||||
(SelfKind::Region(Some(lt), Mutability::Mutable, expect_ident(self)),
|
||||
self.last_span)
|
||||
(SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self))
|
||||
} else {
|
||||
(SelfKind::Static, codemap::DUMMY_SP)
|
||||
return Ok((None, false));
|
||||
}
|
||||
}
|
||||
token::BinOp(token::Star) => {
|
||||
@ -4678,15 +4668,15 @@ impl<'a> Parser<'a> {
|
||||
if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
self.span_err(self.span, "cannot pass `self` by raw pointer");
|
||||
(SelfKind::Value(expect_ident(self)), self.last_span)
|
||||
(SelfKind::Value(Mutability::Immutable), expect_ident(self))
|
||||
} else if self.look_ahead(1, |t| t.is_mutability()) &&
|
||||
self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
self.bump();
|
||||
self.bump();
|
||||
self.span_err(self.span, "cannot pass `self` by raw pointer");
|
||||
(SelfKind::Value(expect_ident(self)), self.last_span)
|
||||
(SelfKind::Value(Mutability::Immutable), expect_ident(self))
|
||||
} else {
|
||||
(SelfKind::Static, codemap::DUMMY_SP)
|
||||
return Ok((None, false));
|
||||
}
|
||||
}
|
||||
token::Ident(..) => {
|
||||
@ -4694,64 +4684,72 @@ impl<'a> Parser<'a> {
|
||||
// self
|
||||
// self: TYPE
|
||||
let eself_ident = expect_ident(self);
|
||||
let eself_ident_sp = self.last_span;
|
||||
if self.eat(&token::Colon) {
|
||||
(SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp)
|
||||
let ty = self.parse_ty_sum()?;
|
||||
(SelfKind::Explicit(ty, Mutability::Immutable), eself_ident)
|
||||
} else {
|
||||
(SelfKind::Value(eself_ident), eself_ident_sp)
|
||||
(SelfKind::Value(Mutability::Immutable), eself_ident)
|
||||
}
|
||||
} else if self.token.is_keyword(keywords::Mut) &&
|
||||
self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) {
|
||||
// mut self
|
||||
// mut self: TYPE
|
||||
eself_mutbl = Mutability::Mutable;
|
||||
self.bump();
|
||||
let eself_ident = expect_ident(self);
|
||||
let eself_ident_sp = self.last_span;
|
||||
if self.eat(&token::Colon) {
|
||||
(SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp)
|
||||
let ty = self.parse_ty_sum()?;
|
||||
(SelfKind::Explicit(ty, Mutability::Mutable), eself_ident)
|
||||
} else {
|
||||
(SelfKind::Value(eself_ident), eself_ident_sp)
|
||||
(SelfKind::Value(Mutability::Mutable), eself_ident)
|
||||
}
|
||||
} else {
|
||||
(SelfKind::Static, codemap::DUMMY_SP)
|
||||
return Ok((None, false));
|
||||
}
|
||||
}
|
||||
_ => (SelfKind::Static, codemap::DUMMY_SP)
|
||||
_ => return Ok((None, false)),
|
||||
};
|
||||
let mut eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself);
|
||||
|
||||
let self_shortcut = if let SelfKind::Explicit(..) = eself { false } else { true };
|
||||
let eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself);
|
||||
Ok((Some(Arg::from_self(eself, eself_ident)), self_shortcut))
|
||||
}
|
||||
|
||||
/// Parse the parameter list and result type of a function that may have a `self` parameter.
|
||||
fn parse_fn_decl_with_self<F>(&mut self,
|
||||
parse_arg_fn: F)
|
||||
-> PResult<'a, (P<FnDecl>, bool)>
|
||||
where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
|
||||
{
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
|
||||
// Parse optional self argument
|
||||
let (self_arg, self_shortcut) = self.parse_self_arg()?;
|
||||
|
||||
// Parse the rest of the function parameter list.
|
||||
let sep = SeqSep::trailing_allowed(token::Comma);
|
||||
let fn_inputs = match eself.node {
|
||||
SelfKind::Static => {
|
||||
eself.span = codemap::DUMMY_SP;
|
||||
self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)
|
||||
}
|
||||
SelfKind::Value(..) | SelfKind::Region(..) | SelfKind::Explicit(..) => {
|
||||
if self.check(&token::CloseDelim(token::Paren)) {
|
||||
vec![Arg::from_self(eself.clone(), eself_ident_sp, eself_mutbl)]
|
||||
} else if self.check(&token::Comma) {
|
||||
self.bump();
|
||||
let mut fn_inputs = vec![Arg::from_self(eself.clone(), eself_ident_sp,
|
||||
eself_mutbl)];
|
||||
fn_inputs.append(&mut self.parse_seq_to_before_end(
|
||||
&token::CloseDelim(token::Paren), sep, parse_arg_fn)
|
||||
);
|
||||
fn_inputs
|
||||
} else {
|
||||
return self.unexpected();
|
||||
}
|
||||
let fn_inputs = if let Some(self_arg) = self_arg {
|
||||
if self.check(&token::CloseDelim(token::Paren)) {
|
||||
vec![self_arg]
|
||||
} else if self.eat(&token::Comma) {
|
||||
let mut fn_inputs = vec![self_arg];
|
||||
fn_inputs.append(&mut self.parse_seq_to_before_end(
|
||||
&token::CloseDelim(token::Paren), sep, parse_arg_fn)
|
||||
);
|
||||
fn_inputs
|
||||
} else {
|
||||
return self.unexpected();
|
||||
}
|
||||
} else {
|
||||
self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)
|
||||
};
|
||||
|
||||
// Parse closing paren and return type.
|
||||
self.expect(&token::CloseDelim(token::Paren))?;
|
||||
Ok((eself, P(FnDecl {
|
||||
Ok((P(FnDecl {
|
||||
inputs: fn_inputs,
|
||||
output: self.parse_ret_ty()?,
|
||||
variadic: false
|
||||
})))
|
||||
}), self_shortcut))
|
||||
}
|
||||
|
||||
// parse the |arg, arg| header on a lambda
|
||||
@ -4944,15 +4942,13 @@ impl<'a> Parser<'a> {
|
||||
let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
|
||||
let ident = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
|
||||
p.parse_arg()
|
||||
})?;
|
||||
let (decl, self_shortcut) = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig {
|
||||
generics: generics,
|
||||
abi: abi,
|
||||
explicit_self: explicit_self,
|
||||
self_shortcut: self_shortcut,
|
||||
unsafety: unsafety,
|
||||
constness: constness,
|
||||
decl: decl
|
||||
|
@ -12,7 +12,7 @@ pub use self::AnnNode::*;
|
||||
|
||||
use abi::{self, Abi};
|
||||
use ast::{self, TokenTree, BlockCheckMode, PatKind};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::Attribute;
|
||||
use attr::ThinAttributesExt;
|
||||
use util::parser::AssocOp;
|
||||
@ -382,13 +382,12 @@ pub fn fun_to_string(decl: &ast::FnDecl,
|
||||
unsafety: ast::Unsafety,
|
||||
constness: ast::Constness,
|
||||
name: ast::Ident,
|
||||
opt_explicit_self: Option<&ast::SelfKind>,
|
||||
generics: &ast::Generics)
|
||||
-> String {
|
||||
to_string(|s| {
|
||||
s.head("")?;
|
||||
s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name),
|
||||
generics, opt_explicit_self, &ast::Visibility::Inherited)?;
|
||||
generics, &ast::Visibility::Inherited)?;
|
||||
s.end()?; // Close the head box
|
||||
s.end() // Close the outer box
|
||||
})
|
||||
@ -416,10 +415,6 @@ pub fn lit_to_string(l: &ast::Lit) -> String {
|
||||
to_string(|s| s.print_literal(l))
|
||||
}
|
||||
|
||||
pub fn explicit_self_to_string(explicit_self: &ast::SelfKind) -> String {
|
||||
to_string(|s| s.print_explicit_self(explicit_self, ast::Mutability::Immutable).map(|_| {}))
|
||||
}
|
||||
|
||||
pub fn variant_to_string(var: &ast::Variant) -> String {
|
||||
to_string(|s| s.print_variant(var))
|
||||
}
|
||||
@ -1005,8 +1000,7 @@ impl<'a> State<'a> {
|
||||
f.unsafety,
|
||||
&f.decl,
|
||||
None,
|
||||
&generics,
|
||||
None)?;
|
||||
&generics)?;
|
||||
}
|
||||
ast::TyKind::Path(None, ref path) => {
|
||||
self.print_path(path, false, 0)?;
|
||||
@ -1054,7 +1048,7 @@ impl<'a> State<'a> {
|
||||
self.print_fn(decl, ast::Unsafety::Normal,
|
||||
ast::Constness::NotConst,
|
||||
Abi::Rust, Some(item.ident),
|
||||
generics, None, &item.vis)?;
|
||||
generics, &item.vis)?;
|
||||
self.end()?; // end head-ibox
|
||||
word(&mut self.s, ";")?;
|
||||
self.end() // end the outer fn box
|
||||
@ -1182,7 +1176,6 @@ impl<'a> State<'a> {
|
||||
abi,
|
||||
Some(item.ident),
|
||||
typarams,
|
||||
None,
|
||||
&item.vis
|
||||
)?;
|
||||
word(&mut self.s, " ")?;
|
||||
@ -1522,7 +1515,6 @@ impl<'a> State<'a> {
|
||||
m.abi,
|
||||
Some(ident),
|
||||
&m.generics,
|
||||
None,
|
||||
vis)
|
||||
}
|
||||
|
||||
@ -2610,29 +2602,25 @@ impl<'a> State<'a> {
|
||||
self.end() // close enclosing cbox
|
||||
}
|
||||
|
||||
// Returns whether it printed anything
|
||||
fn print_explicit_self(&mut self,
|
||||
explicit_self: &ast::SelfKind,
|
||||
mutbl: ast::Mutability) -> io::Result<bool> {
|
||||
self.print_mutability(mutbl)?;
|
||||
match *explicit_self {
|
||||
ast::SelfKind::Static => { return Ok(false); }
|
||||
ast::SelfKind::Value(_) => {
|
||||
word(&mut self.s, "self")?;
|
||||
fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> {
|
||||
match explicit_self.node {
|
||||
SelfKind::Value(m) => {
|
||||
self.print_mutability(m)?;
|
||||
word(&mut self.s, "self")
|
||||
}
|
||||
ast::SelfKind::Region(ref lt, m, _) => {
|
||||
SelfKind::Region(ref lt, m) => {
|
||||
word(&mut self.s, "&")?;
|
||||
self.print_opt_lifetime(lt)?;
|
||||
self.print_mutability(m)?;
|
||||
word(&mut self.s, "self")?;
|
||||
word(&mut self.s, "self")
|
||||
}
|
||||
ast::SelfKind::Explicit(ref typ, _) => {
|
||||
SelfKind::Explicit(ref typ, m) => {
|
||||
self.print_mutability(m)?;
|
||||
word(&mut self.s, "self")?;
|
||||
self.word_space(":")?;
|
||||
self.print_type(&typ)?;
|
||||
self.print_type(&typ)
|
||||
}
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
pub fn print_fn(&mut self,
|
||||
@ -2642,7 +2630,6 @@ impl<'a> State<'a> {
|
||||
abi: abi::Abi,
|
||||
name: Option<ast::Ident>,
|
||||
generics: &ast::Generics,
|
||||
opt_explicit_self: Option<&ast::SelfKind>,
|
||||
vis: &ast::Visibility) -> io::Result<()> {
|
||||
self.print_fn_header_info(unsafety, constness, abi, vis)?;
|
||||
|
||||
@ -2651,21 +2638,14 @@ impl<'a> State<'a> {
|
||||
self.print_ident(name)?;
|
||||
}
|
||||
self.print_generics(generics)?;
|
||||
self.print_fn_args_and_ret(decl, opt_explicit_self)?;
|
||||
self.print_fn_args_and_ret(decl)?;
|
||||
self.print_where_clause(&generics.where_clause)
|
||||
}
|
||||
|
||||
pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
|
||||
_: Option<&ast::SelfKind>,
|
||||
is_closure: bool) -> io::Result<()> {
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, is_closure))
|
||||
}
|
||||
|
||||
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
|
||||
opt_explicit_self: Option<&ast::SelfKind>)
|
||||
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl)
|
||||
-> io::Result<()> {
|
||||
self.popen()?;
|
||||
self.print_fn_args(decl, opt_explicit_self, false)?;
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
|
||||
if decl.variadic {
|
||||
word(&mut self.s, ", ...")?;
|
||||
}
|
||||
@ -2679,7 +2659,7 @@ impl<'a> State<'a> {
|
||||
decl: &ast::FnDecl)
|
||||
-> io::Result<()> {
|
||||
word(&mut self.s, "|")?;
|
||||
self.print_fn_args(decl, None, true)?;
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?;
|
||||
word(&mut self.s, "|")?;
|
||||
|
||||
if let ast::FunctionRetTy::Default(..) = decl.output {
|
||||
@ -2929,17 +2909,14 @@ impl<'a> State<'a> {
|
||||
match input.ty.node {
|
||||
ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?,
|
||||
_ => {
|
||||
let (mutbl, invalid) = match input.pat.node {
|
||||
PatKind::Ident(ast::BindingMode::ByValue(mutbl), ident, _) |
|
||||
PatKind::Ident(ast::BindingMode::ByRef(mutbl), ident, _) => {
|
||||
(mutbl, ident.node.name == keywords::Invalid.name())
|
||||
}
|
||||
_ => (ast::Mutability::Immutable, false)
|
||||
};
|
||||
|
||||
if let Some(eself) = input.to_self() {
|
||||
self.print_explicit_self(&eself.node, mutbl)?;
|
||||
self.print_explicit_self(&eself)?;
|
||||
} else {
|
||||
let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node {
|
||||
ident.node.name == keywords::Invalid.name()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if !invalid {
|
||||
self.print_pat(&input.pat)?;
|
||||
word(&mut self.s, ":")?;
|
||||
@ -2980,8 +2957,7 @@ impl<'a> State<'a> {
|
||||
unsafety: ast::Unsafety,
|
||||
decl: &ast::FnDecl,
|
||||
name: Option<ast::Ident>,
|
||||
generics: &ast::Generics,
|
||||
opt_explicit_self: Option<&ast::SelfKind>)
|
||||
generics: &ast::Generics)
|
||||
-> io::Result<()> {
|
||||
self.ibox(INDENT_UNIT)?;
|
||||
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
||||
@ -3002,7 +2978,6 @@ impl<'a> State<'a> {
|
||||
abi,
|
||||
name,
|
||||
&generics,
|
||||
opt_explicit_self,
|
||||
&ast::Visibility::Inherited)?;
|
||||
self.end()
|
||||
}
|
||||
@ -3126,8 +3101,7 @@ mod tests {
|
||||
let generics = ast::Generics::default();
|
||||
assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
|
||||
ast::Constness::NotConst,
|
||||
abba_ident,
|
||||
None, &generics),
|
||||
abba_ident, &generics),
|
||||
"fn abba()");
|
||||
}
|
||||
|
||||
|
@ -129,10 +129,6 @@ impl<'v> Visitor<'v> for NodeCounter {
|
||||
self.count += 1;
|
||||
walk_lifetime_def(self, lifetime)
|
||||
}
|
||||
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
|
||||
self.count += 1;
|
||||
walk_explicit_self(self, es)
|
||||
}
|
||||
fn visit_mac(&mut self, _mac: &'v Mac) {
|
||||
self.count += 1;
|
||||
walk_mac(self, _mac)
|
||||
|
@ -99,9 +99,6 @@ pub trait Visitor<'v> : Sized {
|
||||
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
|
||||
walk_lifetime_def(self, lifetime)
|
||||
}
|
||||
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
|
||||
walk_explicit_self(self, es)
|
||||
}
|
||||
fn visit_mac(&mut self, _mac: &'v Mac) {
|
||||
panic!("visit_mac disabled by default");
|
||||
// NB: see note about macros above.
|
||||
@ -196,24 +193,6 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
|
||||
}
|
||||
|
||||
pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
explicit_self: &'v ExplicitSelf) {
|
||||
match explicit_self.node {
|
||||
SelfKind::Static => {},
|
||||
SelfKind::Value(ident) => {
|
||||
visitor.visit_ident(explicit_self.span, ident)
|
||||
}
|
||||
SelfKind::Region(ref opt_lifetime, _, ident) => {
|
||||
visitor.visit_ident(explicit_self.span, ident);
|
||||
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
||||
}
|
||||
SelfKind::Explicit(ref typ, ident) => {
|
||||
visitor.visit_ident(explicit_self.span, ident);
|
||||
visitor.visit_ty(typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
||||
trait_ref: &'v PolyTraitRef,
|
||||
_modifier: &'v TraitBoundModifier)
|
||||
@ -553,7 +532,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
}
|
||||
FnKind::Method(_, ref sig, _) => {
|
||||
visitor.visit_generics(&sig.generics);
|
||||
visitor.visit_explicit_self(&sig.explicit_self);
|
||||
}
|
||||
FnKind::Closure => {}
|
||||
}
|
||||
@ -578,7 +556,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
|
||||
walk_list!(visitor, visit_expr, default);
|
||||
}
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
visitor.visit_explicit_self(&sig.explicit_self);
|
||||
visitor.visit_generics(&sig.generics);
|
||||
walk_fn_decl(visitor, &sig.decl);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::ext::base::{ExtCtxt, Annotatable};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::codemap::{self, DUMMY_SP};
|
||||
use syntax::codemap::{self, respan, DUMMY_SP};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::Handler;
|
||||
use syntax::util::move_map::MoveMap;
|
||||
@ -806,25 +806,21 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics)
|
||||
-> (ast::ExplicitSelf, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
|
||||
-> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
|
||||
|
||||
let mut self_args = Vec::new();
|
||||
let mut nonself_args = Vec::new();
|
||||
let mut arg_tys = Vec::new();
|
||||
let mut nonstatic = false;
|
||||
|
||||
let ast_explicit_self = match self.explicit_self {
|
||||
Some(ref self_ptr) => {
|
||||
let (self_expr, explicit_self) =
|
||||
ty::get_explicit_self(cx, trait_.span, self_ptr);
|
||||
let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| {
|
||||
let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_.span, self_ptr);
|
||||
|
||||
self_args.push(self_expr);
|
||||
nonstatic = true;
|
||||
self_args.push(self_expr);
|
||||
nonstatic = true;
|
||||
|
||||
explicit_self
|
||||
}
|
||||
None => codemap::respan(trait_.span, ast::SelfKind::Static),
|
||||
};
|
||||
explicit_self
|
||||
});
|
||||
|
||||
for (i, ty) in self.args.iter().enumerate() {
|
||||
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
|
||||
@ -857,24 +853,22 @@ impl<'a> MethodDef<'a> {
|
||||
type_ident: Ident,
|
||||
generics: &Generics,
|
||||
abi: Abi,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
explicit_self: Option<ast::ExplicitSelf>,
|
||||
arg_types: Vec<(Ident, P<ast::Ty>)> ,
|
||||
body: P<Expr>) -> ast::ImplItem {
|
||||
|
||||
// create the generics that aren't for Self
|
||||
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
|
||||
|
||||
let self_arg = match explicit_self.node {
|
||||
ast::SelfKind::Static => None,
|
||||
// creating fresh self id
|
||||
_ => Some(ast::Arg::from_self(explicit_self.clone(), trait_.span,
|
||||
ast::Mutability::Immutable)),
|
||||
};
|
||||
// derive doesn't generate `self: TYPE` forms
|
||||
let self_shortcut = explicit_self.is_some();
|
||||
let args = {
|
||||
let args = arg_types.into_iter().map(|(name, ty)| {
|
||||
cx.arg(trait_.span, name, ty)
|
||||
});
|
||||
self_arg.into_iter().chain(args).collect()
|
||||
let self_args = explicit_self.map(|explicit_self| {
|
||||
ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
|
||||
});
|
||||
let nonself_args = arg_types.into_iter()
|
||||
.map(|(name, ty)| cx.arg(trait_.span, name, ty));
|
||||
self_args.into_iter().chain(nonself_args).collect()
|
||||
};
|
||||
|
||||
let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
|
||||
@ -900,7 +894,7 @@ impl<'a> MethodDef<'a> {
|
||||
node: ast::ImplItemKind::Method(ast::MethodSig {
|
||||
generics: fn_generics,
|
||||
abi: abi,
|
||||
explicit_self: explicit_self,
|
||||
self_shortcut: self_shortcut,
|
||||
unsafety: unsafety,
|
||||
constness: ast::Constness::NotConst,
|
||||
decl: fn_decl
|
||||
|
@ -15,11 +15,10 @@ pub use self::PtrTy::*;
|
||||
pub use self::Ty::*;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Expr,Generics,Ident};
|
||||
use syntax::ast::{Expr, Generics, Ident, SelfKind};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::codemap::{Span,respan};
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::ptr::P;
|
||||
|
||||
/// The types of pointers
|
||||
@ -258,12 +257,11 @@ impl<'a> LifetimeBounds<'a> {
|
||||
|
||||
pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
|
||||
-> (P<Expr>, ast::ExplicitSelf) {
|
||||
// this constructs a fresh `self` path, which will match the fresh `self` binding
|
||||
// created below.
|
||||
// this constructs a fresh `self` path
|
||||
let self_path = cx.expr_self(span);
|
||||
match *self_ptr {
|
||||
None => {
|
||||
(self_path, respan(span, ast::SelfKind::Value(keywords::SelfValue.ident())))
|
||||
(self_path, respan(span, SelfKind::Value(ast::Mutability::Immutable)))
|
||||
}
|
||||
Some(ref ptr) => {
|
||||
let self_ty = respan(
|
||||
@ -271,7 +269,7 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
|
||||
match *ptr {
|
||||
Borrowed(ref lt, mutbl) => {
|
||||
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
|
||||
ast::SelfKind::Region(lt, mutbl, keywords::SelfValue.ident())
|
||||
SelfKind::Region(lt, mutbl)
|
||||
}
|
||||
Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition")
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user