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]
This commit is contained in:
parent
459ffc2adc
commit
357d5cd96c
25 changed files with 633 additions and 157 deletions
|
@ -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),
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue