Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add a new AST-only type variant ImplicitSelf
  • Loading branch information
petrochenkov committed May 25, 2016
commit 1a1de5bf899a15cd97f2a113add070bec46cf209
23 changes: 12 additions & 11 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ impl<'a> LoweringContext<'a> {
P(hir::Ty {
id: t.id,
node: match t.node {
Infer => hir::TyInfer,
Infer | ImplicitSelf => hir::TyInfer,
Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
Rptr(ref region, ref mt) => {
Expand Down Expand Up @@ -787,23 +787,24 @@ impl<'a> LoweringContext<'a> {
}

fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
let hir_sig = hir::MethodSig {
generics: self.lower_generics(&sig.generics),
abi: sig.abi,
unsafety: self.lower_unsafety(sig.unsafety),
constness: self.lower_constness(sig.constness),
decl: self.lower_fn_decl(&sig.decl),
};
// Check for `self: _` and `self: &_`
if !sig.self_shortcut {
match sig.decl.get_self().map(|eself| eself.node) {
Some(SelfKind::Value(..)) | Some(SelfKind::Region(..)) => {
if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
match hir_sig.decl.get_self().map(|eself| eself.node) {
Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].ty.span,
"the type placeholder `_` is not allowed within types on item signatures");
}
_ => {}
}
}
hir::MethodSig {
generics: self.lower_generics(&sig.generics),
abi: sig.abi,
unsafety: self.lower_unsafety(sig.unsafety),
constness: self.lower_constness(sig.constness),
decl: self.lower_fn_decl(&sig.decl),
}
hir_sig
}

fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
Expand Down
10 changes: 5 additions & 5 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1387,8 +1387,6 @@ pub struct MethodSig {
pub abi: Abi,
pub decl: P<FnDecl>,
pub generics: Generics,
/// 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,
Expand Down Expand Up @@ -1639,6 +1637,8 @@ pub enum TyKind {
/// TyKind::Infer means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
Infer,
/// Inferred type of a `self` or `&self` argument in a method.
ImplicitSelf,
// A macro in the type position.
Mac(Mac),
}
Expand Down Expand Up @@ -1696,8 +1696,8 @@ impl Arg {
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(mutbl))),
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::ImplicitSelf => {
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
}
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
Expand All @@ -1719,7 +1719,7 @@ impl Arg {
pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
let infer_ty = P(Ty {
id: DUMMY_NODE_ID,
node: TyKind::Infer,
node: TyKind::ImplicitSelf,
span: DUMMY_SP,
});
let arg = |mutbl, ty, span| Arg {
Expand Down
1 change: 0 additions & 1 deletion src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,6 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
(ast::MethodSig {
generics: fld.fold_generics(sig.generics),
abi: sig.abi,
self_shortcut: sig.self_shortcut,
unsafety: sig.unsafety,
constness: sig.constness,
decl: rewritten_fn_decl
Expand Down
3 changes: 1 addition & 2 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
t.map(|Ty {id, node, span}| Ty {
id: fld.new_id(id),
node: match node {
TyKind::Infer => node,
TyKind::Infer | TyKind::ImplicitSelf => node,
TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)),
TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)),
TyKind::Rptr(region, mt) => {
Expand Down Expand Up @@ -1066,7 +1066,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
MethodSig {
generics: folder.fold_generics(sig.generics),
abi: sig.abi,
self_shortcut: sig.self_shortcut,
unsafety: sig.unsafety,
constness: sig.constness,
decl: folder.fold_fn_decl(sig.decl)
Expand Down
29 changes: 12 additions & 17 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> {
let ident = p.parse_ident()?;
let mut generics = p.parse_generics()?;

let (d, self_shortcut) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
let d = 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...
Expand All @@ -1324,7 +1324,6 @@ impl<'a> Parser<'a> {
decl: d,
generics: generics,
abi: abi,
self_shortcut: self_shortcut,
};

let body = match p.token {
Expand Down Expand Up @@ -4617,7 +4616,7 @@ impl<'a> Parser<'a> {
}

/// Returns the parsed optional self argument and whether a self shortcut was used.
fn parse_self_arg(&mut self) -> PResult<'a, (Option<Arg>, bool)> {
fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
let expect_ident = |this: &mut Self| match this.token {
// Preserve hygienic context.
token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) }
Expand Down Expand Up @@ -4656,7 +4655,7 @@ impl<'a> Parser<'a> {
self.bump();
(SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self))
} else {
return Ok((None, false));
return Ok(None);
}
}
token::BinOp(token::Star) => {
Expand All @@ -4676,7 +4675,7 @@ impl<'a> Parser<'a> {
self.span_err(self.span, "cannot pass `self` by raw pointer");
(SelfKind::Value(Mutability::Immutable), expect_ident(self))
} else {
return Ok((None, false));
return Ok(None);
}
}
token::Ident(..) => {
Expand All @@ -4703,27 +4702,24 @@ impl<'a> Parser<'a> {
(SelfKind::Value(Mutability::Mutable), eself_ident)
}
} else {
return Ok((None, false));
return Ok(None);
}
}
_ => return Ok((None, false)),
_ => return Ok(None),
};

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))
Ok(Some(Arg::from_self(eself, eself_ident)))
}

/// 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)>
fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>>
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()?;
let self_arg = self.parse_self_arg()?;

// Parse the rest of the function parameter list.
let sep = SeqSep::trailing_allowed(token::Comma);
Expand All @@ -4745,11 +4741,11 @@ impl<'a> Parser<'a> {

// Parse closing paren and return type.
self.expect(&token::CloseDelim(token::Paren))?;
Ok((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
Expand Down Expand Up @@ -4942,13 +4938,12 @@ 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 (decl, self_shortcut) = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
let decl = 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,
self_shortcut: self_shortcut,
unsafety: unsafety,
constness: constness,
decl: decl
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,9 @@ impl<'a> State<'a> {
ast::TyKind::Infer => {
word(&mut self.s, "_")?;
}
ast::TyKind::ImplicitSelf => {
unreachable!();
}
ast::TyKind::Mac(ref m) => {
self.print_mac(m, token::Paren)?;
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyKind::Typeof(ref expression) => {
visitor.visit_expr(expression)
}
TyKind::Infer => {}
TyKind::Infer | TyKind::ImplicitSelf => {}
TyKind::Mac(ref mac) => {
visitor.visit_mac(mac)
}
Expand Down
3 changes: 0 additions & 3 deletions src/libsyntax_ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -860,8 +860,6 @@ impl<'a> MethodDef<'a> {
// create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);

// derive doesn't generate `self: TYPE` forms
let self_shortcut = explicit_self.is_some();
let args = {
let self_args = explicit_self.map(|explicit_self| {
ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
Expand Down Expand Up @@ -894,7 +892,6 @@ impl<'a> MethodDef<'a> {
node: ast::ImplItemKind::Method(ast::MethodSig {
generics: fn_generics,
abi: abi,
self_shortcut: self_shortcut,
unsafety: unsafety,
constness: ast::Constness::NotConst,
decl: fn_decl
Expand Down