diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-12-10 06:15:06 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-12-14 11:11:55 -0500 |
| commit | 22f777ba2ecfcd8d914d37db310a6feb4ad5219e (patch) | |
| tree | c8b867087fe35ee35e239f2aa31ff944d46ca4a5 /src | |
| parent | 5686a91914ac678ccb78220367daefe585a0d66a (diff) | |
| download | rust-22f777ba2ecfcd8d914d37db310a6feb4ad5219e.tar.gz rust-22f777ba2ecfcd8d914d37db310a6feb4ad5219e.zip | |
Parse `unsafe impl` but don't do anything particularly interesting with the results.
Diffstat (limited to 'src')
28 files changed, 97 insertions, 57 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 5af7fec4181..3040125d97e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1729,7 +1729,7 @@ impl LintPass for Stability { } } } - ast::ItemImpl(_, Some(ref t), _, _) => { + ast::ItemImpl(_, _, Some(ref t), _, _) => { let id = ty::trait_ref_to_def_id(cx.tcx, t); self.lint(cx, id, t.path.span); } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 37124286398..b78112f1f78 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -361,6 +361,15 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum) } } +fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety { + let unsafety_doc = reader::get_doc(item_doc, tag_unsafety); + if reader::doc_as_u8(unsafety_doc) != 0 { + ast::Unsafety::Unsafe + } else { + ast::Unsafety::Normal + } +} + pub fn get_trait_def<'tcx>(cdata: Cmd, item_id: ast::NodeId, tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx> @@ -368,10 +377,7 @@ pub fn get_trait_def<'tcx>(cdata: Cmd, let item_doc = lookup_item(item_id, cdata.data()); let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics); let bounds = trait_def_bounds(item_doc, tcx, cdata); - let unsafety = match reader::maybe_get_doc(item_doc, tag_unsafety) { - Some(_) => ast::Unsafety::Unsafe, - None => ast::Unsafety::Normal, - }; + let unsafety = parse_unsafety(item_doc); ty::TraitDef { unsafety: unsafety, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index cb8de256448..a1f04b7412b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1205,7 +1205,7 @@ fn encode_info_for_item(ecx: &EncodeContext, None => {} } } - ast::ItemImpl(_, ref opt_trait, ref ty, ref ast_items) => { + ast::ItemImpl(unsafety, _, ref opt_trait, ref ty, ref ast_items) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); @@ -1218,6 +1218,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id)); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, item.attrs.as_slice()); + encode_unsafety(rbml_w, unsafety); match ty.node { ast::TyPath(ref path, _) if path.segments .len() == 1 => { @@ -1315,15 +1316,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_family(rbml_w, 'I'); encode_item_variances(rbml_w, ecx, item.id); let trait_def = ty::lookup_trait_def(tcx, def_id); - - match trait_def.unsafety { - ast::Unsafety::Unsafe => { - rbml_w.start_tag(tag_unsafety); - rbml_w.end_tag(); - } - ast::Unsafety::Normal => { } - } - + encode_unsafety(rbml_w, trait_def.unsafety); encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics); encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.ident.name); @@ -1683,6 +1676,14 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) { rbml_w.end_tag(); } +fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) { + let byte: u8 = match unsafety { + ast::Unsafety::Normal => 0, + ast::Unsafety::Unsafe => 1, + }; + rbml_w.wr_tagged_u8(tag_unsafety, byte); +} + fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) { fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> { // Pull the cnums and name,vers,hash out of cstore @@ -1864,7 +1865,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> { impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> { fn visit_item(&mut self, item: &ast::Item) { - if let ast::ItemImpl(_, Some(ref trait_ref), _, _) = item.node { + if let ast::ItemImpl(_, _, Some(ref trait_ref), _, _) = item.node { let def_map = &self.ecx.tcx.def_map; let trait_def = def_map.borrow()[trait_ref.ref_id].clone(); let def_id = trait_def.def_id(); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index d2f43faa003..939775e7507 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -355,7 +355,7 @@ impl<'v> Visitor<'v> for LifeSeeder { ast::ItemEnum(ref enum_def, _) if allow_dead_code => { self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id)); } - ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => { + ast::ItemImpl(_, _, Some(ref _trait_ref), _, ref impl_items) => { for impl_item in impl_items.iter() { match *impl_item { ast::MethodImplItem(ref method) => { diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index c638182d7f3..5c2944f898e 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1690,7 +1690,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt, match tcx.map.find(parent) { Some(node) => match node { ast_map::NodeItem(item) => match item.node { - ast::ItemImpl(ref gen, _, _, _) => { + ast::ItemImpl(_, ref gen, _, _, _) => { taken.push_all(gen.lifetimes.as_slice()); } _ => () diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 352c2add000..8cce1321d72 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -241,7 +241,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { // undefined symbols at linkage time if this case is not handled. // // * Private trait impls for private types can be completely ignored - ast::ItemImpl(_, _, ref ty, ref impl_items) => { + ast::ItemImpl(_, _, _, ref ty, ref impl_items) => { let public_ty = match ty.node { ast::TyPath(_, id) => { match self.tcx.def_map.borrow()[id].clone() { @@ -611,7 +611,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { // invoked, and the struct/enum itself is private. Crawl // back up the chains to find the relevant struct/enum that // was private. - ast::ItemImpl(_, _, ref ty, _) => { + ast::ItemImpl(_, _, _, ref ty, _) => { let id = match ty.node { ast::TyPath(_, id) => id, _ => return Some((err_span, err_msg, None)), @@ -1096,7 +1096,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { match item.node { // implementations of traits don't need visibility qualifiers because // that's controlled by having the trait in scope. - ast::ItemImpl(_, Some(..), _, ref impl_items) => { + ast::ItemImpl(_, _, Some(..), _, ref impl_items) => { check_inherited(item.span, item.vis, "visibility qualifiers have no effect on trait \ impls"); @@ -1175,7 +1175,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { }; check_inherited(tcx, item.span, item.vis); match item.node { - ast::ItemImpl(_, _, _, ref impl_items) => { + ast::ItemImpl(_, _, _, _, ref impl_items) => { for impl_item in impl_items.iter() { match *impl_item { ast::MethodImplItem(ref m) => { @@ -1320,7 +1320,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { // (i.e. we could just return here to not check them at // all, or some worse estimation of whether an impl is // publicly visible. - ast::ItemImpl(ref g, ref trait_ref, ref self_, ref impl_items) => { + ast::ItemImpl(_, ref g, ref trait_ref, ref self_, ref impl_items) => { // `impl [... for] Private` is never visible. let self_contains_private; // impl [... for] Public<...>, but not `impl [... for] diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index fa02c940aa7..38d3b859c9d 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -55,7 +55,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool { } match item.node { - ast::ItemImpl(ref generics, _, _, _) | + ast::ItemImpl(_, ref generics, _, _, _) | ast::ItemFn(_, _, _, ref generics, _) => { generics_require_inlining(generics) } @@ -216,7 +216,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { .map .expect_item(impl_did.node) .node { - ast::ItemImpl(ref generics, _, _, _) => { + ast::ItemImpl(_, ref generics, _, _, _) => { generics_require_inlining(generics) } _ => false diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 2e52bab2ae3..c6fdd845ea7 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1432,7 +1432,7 @@ impl<'a> Resolver<'a> { parent } - ItemImpl(_, None, ref ty, ref impl_items) => { + ItemImpl(_, _, None, ref ty, ref impl_items) => { // If this implements an anonymous trait, then add all the // methods within to a new module, if the type was defined // within this module. @@ -1581,7 +1581,7 @@ impl<'a> Resolver<'a> { parent } - ItemImpl(_, Some(_), _, _) => parent, + ItemImpl(_, _, Some(_), _, _) => parent, ItemTrait(_, _, _, _, ref items) => { let name_bindings = @@ -4230,7 +4230,8 @@ impl<'a> Resolver<'a> { }); } - ItemImpl(ref generics, + ItemImpl(_, + ref generics, ref implemented_traits, ref self_type, ref impl_items) => { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 683948cd2e7..48d6ac847d8 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -114,7 +114,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { visit::walk_item(this, item); }); } - ast::ItemImpl(ref generics, _, _, _) => { + ast::ItemImpl(_, ref generics, _, _, _) => { // Impls have both early- and late-bound lifetimes. self.visit_early_late(subst::TypeSpace, generics, |this| { this.check_lifetime_defs(&generics.lifetimes); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4c4df698f33..d6fd3d9a943 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4741,7 +4741,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) match cx.map.find(id.node) { Some(ast_map::NodeItem(item)) => { match item.node { - ast::ItemImpl(_, ref opt_trait, _, _) => { + ast::ItemImpl(_, _, ref opt_trait, _, _) => { match opt_trait { &Some(ref t) => { Some(ty::node_id_to_trait_ref(cx, t.ref_id)) @@ -5722,7 +5722,7 @@ pub fn trait_id_of_impl(tcx: &ctxt, match node { ast_map::NodeItem(item) => { match item.node { - ast::ItemImpl(_, Some(ref trait_ref), _, _) => { + ast::ItemImpl(_, _, Some(ref trait_ref), _, _) => { Some(node_id_to_trait_ref(tcx, trait_ref.ref_id).def_id) } _ => None diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 779fcd70864..712d6217dde 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -282,7 +282,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { NodeItem(item) => { scope_id = item.id; match item.node { - ast::ItemImpl(_, _, ref ty, _) => { + ast::ItemImpl(_, _, _, ref ty, _) => { let mut result = String::from_str("<"); result.push_str(ty_to_string(&**ty).as_slice()); @@ -1040,7 +1040,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { self.process_const(item, &**typ, &**expr), ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params), ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - ast::ItemImpl(ref ty_params, + ast::ItemImpl(_, + ref ty_params, ref trait_ref, ref typ, ref impl_items) => { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index b2578fdbc05..83779ffbe16 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2304,7 +2304,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { let mut v = TransItemVisitor{ ccx: ccx }; v.visit_block(&**body); } - ast::ItemImpl(ref generics, _, _, ref impl_items) => { + ast::ItemImpl(_, ref generics, _, _, ref impl_items) => { meth::trans_impl(ccx, item.ident, impl_items.as_slice(), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c64519c96dd..e0df94745d6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -595,7 +595,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id); check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env); } - ast::ItemImpl(_, ref opt_trait_ref, _, ref impl_items) => { + ast::ItemImpl(_, _, ref opt_trait_ref, _, ref impl_items) => { debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id); let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index defad95f749..7bc79d6e4a4 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> { //debug!("(checking coherence) item '{}'", token::get_ident(item.ident)); match item.node { - ItemImpl(_, ref opt_trait, _, _) => { + ItemImpl(_, _, ref opt_trait, _, _) => { match opt_trait.clone() { Some(opt_trait) => { self.cc.check_implementation(item, &[opt_trait]); @@ -325,7 +325,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Converts an implementation in the AST to a vector of items. fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> { match item.node { - ItemImpl(_, ref trait_refs, _, ref ast_items) => { + ItemImpl(_, _, ref trait_refs, _, ref ast_items) => { let mut items: Vec<ImplOrTraitItemId> = ast_items.iter() .map(|ast_item| { diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index dc3afaae35f..1803bf766dd 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -44,7 +44,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &'v ast::Item) { let def_id = ast_util::local_def(item.id); match item.node { - ast::ItemImpl(_, None, _, _) => { + ast::ItemImpl(_, _, None, _, _) => { // For inherent impls, self type must be a nominal type // defined in this crate. debug!("coherence2::orphan check: inherent impl {}", item.repr(self.tcx)); @@ -64,7 +64,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { } } } - ast::ItemImpl(_, Some(_), _, _) => { + ast::ItemImpl(_, _, Some(_), _, _) => { // "Trait" impl debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx)); if traits::is_orphan_impl(self.tcx, def_id) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 643d8eb60ce..61b8e6c956c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1045,7 +1045,8 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) { enum_definition.variants.as_slice(), generics); }, - ast::ItemImpl(ref generics, + ast::ItemImpl(_, + ref generics, ref opt_trait_ref, ref selfty, ref impl_items) => { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 79f04e91260..6592ca498dc 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -184,6 +184,7 @@ pub struct Trait { } pub struct Impl { + pub unsafety: ast::Unsafety, pub generics: ast::Generics, pub trait_: Option<ast::TraitRef>, pub for_: P<ast::Ty>, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f94e647b1cf..4374ce5deef 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -338,8 +338,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; om.traits.push(t); }, - ast::ItemImpl(ref gen, ref tr, ref ty, ref items) => { + ast::ItemImpl(unsafety, ref gen, ref tr, ref ty, ref items) => { let i = Impl { + unsafety: unsafety, generics: gen.clone(), trait_: tr.clone(), for_: ty.clone(), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1cc6b6feee8..206fb26eb55 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1617,7 +1617,8 @@ pub enum Item_ { // Currently, only Sized makes sense here. TyParamBounds, Vec<TraitItem>), - ItemImpl(Generics, + ItemImpl(Unsafety, + Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self Vec<ImplItem>), diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index a2cdc4d2fbc..6089f39e828 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -755,7 +755,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { let parent = self.parent; self.parent = i.id; match i.node { - ItemImpl(_, _, _, ref impl_items) => { + ItemImpl(_, _, _, _, ref impl_items) => { for impl_item in impl_items.iter() { match *impl_item { MethodImplItem(ref m) => { diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index ee651592117..d2185a00876 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -133,11 +133,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ F: FnMut(&[ast::Attribute]) -> bool { let item = match item { - ast::ItemImpl(a, b, c, impl_items) => { + ast::ItemImpl(u, a, b, c, impl_items) => { let impl_items = impl_items.into_iter() .filter(|ii| impl_item_in_cfg(cx, ii)) .collect(); - ast::ItemImpl(a, b, c, impl_items) + ast::ItemImpl(u, a, b, c, impl_items) } ast::ItemTrait(u, a, b, c, methods) => { let methods = methods.into_iter() diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 820ff08a255..f40be823a1a 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -462,7 +462,8 @@ impl<'a> TraitDef<'a> { self.span, ident, a, - ast::ItemImpl(trait_generics, + ast::ItemImpl(ast::Unsafety::Normal, + trait_generics, opt_trait_ref, self_type, methods.into_iter() diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 66fe672c3e5..9656629e14d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -215,7 +215,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { } } - ast::ItemImpl(_, _, _, ref items) => { + ast::ItemImpl(_, _, _, _, ref items) => { if attr::contains_name(i.attrs.as_slice(), "unsafe_destructor") { self.gate_feature("unsafe_destructor", diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index daed014f4eb..8a578c2cb05 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1008,7 +1008,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { let struct_def = folder.fold_struct_def(struct_def); ItemStruct(struct_def, folder.fold_generics(generics)) } - ItemImpl(generics, ifce, ty, impl_items) => { + ItemImpl(unsafety, generics, ifce, ty, impl_items) => { let mut new_impl_items = Vec::new(); for impl_item in impl_items.iter() { match *impl_item { @@ -1030,7 +1030,8 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { Some(folder.fold_trait_ref((*trait_ref).clone())) } }; - ItemImpl(folder.fold_generics(generics), + ItemImpl(unsafety, + folder.fold_generics(generics), ifce, folder.fold_ty(ty), new_impl_items) @@ -1160,7 +1161,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span} let node = folder.fold_item_underscore(node); let ident = match node { // The node may have changed, recompute the "pretty" impl name. - ItemImpl(_, ref maybe_trait, ref ty, _) => { + ItemImpl(_, _, ref maybe_trait, ref ty, _) => { ast_util::impl_pretty_name(maybe_trait, &**ty) } _ => ident diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b2c30797cac..d1991c0463f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4667,7 +4667,7 @@ impl<'a> Parser<'a> { /// Parses two variants (with the region/type params always optional): /// impl<T> Foo { ... } /// impl<T> ToString for ~[T] { ... } - fn parse_item_impl(&mut self) -> ItemInfo { + fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo { // First, parse type parameters if necessary. let mut generics = self.parse_generics(); @@ -4706,7 +4706,7 @@ impl<'a> Parser<'a> { let ident = ast_util::impl_pretty_name(&opt_trait, &*ty); (ident, - ItemImpl(generics, opt_trait, ty, impl_items), + ItemImpl(unsafety, generics, opt_trait, ty, impl_items), Some(attrs)) } @@ -5556,6 +5556,22 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return IoviItem(item); } + if self.token.is_keyword(keywords::Unsafe) && + self.look_ahead(1u, |t| t.is_keyword(keywords::Impl)) + { + // IMPL ITEM + self.expect_keyword(keywords::Unsafe); + self.expect_keyword(keywords::Impl); + let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe); + let last_span = self.last_span; + let item = self.mk_item(lo, + last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return IoviItem(item); + } if self.token.is_keyword(keywords::Fn) && self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) { // FUNCTION ITEM @@ -5644,7 +5660,7 @@ impl<'a> Parser<'a> { } if self.eat_keyword(keywords::Impl) { // IMPL ITEM - let (ident, item_, extra_attrs) = self.parse_item_impl(); + let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal); let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 037118b145f..db122f271a9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -917,12 +917,16 @@ impl<'a> State<'a> { try!(self.print_struct(&**struct_def, generics, item.ident, item.span)); } - ast::ItemImpl(ref generics, + ast::ItemImpl(unsafety, + ref generics, ref opt_trait, ref ty, ref impl_items) => { - try!(self.head(visibility_qualified(item.vis, - "impl").as_slice())); + try!(self.head("")); + try!(self.print_visibility(item.vis)); + try!(self.print_unsafety(unsafety)); + try!(self.word_nbsp("impl")); + if generics.is_parameterized() { try!(self.print_generics(generics)); try!(space(&mut self.s)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7bb79a15f45..3535c6e267e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -282,7 +282,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_generics(type_parameters); walk_enum_def(visitor, enum_definition, type_parameters) } - ItemImpl(ref type_parameters, + ItemImpl(_, + ref type_parameters, ref trait_reference, ref typ, ref impl_items) => { diff --git a/src/test/pretty/trait-safety.rs b/src/test/pretty/trait-safety.rs index 42e578482e6..b96dbbf3cc9 100644 --- a/src/test/pretty/trait-safety.rs +++ b/src/test/pretty/trait-safety.rs @@ -14,6 +14,10 @@ unsafe trait UnsafeTrait { fn foo(&self); } +unsafe impl UnsafeTrait for int { + fn foo(&self) { } +} + pub unsafe trait PubUnsafeTrait { fn foo(&self); } |
