Parse unsafe trait
but do not do anything with it beyond parsing and integrating into rustdoc etc.
This commit is contained in:
parent
092d04a40a
commit
5686a91914
25 changed files with 103 additions and 34 deletions
|
@ -1721,7 +1721,7 @@ impl LintPass for Stability {
|
||||||
if self.is_internal(cx, item.span) { return }
|
if self.is_internal(cx, item.span) { return }
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemTrait(_, _, ref supertraits, _) => {
|
ast::ItemTrait(_, _, _, ref supertraits, _) => {
|
||||||
for t in supertraits.iter() {
|
for t in supertraits.iter() {
|
||||||
if let ast::TraitTyParamBound(ref t) = *t {
|
if let ast::TraitTyParamBound(ref t) = *t {
|
||||||
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
|
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
|
||||||
|
|
|
@ -255,3 +255,5 @@ pub const tag_method_ty_generics: uint = 0xa7;
|
||||||
pub const tag_predicate: uint = 0xa8;
|
pub const tag_predicate: uint = 0xa8;
|
||||||
pub const tag_predicate_space: uint = 0xa9;
|
pub const tag_predicate_space: uint = 0xa9;
|
||||||
pub const tag_predicate_data: uint = 0xb0;
|
pub const tag_predicate_data: uint = 0xb0;
|
||||||
|
|
||||||
|
pub const tag_unsafety: uint = 0xb1;
|
||||||
|
|
|
@ -368,8 +368,13 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
|
||||||
let item_doc = lookup_item(item_id, cdata.data());
|
let item_doc = lookup_item(item_id, cdata.data());
|
||||||
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
|
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
|
||||||
let bounds = trait_def_bounds(item_doc, tcx, cdata);
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
ty::TraitDef {
|
ty::TraitDef {
|
||||||
|
unsafety: unsafety,
|
||||||
generics: generics,
|
generics: generics,
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
|
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
|
||||||
|
|
|
@ -1308,13 +1308,22 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ItemTrait(_, _, _, ref ms) => {
|
ast::ItemTrait(_, _, _, _, ref ms) => {
|
||||||
add_to_index(item, rbml_w, index);
|
add_to_index(item, rbml_w, index);
|
||||||
rbml_w.start_tag(tag_items_data_item);
|
rbml_w.start_tag(tag_items_data_item);
|
||||||
encode_def_id(rbml_w, def_id);
|
encode_def_id(rbml_w, def_id);
|
||||||
encode_family(rbml_w, 'I');
|
encode_family(rbml_w, 'I');
|
||||||
encode_item_variances(rbml_w, ecx, item.id);
|
encode_item_variances(rbml_w, ecx, item.id);
|
||||||
let trait_def = ty::lookup_trait_def(tcx, def_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_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
|
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_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
|
||||||
encode_name(rbml_w, item.ident.name);
|
encode_name(rbml_w, item.ident.name);
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
|
||||||
// method to the root. In this case, if the trait is private, then
|
// method to the root. In this case, if the trait is private, then
|
||||||
// parent all the methods to the trait to indicate that they're
|
// parent all the methods to the trait to indicate that they're
|
||||||
// private.
|
// private.
|
||||||
ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
|
ast::ItemTrait(_, _, _, _, ref methods) if item.vis != ast::Public => {
|
||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
match *m {
|
match *m {
|
||||||
ast::ProvidedMethod(ref m) => {
|
ast::ProvidedMethod(ref m) => {
|
||||||
|
@ -282,7 +282,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
// Default methods on traits are all public so long as the trait
|
// Default methods on traits are all public so long as the trait
|
||||||
// is public
|
// is public
|
||||||
ast::ItemTrait(_, _, _, ref methods) if public_first => {
|
ast::ItemTrait(_, _, _, _, ref methods) if public_first => {
|
||||||
for method in methods.iter() {
|
for method in methods.iter() {
|
||||||
match *method {
|
match *method {
|
||||||
ast::ProvidedMethod(ref m) => {
|
ast::ProvidedMethod(ref m) => {
|
||||||
|
@ -1134,7 +1134,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemTrait(_, _, _, ref methods) => {
|
ast::ItemTrait(_, _, _, _, ref methods) => {
|
||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
match *m {
|
match *m {
|
||||||
ast::ProvidedMethod(ref m) => {
|
ast::ProvidedMethod(ref m) => {
|
||||||
|
@ -1198,7 +1198,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
ast::ItemStruct(ref def, _) => check_struct(&**def),
|
ast::ItemStruct(ref def, _) => check_struct(&**def),
|
||||||
|
|
||||||
ast::ItemTrait(_, _, _, ref methods) => {
|
ast::ItemTrait(_, _, _, _, ref methods) => {
|
||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
match *m {
|
match *m {
|
||||||
ast::RequiredMethod(..) => {}
|
ast::RequiredMethod(..) => {}
|
||||||
|
@ -1305,7 +1305,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||||
// namespace (the contents have their own privacies).
|
// namespace (the contents have their own privacies).
|
||||||
ast::ItemForeignMod(_) => {}
|
ast::ItemForeignMod(_) => {}
|
||||||
|
|
||||||
ast::ItemTrait(_, _, ref bounds, _) => {
|
ast::ItemTrait(_, _, _, ref bounds, _) => {
|
||||||
if !self.trait_is_public(item.id) {
|
if !self.trait_is_public(item.id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1583,7 +1583,7 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
ItemImpl(_, Some(_), _, _) => parent,
|
ItemImpl(_, Some(_), _, _) => parent,
|
||||||
|
|
||||||
ItemTrait(_, _, _, ref items) => {
|
ItemTrait(_, _, _, _, ref items) => {
|
||||||
let name_bindings =
|
let name_bindings =
|
||||||
self.add_child(name,
|
self.add_child(name,
|
||||||
parent.clone(),
|
parent.clone(),
|
||||||
|
@ -4241,7 +4241,7 @@ impl<'a> Resolver<'a> {
|
||||||
impl_items.as_slice());
|
impl_items.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTrait(ref generics, ref unbound, ref bounds, ref trait_items) => {
|
ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
|
||||||
// Create a new rib for the self type.
|
// Create a new rib for the self type.
|
||||||
let mut self_type_rib = Rib::new(ItemRibKind);
|
let mut self_type_rib = Rib::new(ItemRibKind);
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||||
ast::ItemTy(_, ref generics) |
|
ast::ItemTy(_, ref generics) |
|
||||||
ast::ItemEnum(_, ref generics) |
|
ast::ItemEnum(_, ref generics) |
|
||||||
ast::ItemStruct(_, ref generics) |
|
ast::ItemStruct(_, ref generics) |
|
||||||
ast::ItemTrait(ref generics, _, _, _) => {
|
ast::ItemTrait(_, ref generics, _, _, _) => {
|
||||||
// These kinds of items have only early bound lifetime parameters.
|
// These kinds of items have only early bound lifetime parameters.
|
||||||
let lifetimes = &generics.lifetimes;
|
let lifetimes = &generics.lifetimes;
|
||||||
self.with(EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE), |this| {
|
self.with(EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE), |this| {
|
||||||
|
|
|
@ -1915,6 +1915,8 @@ pub struct Polytype<'tcx> {
|
||||||
|
|
||||||
/// As `Polytype` but for a trait ref.
|
/// As `Polytype` but for a trait ref.
|
||||||
pub struct TraitDef<'tcx> {
|
pub struct TraitDef<'tcx> {
|
||||||
|
pub unsafety: ast::Unsafety,
|
||||||
|
|
||||||
/// Generic type definitions. Note that `Self` is listed in here
|
/// Generic type definitions. Note that `Self` is listed in here
|
||||||
/// as having a single bound, the trait itself (e.g., in the trait
|
/// as having a single bound, the trait itself (e.g., in the trait
|
||||||
/// `Eq`, there is a single bound `Self : Eq`). This is so that
|
/// `Eq`, there is a single bound `Self : Eq`). This is so that
|
||||||
|
@ -4572,7 +4574,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
||||||
match cx.map.find(id.node) {
|
match cx.map.find(id.node) {
|
||||||
Some(ast_map::NodeItem(item)) => {
|
Some(ast_map::NodeItem(item)) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemTrait(_, _, _, ref ms) => {
|
ItemTrait(_, _, _, _, ref ms) => {
|
||||||
let (_, p) =
|
let (_, p) =
|
||||||
ast_util::split_trait_methods(ms.as_slice());
|
ast_util::split_trait_methods(ms.as_slice());
|
||||||
p.iter()
|
p.iter()
|
||||||
|
|
|
@ -1050,7 +1050,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
&**typ,
|
&**typ,
|
||||||
impl_items)
|
impl_items)
|
||||||
}
|
}
|
||||||
ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
|
ast::ItemTrait(_, ref generics, _, ref trait_refs, ref methods) =>
|
||||||
self.process_trait(item, generics, trait_refs, methods),
|
self.process_trait(item, generics, trait_refs, methods),
|
||||||
ast::ItemMod(ref m) => self.process_mod(item, m),
|
ast::ItemMod(ref m) => self.process_mod(item, m),
|
||||||
ast::ItemTy(ref ty, ref ty_params) => {
|
ast::ItemTy(ref ty, ref ty_params) => {
|
||||||
|
|
|
@ -625,7 +625,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ast::ItemTrait(_, _, _, ref trait_methods) => {
|
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
|
||||||
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
|
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
|
||||||
for trait_method in trait_methods.iter() {
|
for trait_method in trait_methods.iter() {
|
||||||
match *trait_method {
|
match *trait_method {
|
||||||
|
|
|
@ -258,7 +258,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
trait_def: &ty::TraitDef<'tcx>) {
|
trait_def: &ty::TraitDef<'tcx>) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
|
if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
|
||||||
if let ast::ItemTrait(_, _, _, ref trait_items) = item.node {
|
if let ast::ItemTrait(_, _, _, _, ref trait_items) = item.node {
|
||||||
// For each method, construct a suitable ty::Method and
|
// For each method, construct a suitable ty::Method and
|
||||||
// store it into the `tcx.impl_or_trait_items` table:
|
// store it into the `tcx.impl_or_trait_items` table:
|
||||||
for trait_item in trait_items.iter() {
|
for trait_item in trait_items.iter() {
|
||||||
|
@ -1144,7 +1144,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
||||||
AllowEqConstraints::DontAllow);
|
AllowEqConstraints::DontAllow);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::ItemTrait(_, _, _, ref trait_methods) => {
|
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
|
||||||
let trait_def = trait_def_of_item(ccx, it);
|
let trait_def = trait_def_of_item(ccx, it);
|
||||||
|
|
||||||
debug!("trait_def: ident={} trait_def={}",
|
debug!("trait_def: ident={} trait_def={}",
|
||||||
|
@ -1335,12 +1335,13 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
return def.clone();
|
return def.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (generics, unbound, bounds, items) = match it.node {
|
let (unsafety, generics, unbound, bounds, items) = match it.node {
|
||||||
ast::ItemTrait(ref generics,
|
ast::ItemTrait(unsafety,
|
||||||
|
ref generics,
|
||||||
ref unbound,
|
ref unbound,
|
||||||
ref supertraits,
|
ref supertraits,
|
||||||
ref items) => {
|
ref items) => {
|
||||||
(generics, unbound, supertraits, items.as_slice())
|
(unsafety, generics, unbound, supertraits, items.as_slice())
|
||||||
}
|
}
|
||||||
ref s => {
|
ref s => {
|
||||||
tcx.sess.span_bug(
|
tcx.sess.span_bug(
|
||||||
|
@ -1369,6 +1370,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
let substs = mk_item_substs(ccx, &ty_generics);
|
let substs = mk_item_substs(ccx, &ty_generics);
|
||||||
let trait_def = Rc::new(ty::TraitDef {
|
let trait_def = Rc::new(ty::TraitDef {
|
||||||
|
unsafety: unsafety,
|
||||||
generics: ty_generics,
|
generics: ty_generics,
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
trait_ref: Rc::new(ty::TraitRef {
|
trait_ref: Rc::new(ty::TraitRef {
|
||||||
|
|
|
@ -358,7 +358,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemEnum(_, ref generics) |
|
ast::ItemEnum(_, ref generics) |
|
||||||
ast::ItemStruct(_, ref generics) |
|
ast::ItemStruct(_, ref generics) |
|
||||||
ast::ItemTrait(ref generics, _, _, _) => {
|
ast::ItemTrait(_, ref generics, _, _, _) => {
|
||||||
for (i, p) in generics.lifetimes.iter().enumerate() {
|
for (i, p) in generics.lifetimes.iter().enumerate() {
|
||||||
let id = p.lifetime.id;
|
let id = p.lifetime.id;
|
||||||
self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
|
self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
|
||||||
|
|
|
@ -161,6 +161,7 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
|
||||||
let trait_def = ty::lookup_trait_def(tcx, did);
|
let trait_def = ty::lookup_trait_def(tcx, did);
|
||||||
let (bounds, default_unbound) = trait_def.bounds.clean(cx);
|
let (bounds, default_unbound) = trait_def.bounds.clean(cx);
|
||||||
clean::Trait {
|
clean::Trait {
|
||||||
|
unsafety: def.unsafety,
|
||||||
generics: (&def.generics, subst::TypeSpace).clean(cx),
|
generics: (&def.generics, subst::TypeSpace).clean(cx),
|
||||||
items: items.collect(),
|
items: items.collect(),
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
|
|
@ -974,6 +974,7 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
|
||||||
|
|
||||||
#[deriving(Clone, Encodable, Decodable)]
|
#[deriving(Clone, Encodable, Decodable)]
|
||||||
pub struct Trait {
|
pub struct Trait {
|
||||||
|
pub unsafety: ast::Unsafety,
|
||||||
pub items: Vec<TraitMethod>,
|
pub items: Vec<TraitMethod>,
|
||||||
pub generics: Generics,
|
pub generics: Generics,
|
||||||
pub bounds: Vec<TyParamBound>,
|
pub bounds: Vec<TyParamBound>,
|
||||||
|
@ -991,6 +992,7 @@ impl Clean<Item> for doctree::Trait {
|
||||||
visibility: self.vis.clean(cx),
|
visibility: self.vis.clean(cx),
|
||||||
stability: self.stab.clean(cx),
|
stability: self.stab.clean(cx),
|
||||||
inner: TraitItem(Trait {
|
inner: TraitItem(Trait {
|
||||||
|
unsafety: self.unsafety,
|
||||||
items: self.items.clean(cx),
|
items: self.items.clean(cx),
|
||||||
generics: self.generics.clean(cx),
|
generics: self.generics.clean(cx),
|
||||||
bounds: self.bounds.clean(cx),
|
bounds: self.bounds.clean(cx),
|
||||||
|
|
|
@ -170,6 +170,7 @@ pub struct Constant {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Trait {
|
pub struct Trait {
|
||||||
|
pub unsafety: ast::Unsafety,
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub items: Vec<ast::TraitItem>, //should be TraitItem
|
pub items: Vec<ast::TraitItem>, //should be TraitItem
|
||||||
pub generics: ast::Generics,
|
pub generics: ast::Generics,
|
||||||
|
|
|
@ -1693,8 +1693,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the trait definition
|
// Output the trait definition
|
||||||
try!(write!(w, "<pre class='rust trait'>{}trait {}{}{}{} ",
|
try!(write!(w, "<pre class='rust trait'>{}{}trait {}{}{}{} ",
|
||||||
VisSpace(it.visibility),
|
VisSpace(it.visibility),
|
||||||
|
UnsafetySpace(t.unsafety),
|
||||||
it.name.as_ref().unwrap().as_slice(),
|
it.name.as_ref().unwrap().as_slice(),
|
||||||
t.generics,
|
t.generics,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
|
@ -322,8 +322,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
om.constants.push(s);
|
om.constants.push(s);
|
||||||
},
|
},
|
||||||
ast::ItemTrait(ref gen, ref def_ub, ref b, ref items) => {
|
ast::ItemTrait(unsafety, ref gen, ref def_ub, ref b, ref items) => {
|
||||||
let t = Trait {
|
let t = Trait {
|
||||||
|
unsafety: unsafety,
|
||||||
name: name,
|
name: name,
|
||||||
items: items.clone(),
|
items: items.clone(),
|
||||||
generics: gen.clone(),
|
generics: gen.clone(),
|
||||||
|
|
|
@ -1611,7 +1611,8 @@ pub enum Item_ {
|
||||||
ItemEnum(EnumDef, Generics),
|
ItemEnum(EnumDef, Generics),
|
||||||
ItemStruct(P<StructDef>, Generics),
|
ItemStruct(P<StructDef>, Generics),
|
||||||
/// Represents a Trait Declaration
|
/// Represents a Trait Declaration
|
||||||
ItemTrait(Generics,
|
ItemTrait(Unsafety,
|
||||||
|
Generics,
|
||||||
Option<TraitRef>, // (optional) default bound not required for Self.
|
Option<TraitRef>, // (optional) default bound not required for Self.
|
||||||
// Currently, only Sized makes sense here.
|
// Currently, only Sized makes sense here.
|
||||||
TyParamBounds,
|
TyParamBounds,
|
||||||
|
|
|
@ -786,7 +786,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemTrait(_, _, ref bounds, ref trait_items) => {
|
ItemTrait(_, _, _, ref bounds, ref trait_items) => {
|
||||||
for b in bounds.iter() {
|
for b in bounds.iter() {
|
||||||
if let TraitTyParamBound(ref t) = *b {
|
if let TraitTyParamBound(ref t) = *b {
|
||||||
self.insert(t.trait_ref.ref_id, NodeItem(i));
|
self.insert(t.trait_ref.ref_id, NodeItem(i));
|
||||||
|
|
|
@ -139,11 +139,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
|
||||||
.collect();
|
.collect();
|
||||||
ast::ItemImpl(a, b, c, impl_items)
|
ast::ItemImpl(a, b, c, impl_items)
|
||||||
}
|
}
|
||||||
ast::ItemTrait(a, b, c, methods) => {
|
ast::ItemTrait(u, a, b, c, methods) => {
|
||||||
let methods = methods.into_iter()
|
let methods = methods.into_iter()
|
||||||
.filter(|m| trait_method_in_cfg(cx, m))
|
.filter(|m| trait_method_in_cfg(cx, m))
|
||||||
.collect();
|
.collect();
|
||||||
ast::ItemTrait(a, b, c, methods)
|
ast::ItemTrait(u, a, b, c, methods)
|
||||||
}
|
}
|
||||||
ast::ItemStruct(def, generics) => {
|
ast::ItemStruct(def, generics) => {
|
||||||
ast::ItemStruct(fold_struct(cx, def), generics)
|
ast::ItemStruct(fold_struct(cx, def), generics)
|
||||||
|
|
|
@ -1035,7 +1035,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
||||||
folder.fold_ty(ty),
|
folder.fold_ty(ty),
|
||||||
new_impl_items)
|
new_impl_items)
|
||||||
}
|
}
|
||||||
ItemTrait(generics, unbound, bounds, methods) => {
|
ItemTrait(unsafety, generics, unbound, bounds, methods) => {
|
||||||
let bounds = folder.fold_bounds(bounds);
|
let bounds = folder.fold_bounds(bounds);
|
||||||
let methods = methods.into_iter().flat_map(|method| {
|
let methods = methods.into_iter().flat_map(|method| {
|
||||||
let r = match method {
|
let r = match method {
|
||||||
|
@ -1063,7 +1063,8 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
||||||
};
|
};
|
||||||
r
|
r
|
||||||
}).collect();
|
}).collect();
|
||||||
ItemTrait(folder.fold_generics(generics),
|
ItemTrait(unsafety,
|
||||||
|
folder.fold_generics(generics),
|
||||||
unbound,
|
unbound,
|
||||||
bounds,
|
bounds,
|
||||||
methods)
|
methods)
|
||||||
|
|
|
@ -4628,7 +4628,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse trait Foo { ... }
|
/// Parse trait Foo { ... }
|
||||||
fn parse_item_trait(&mut self) -> ItemInfo {
|
fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo {
|
||||||
let ident = self.parse_ident();
|
let ident = self.parse_ident();
|
||||||
let mut tps = self.parse_generics();
|
let mut tps = self.parse_generics();
|
||||||
let sized = self.parse_for_sized();
|
let sized = self.parse_for_sized();
|
||||||
|
@ -4639,7 +4639,7 @@ impl<'a> Parser<'a> {
|
||||||
self.parse_where_clause(&mut tps);
|
self.parse_where_clause(&mut tps);
|
||||||
|
|
||||||
let meths = self.parse_trait_items();
|
let meths = self.parse_trait_items();
|
||||||
(ident, ItemTrait(tps, sized, bounds, meths), None)
|
(ident, ItemTrait(unsafety, tps, sized, bounds, meths), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
|
fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
|
||||||
|
@ -5539,6 +5539,23 @@ impl<'a> Parser<'a> {
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return IoviItem(item);
|
||||||
}
|
}
|
||||||
|
if self.token.is_keyword(keywords::Unsafe) &&
|
||||||
|
self.look_ahead(1u, |t| t.is_keyword(keywords::Trait))
|
||||||
|
{
|
||||||
|
// UNSAFE TRAIT ITEM
|
||||||
|
self.expect_keyword(keywords::Unsafe);
|
||||||
|
self.expect_keyword(keywords::Trait);
|
||||||
|
let (ident, item_, extra_attrs) =
|
||||||
|
self.parse_item_trait(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) &&
|
if self.token.is_keyword(keywords::Fn) &&
|
||||||
self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
|
self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
|
||||||
// FUNCTION ITEM
|
// FUNCTION ITEM
|
||||||
|
@ -5614,7 +5631,8 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Trait) {
|
if self.eat_keyword(keywords::Trait) {
|
||||||
// TRAIT ITEM
|
// TRAIT ITEM
|
||||||
let (ident, item_, extra_attrs) = self.parse_item_trait();
|
let (ident, item_, extra_attrs) =
|
||||||
|
self.parse_item_trait(ast::Unsafety::Normal);
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
let item = self.mk_item(lo,
|
let item = self.mk_item(lo,
|
||||||
last_span.hi,
|
last_span.hi,
|
||||||
|
|
|
@ -955,9 +955,11 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
try!(self.bclose(item.span));
|
try!(self.bclose(item.span));
|
||||||
}
|
}
|
||||||
ast::ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
|
ast::ItemTrait(unsafety, ref generics, ref unbound, ref bounds, ref methods) => {
|
||||||
try!(self.head(visibility_qualified(item.vis,
|
try!(self.head(""));
|
||||||
"trait").as_slice()));
|
try!(self.print_visibility(item.vis));
|
||||||
|
try!(self.print_unsafety(unsafety));
|
||||||
|
try!(self.word_nbsp("trait"));
|
||||||
try!(self.print_ident(item.ident));
|
try!(self.print_ident(item.ident));
|
||||||
try!(self.print_generics(generics));
|
try!(self.print_generics(generics));
|
||||||
if let &Some(ref tref) = unbound {
|
if let &Some(ref tref) = unbound {
|
||||||
|
|
|
@ -311,7 +311,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||||
generics,
|
generics,
|
||||||
item.id)
|
item.id)
|
||||||
}
|
}
|
||||||
ItemTrait(ref generics, _, ref bounds, ref methods) => {
|
ItemTrait(_, ref generics, _, ref bounds, ref methods) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
walk_ty_param_bounds_helper(visitor, bounds);
|
walk_ty_param_bounds_helper(visitor, bounds);
|
||||||
for method in methods.iter() {
|
for method in methods.iter() {
|
||||||
|
|
21
src/test/pretty/trait-safety.rs
Normal file
21
src/test/pretty/trait-safety.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// pp-exact
|
||||||
|
|
||||||
|
unsafe trait UnsafeTrait {
|
||||||
|
fn foo(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe trait PubUnsafeTrait {
|
||||||
|
fn foo(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
Loading…
Add table
Add a link
Reference in a new issue