about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-05-06 16:37:32 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-07-16 20:01:52 -0700
commit357d5cd96caea4fbccb989dc4bf5eed71c785c1c (patch)
tree444078402829e231abcbef1ab2a6d30af1ac819e /src/libsyntax
parent459ffc2adc74f5e8b64a76f5670edb419b9f65da (diff)
downloadrust-357d5cd96caea4fbccb989dc4bf5eed71c785c1c.tar.gz
rust-357d5cd96caea4fbccb989dc4bf5eed71c785c1c.zip
librustc: Implement the fully-expanded, UFCS form of explicit self.
This makes two changes to region inference: (1) it allows region
inference to relate early-bound regions; and (2) it allows regions to be
related before variance runs. The former is needed because there is no
relation between the two regions before region substitution happens,
while the latter is needed because type collection has to run before
variance. We assume that, before variance is inferred, that lifetimes
are invariant. This is a conservative overapproximation.

This relates to #13885. This does not remove `~self` from the language
yet, however.

[breaking-change]
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs30
-rw-r--r--src/libsyntax/print/pprust.rs5
-rw-r--r--src/libsyntax/visit.rs1
5 files changed, 35 insertions, 8 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 857cb4c0162..d9f14bfa156 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -949,12 +949,14 @@ pub enum RetStyle {
 pub enum ExplicitSelf_ {
     /// No self
     SelfStatic,
-    /// `self
+    /// `self`
     SelfValue(Ident),
     /// `&'lt self`, `&'lt mut self`
     SelfRegion(Option<Lifetime>, Mutability, Ident),
     /// `~self`
-    SelfUniq(Ident)
+    SelfUniq(Ident),
+    /// `self: TYPE`
+    SelfExplicit(P<Ty>, Ident),
 }
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index fd786192cb4..87c762af2e5 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -344,6 +344,7 @@ pub trait Folder {
             SelfRegion(ref lifetime, m, id) => {
                 SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
             }
+            SelfExplicit(ref typ, id) => SelfExplicit(self.fold_ty(*typ), id),
         }
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e0c94dffb5c..bdfd928cfbc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -45,7 +45,7 @@ use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
-use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
+use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfUniq, SelfValue};
 use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
@@ -3843,7 +3843,15 @@ impl<'a> Parser<'a> {
                 }
             }
             token::IDENT(..) if self.is_self_ident() => {
-                SelfValue(self.expect_self_ident())
+                let self_ident = self.expect_self_ident();
+
+                // Determine whether this is the fully explicit form, `self:
+                // TYPE`.
+                if self.eat(&token::COLON) {
+                    SelfExplicit(self.parse_ty(false), self_ident)
+                } else {
+                    SelfValue(self_ident)
+                }
             }
             token::BINOP(token::STAR) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
@@ -3851,7 +3859,9 @@ impl<'a> Parser<'a> {
                 self.bump();
                 let _mutability = if Parser::token_is_mutability(&self.token) {
                     self.parse_mutability()
-                } else { MutImmutable };
+                } else {
+                    MutImmutable
+                };
                 if self.is_self_ident() {
                     let span = self.span;
                     self.span_err(span, "cannot pass self by unsafe pointer");
@@ -3863,7 +3873,15 @@ impl<'a> Parser<'a> {
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
                 mutbl_self = self.parse_mutability();
-                SelfValue(self.expect_self_ident())
+                let self_ident = self.expect_self_ident();
+
+                // Determine whether this is the fully explicit form, `self:
+                // TYPE`.
+                if self.eat(&token::COLON) {
+                    SelfExplicit(self.parse_ty(false), self_ident)
+                } else {
+                    SelfValue(self_ident)
+                }
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| *t == token::TILDE) &&
@@ -3914,8 +3932,8 @@ impl<'a> Parser<'a> {
             }
             SelfValue(id) => parse_remaining_arguments!(id),
             SelfRegion(_,_,id) => parse_remaining_arguments!(id),
-            SelfUniq(id) => parse_remaining_arguments!(id)
-
+            SelfUniq(id) => parse_remaining_arguments!(id),
+            SelfExplicit(_,id) => parse_remaining_arguments!(id),
         };
 
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d524622f8ec..428a15cb8cf 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1859,6 +1859,11 @@ impl<'a> State<'a> {
                 try!(self.print_mutability(m));
                 try!(word(&mut self.s, "self"));
             }
+            ast::SelfExplicit(ref typ, _) => {
+                try!(word(&mut self.s, "self"));
+                try!(self.word_space(":"));
+                try!(self.print_type(*typ));
+            }
         }
         return Ok(true);
     }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 795f19d0cfb..6760d7a3932 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -215,6 +215,7 @@ pub fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
         SelfRegion(ref lifetime, _, _) => {
             visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
         }
+        SelfExplicit(ref typ, _) => visitor.visit_ty(*typ, env.clone()),
     }
 }