Add a new AST-only type variant ImplicitSelf
This commit is contained in:
parent
5660a00486
commit
1a1de5bf89
8 changed files with 34 additions and 40 deletions
|
@ -269,7 +269,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
P(hir::Ty {
|
P(hir::Ty {
|
||||||
id: t.id,
|
id: t.id,
|
||||||
node: match t.node {
|
node: match t.node {
|
||||||
Infer => hir::TyInfer,
|
Infer | ImplicitSelf => hir::TyInfer,
|
||||||
Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
|
Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
|
||||||
Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
|
Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
|
||||||
Rptr(ref region, ref mt) => {
|
Rptr(ref region, ref mt) => {
|
||||||
|
@ -787,23 +787,24 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
|
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: &_`
|
// Check for `self: _` and `self: &_`
|
||||||
if !sig.self_shortcut {
|
if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
|
||||||
match sig.decl.get_self().map(|eself| eself.node) {
|
match hir_sig.decl.get_self().map(|eself| eself.node) {
|
||||||
Some(SelfKind::Value(..)) | Some(SelfKind::Region(..)) => {
|
Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
|
||||||
self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].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");
|
"the type placeholder `_` is not allowed within types on item signatures");
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::MethodSig {
|
hir_sig
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
|
fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
|
||||||
|
|
|
@ -1387,8 +1387,6 @@ pub struct MethodSig {
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
pub decl: P<FnDecl>,
|
pub decl: P<FnDecl>,
|
||||||
pub generics: Generics,
|
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,
|
/// Represents an item declaration within a trait declaration,
|
||||||
|
@ -1639,6 +1637,8 @@ pub enum TyKind {
|
||||||
/// TyKind::Infer means the type should be inferred instead of it having been
|
/// TyKind::Infer means the type should be inferred instead of it having been
|
||||||
/// specified. This can appear anywhere in a type.
|
/// specified. This can appear anywhere in a type.
|
||||||
Infer,
|
Infer,
|
||||||
|
/// Inferred type of a `self` or `&self` argument in a method.
|
||||||
|
ImplicitSelf,
|
||||||
// A macro in the type position.
|
// A macro in the type position.
|
||||||
Mac(Mac),
|
Mac(Mac),
|
||||||
}
|
}
|
||||||
|
@ -1696,8 +1696,8 @@ impl Arg {
|
||||||
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
|
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
|
||||||
if ident.node.name == keywords::SelfValue.name() {
|
if ident.node.name == keywords::SelfValue.name() {
|
||||||
return match self.ty.node {
|
return match self.ty.node {
|
||||||
TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
||||||
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => {
|
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::ImplicitSelf => {
|
||||||
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
||||||
}
|
}
|
||||||
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
|
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
|
||||||
|
@ -1719,7 +1719,7 @@ impl Arg {
|
||||||
pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
|
pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
|
||||||
let infer_ty = P(Ty {
|
let infer_ty = P(Ty {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
node: TyKind::Infer,
|
node: TyKind::ImplicitSelf,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
});
|
});
|
||||||
let arg = |mutbl, ty, span| Arg {
|
let arg = |mutbl, ty, span| Arg {
|
||||||
|
|
|
@ -1128,7 +1128,6 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
|
||||||
(ast::MethodSig {
|
(ast::MethodSig {
|
||||||
generics: fld.fold_generics(sig.generics),
|
generics: fld.fold_generics(sig.generics),
|
||||||
abi: sig.abi,
|
abi: sig.abi,
|
||||||
self_shortcut: sig.self_shortcut,
|
|
||||||
unsafety: sig.unsafety,
|
unsafety: sig.unsafety,
|
||||||
constness: sig.constness,
|
constness: sig.constness,
|
||||||
decl: rewritten_fn_decl
|
decl: rewritten_fn_decl
|
||||||
|
|
|
@ -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 {
|
t.map(|Ty {id, node, span}| Ty {
|
||||||
id: fld.new_id(id),
|
id: fld.new_id(id),
|
||||||
node: match node {
|
node: match node {
|
||||||
TyKind::Infer => node,
|
TyKind::Infer | TyKind::ImplicitSelf => node,
|
||||||
TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)),
|
TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)),
|
||||||
TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)),
|
TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)),
|
||||||
TyKind::Rptr(region, mt) => {
|
TyKind::Rptr(region, mt) => {
|
||||||
|
@ -1066,7 +1066,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
|
||||||
MethodSig {
|
MethodSig {
|
||||||
generics: folder.fold_generics(sig.generics),
|
generics: folder.fold_generics(sig.generics),
|
||||||
abi: sig.abi,
|
abi: sig.abi,
|
||||||
self_shortcut: sig.self_shortcut,
|
|
||||||
unsafety: sig.unsafety,
|
unsafety: sig.unsafety,
|
||||||
constness: sig.constness,
|
constness: sig.constness,
|
||||||
decl: folder.fold_fn_decl(sig.decl)
|
decl: folder.fold_fn_decl(sig.decl)
|
||||||
|
|
|
@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> {
|
||||||
let ident = p.parse_ident()?;
|
let ident = p.parse_ident()?;
|
||||||
let mut generics = p.parse_generics()?;
|
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
|
// This is somewhat dubious; We don't want to allow
|
||||||
// argument names to be left off if there is a
|
// argument names to be left off if there is a
|
||||||
// definition...
|
// definition...
|
||||||
|
@ -1324,7 +1324,6 @@ impl<'a> Parser<'a> {
|
||||||
decl: d,
|
decl: d,
|
||||||
generics: generics,
|
generics: generics,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
self_shortcut: self_shortcut,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = match p.token {
|
let body = match p.token {
|
||||||
|
@ -4617,7 +4616,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the parsed optional self argument and whether a self shortcut was used.
|
/// 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 {
|
let expect_ident = |this: &mut Self| match this.token {
|
||||||
// Preserve hygienic context.
|
// Preserve hygienic context.
|
||||||
token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) }
|
token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) }
|
||||||
|
@ -4656,7 +4655,7 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
(SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self))
|
(SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self))
|
||||||
} else {
|
} else {
|
||||||
return Ok((None, false));
|
return Ok(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token::BinOp(token::Star) => {
|
token::BinOp(token::Star) => {
|
||||||
|
@ -4676,7 +4675,7 @@ impl<'a> Parser<'a> {
|
||||||
self.span_err(self.span, "cannot pass `self` by raw pointer");
|
self.span_err(self.span, "cannot pass `self` by raw pointer");
|
||||||
(SelfKind::Value(Mutability::Immutable), expect_ident(self))
|
(SelfKind::Value(Mutability::Immutable), expect_ident(self))
|
||||||
} else {
|
} else {
|
||||||
return Ok((None, false));
|
return Ok(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token::Ident(..) => {
|
token::Ident(..) => {
|
||||||
|
@ -4703,27 +4702,24 @@ impl<'a> Parser<'a> {
|
||||||
(SelfKind::Value(Mutability::Mutable), eself_ident)
|
(SelfKind::Value(Mutability::Mutable), eself_ident)
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
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.
|
/// 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,
|
fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>>
|
||||||
parse_arg_fn: F)
|
|
||||||
-> PResult<'a, (P<FnDecl>, bool)>
|
|
||||||
where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
|
where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
|
||||||
{
|
{
|
||||||
self.expect(&token::OpenDelim(token::Paren))?;
|
self.expect(&token::OpenDelim(token::Paren))?;
|
||||||
|
|
||||||
// Parse optional self argument
|
// 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.
|
// Parse the rest of the function parameter list.
|
||||||
let sep = SeqSep::trailing_allowed(token::Comma);
|
let sep = SeqSep::trailing_allowed(token::Comma);
|
||||||
|
@ -4745,11 +4741,11 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Parse closing paren and return type.
|
// Parse closing paren and return type.
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
Ok((P(FnDecl {
|
Ok(P(FnDecl {
|
||||||
inputs: fn_inputs,
|
inputs: fn_inputs,
|
||||||
output: self.parse_ret_ty()?,
|
output: self.parse_ret_ty()?,
|
||||||
variadic: false
|
variadic: false
|
||||||
}), self_shortcut))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the |arg, arg| header on a lambda
|
// parse the |arg, arg| header on a lambda
|
||||||
|
@ -4942,13 +4938,12 @@ impl<'a> Parser<'a> {
|
||||||
let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
|
let (constness, unsafety, abi) = self.parse_fn_front_matter()?;
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
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()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||||
Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig {
|
Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig {
|
||||||
generics: generics,
|
generics: generics,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
self_shortcut: self_shortcut,
|
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
constness: constness,
|
constness: constness,
|
||||||
decl: decl
|
decl: decl
|
||||||
|
|
|
@ -1030,6 +1030,9 @@ impl<'a> State<'a> {
|
||||||
ast::TyKind::Infer => {
|
ast::TyKind::Infer => {
|
||||||
word(&mut self.s, "_")?;
|
word(&mut self.s, "_")?;
|
||||||
}
|
}
|
||||||
|
ast::TyKind::ImplicitSelf => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
ast::TyKind::Mac(ref m) => {
|
ast::TyKind::Mac(ref m) => {
|
||||||
self.print_mac(m, token::Paren)?;
|
self.print_mac(m, token::Paren)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
TyKind::Typeof(ref expression) => {
|
TyKind::Typeof(ref expression) => {
|
||||||
visitor.visit_expr(expression)
|
visitor.visit_expr(expression)
|
||||||
}
|
}
|
||||||
TyKind::Infer => {}
|
TyKind::Infer | TyKind::ImplicitSelf => {}
|
||||||
TyKind::Mac(ref mac) => {
|
TyKind::Mac(ref mac) => {
|
||||||
visitor.visit_mac(mac)
|
visitor.visit_mac(mac)
|
||||||
}
|
}
|
||||||
|
|
|
@ -860,8 +860,6 @@ impl<'a> MethodDef<'a> {
|
||||||
// create the generics that aren't for Self
|
// create the generics that aren't for Self
|
||||||
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
|
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 args = {
|
||||||
let self_args = explicit_self.map(|explicit_self| {
|
let self_args = explicit_self.map(|explicit_self| {
|
||||||
ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
|
ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
|
||||||
|
@ -894,7 +892,6 @@ impl<'a> MethodDef<'a> {
|
||||||
node: ast::ImplItemKind::Method(ast::MethodSig {
|
node: ast::ImplItemKind::Method(ast::MethodSig {
|
||||||
generics: fn_generics,
|
generics: fn_generics,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
self_shortcut: self_shortcut,
|
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
constness: ast::Constness::NotConst,
|
constness: ast::Constness::NotConst,
|
||||||
decl: fn_decl
|
decl: fn_decl
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue