support default impl for specialization

this commit implements the first step of the `default impl` feature:
all items in a `default impl` are (implicitly) `default` and hence
specializable.
In order to test this feature I've copied all the tests provided for the
`default` method implementation (in run-pass/specialization and
compile-fail/specialization directories) and moved the `default` keyword
from the item to the impl.
See referenced issue for further info
This commit is contained in:
Gianni Ciccarelli 2016-11-18 17:14:42 +01:00
parent 15ce54096a
commit 116e9831a5
50 changed files with 1078 additions and 41 deletions

View file

@ -4863,7 +4863,9 @@ impl<'a> Parser<'a> {
/// impl<T> Foo { ... }
/// impl<T> ToString for &'static T { ... }
/// impl Send for .. {}
fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> {
fn parse_item_impl(&mut self,
unsafety: ast::Unsafety,
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
let impl_span = self.span;
// First, parse type parameters if necessary.
@ -4944,7 +4946,7 @@ impl<'a> Parser<'a> {
}
Ok((keywords::Invalid.ident(),
ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items),
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
Some(attrs)))
}
}
@ -5756,13 +5758,19 @@ impl<'a> Parser<'a> {
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
if self.check_keyword(keywords::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Impl))
if (self.check_keyword(keywords::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) ||
(self.check_keyword(keywords::Default) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) &&
self.look_ahead(2, |t| t.is_keyword(keywords::Impl)))
{
// IMPL ITEM
let defaultness = self.parse_defaultness()?;
self.expect_keyword(keywords::Unsafe)?;
self.expect_keyword(keywords::Impl)?;
let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe)?;
let (ident,
item_,
extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe, defaultness)?;
let prev_span = self.prev_span;
let item = self.mk_item(lo.to(prev_span),
ident,
@ -5856,9 +5864,16 @@ impl<'a> Parser<'a> {
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
if self.eat_keyword(keywords::Impl) {
if (self.check_keyword(keywords::Impl)) ||
(self.check_keyword(keywords::Default) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Impl)))
{
// IMPL ITEM
let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal)?;
let defaultness = self.parse_defaultness()?;
self.expect_keyword(keywords::Impl)?;
let (ident,
item_,
extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal, defaultness)?;
let prev_span = self.prev_span;
let item = self.mk_item(lo.to(prev_span),
ident,