use symbol::{Symbol, keywords};
use util::ThinVec;
+use std::cmp;
use std::collections::HashSet;
-use std::{cmp, mem, slice};
+use std::mem;
use std::path::{self, Path, PathBuf};
+use std::slice;
bitflags! {
flags Restrictions: u8 {
} else if self.eat_keyword(keywords::Impl) {
// FIXME: figure out priority of `+` in `impl Trait1 + Trait2` (#34511).
TyKind::ImplTrait(self.parse_ty_param_bounds()?)
- } else if self.check(&token::Question) {
+ } else if self.check(&token::Question) ||
+ self.check_lifetime() && self.look_ahead(1, |t| t == &token::BinOp(token::Plus)){
// Bound list (trait object type)
- // Bound lists starting with `'lt` are not currently supported (#40043)
TyKind::TraitObject(self.parse_ty_param_bounds_common(allow_plus)?)
} else {
let msg = format!("expected type, found {}", self.this_token_descr());
/// 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.
allowed to have generics");
}
+ if let ast::Defaultness::Default = defaultness {
+ self.span_err(impl_span, "`default impl` is not allowed for \
+ default trait implementations");
+ }
+
self.expect(&token::OpenDelim(token::Brace))?;
self.expect(&token::CloseDelim(token::Brace))?;
Ok((keywords::Invalid.ident(),
}
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)))
}
}
}
let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location");
- let this_module = match self.directory.path.file_name() {
- Some(file_name) => file_name.to_str().unwrap().to_owned(),
- None => self.root_module_name.as_ref().unwrap().clone(),
- };
- err.span_note(id_sp,
- &format!("maybe move this module `{0}` to its own directory \
- via `{0}{1}mod.rs`",
- this_module,
- path::MAIN_SEPARATOR));
+ if id_sp != syntax_pos::DUMMY_SP {
+ let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp));
+ if let Some(stem) = src_path.file_stem() {
+ let mut dest_path = src_path.clone();
+ dest_path.set_file_name(stem);
+ dest_path.push("mod.rs");
+ err.span_note(id_sp,
+ &format!("maybe move this module `{}` to its own \
+ directory via `{}`", src_path.to_string_lossy(),
+ dest_path.to_string_lossy()));
+ }
+ }
if paths.path_exists {
err.span_note(id_sp,
&format!("... or maybe `use` the module `{}` instead \
of possibly redeclaring it",
paths.name));
- Err(err)
- } else {
- Err(err)
}
+ Err(err)
} else {
paths.result.map_err(|err| self.span_fatal_err(id_sp, err))
}
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,
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,