Structural changes for associated constants

Introduces new variants and types in syntax::ast, middle::ty, and middle::def.
This commit is contained in:
Sean Patrick Santos 2015-03-14 12:05:00 -06:00
parent 21f278a687
commit b5499775d6
40 changed files with 418 additions and 245 deletions

View File

@ -951,11 +951,8 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
cdata,
did.node,
tcx);
match trait_item {
ty::MethodTraitItem(ref method) => {
result.push((*method).clone())
}
ty::TypeTraitItem(_) => {}
if let ty::MethodTraitItem(ref method) = trait_item {
result.push((*method).clone())
}
}
true

View File

@ -378,14 +378,11 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
let impl_item = ty::impl_or_trait_item(
ecx.tcx,
method_did.def_id());
match impl_item {
ty::MethodTraitItem(ref m) => {
encode_reexported_static_method(rbml_w,
exp,
m.def_id,
m.name);
}
ty::TypeTraitItem(_) => {}
if let ty::MethodTraitItem(ref m) = impl_item {
encode_reexported_static_method(rbml_w,
exp,
m.def_id,
m.name);
}
}
}
@ -1195,6 +1192,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
for &item_def_id in items {
rbml_w.start_tag(tag_item_impl_item);
match item_def_id {
ty::ConstTraitItemId(_) => {}
ty::MethodTraitItemId(item_def_id) => {
encode_def_id(rbml_w, item_def_id);
encode_item_sort(rbml_w, 'r');
@ -1232,6 +1230,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
});
match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
ty::ConstTraitItem(_) => {}
ty::MethodTraitItem(ref method_type) => {
encode_info_for_method(ecx,
rbml_w,
@ -1276,6 +1275,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
for &method_def_id in &*ty::trait_item_def_ids(tcx, def_id) {
rbml_w.start_tag(tag_item_trait_item);
match method_def_id {
ty::ConstTraitItemId(_) => {}
ty::MethodTraitItemId(method_def_id) => {
encode_def_id(rbml_w, method_def_id);
encode_item_sort(rbml_w, 'r');
@ -1321,6 +1321,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
ty::impl_or_trait_item(tcx, item_def_id.def_id());
let is_nonstatic_method;
match trait_item_type {
ty::ConstTraitItem(_) => {
is_nonstatic_method = false;
}
ty::MethodTraitItem(method_ty) => {
let method_def_id = item_def_id.def_id();
@ -1365,6 +1368,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let trait_item = &*ms[i];
encode_attributes(rbml_w, &trait_item.attrs);
match trait_item.node {
ast::ConstTraitItem(_, _) => {}
ast::MethodTraitItem(ref sig, ref body) => {
// If this is a static method, we've already
// encoded this.

View File

@ -465,6 +465,9 @@ impl tr for def::Def {
def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
def::DefAssociatedConst(did, p) => {
def::DefAssociatedConst(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
}
def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
def::DefVariant(e_did, v_did, is_s) => {
def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)

View File

@ -72,7 +72,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
self.tcx.def_map.borrow().get(id).map(|def| {
match def.full_def() {
def::DefConst(_) => {
def::DefConst(_) | def::DefAssociatedConst(..) => {
self.check_def_id(def.def_id())
}
_ if self.ignore_non_const_paths => (),
@ -114,14 +114,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
let trait_item = ty::trait_item(self.tcx,
trait_ref.def_id,
index);
match trait_item {
ty::MethodTraitItem(method) => {
self.check_def_id(method.def_id);
}
ty::TypeTraitItem(typedef) => {
self.check_def_id(typedef.def_id);
}
}
self.check_def_id(trait_item.def_id());
}
}
}
@ -365,6 +358,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(..) => {}
ast::MethodImplItem(..) => {
if opt_trait.is_some() ||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
@ -584,6 +578,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
match trait_method.node {
ast::ConstTraitItem(_, _) => {}
ast::MethodTraitItem(_, Some(ref body)) => {
visit::walk_block(self, body)
}

View File

@ -28,6 +28,7 @@ pub enum Def {
DefForeignMod(ast::DefId),
DefStatic(ast::DefId, bool /* is_mutbl */),
DefConst(ast::DefId),
DefAssociatedConst(ast::DefId /* const */, MethodProvenance),
DefLocal(ast::NodeId),
DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
DefTy(ast::DefId, bool /* is_enum */),
@ -140,7 +141,8 @@ impl Def {
DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
DefMethod(id, _) | DefConst(id) | DefSelfTy(Some(id), None)=> {
DefMethod(id, _) | DefConst(id) | DefAssociatedConst(id, _) |
DefSelfTy(Some(id), None)=> {
id
}
DefLocal(id) |

View File

@ -234,7 +234,7 @@ impl OverloadedCallType {
ty::MethodTraitItem(ref method_descriptor) => {
(*method_descriptor).clone()
}
ty::TypeTraitItem(_) => {
_ => {
tcx.sess.bug("overloaded call method wasn't in method map")
}
};
@ -1183,6 +1183,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
}
Some(def::DefConst(..)) |
Some(def::DefAssociatedConst(..)) |
Some(def::DefLocal(..)) => {
// This is a leaf (i.e. identifier binding
// or constant value to match); thus no

View File

@ -843,8 +843,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
Some(&sig.explicit_self.node),
item.span))
}
ast::TypeImplItem(_) => None,
ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro"),
_ => None,
}
},
ast_map::NodeTraitItem(item) => {
@ -1723,8 +1723,8 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
taken.push_all(&sig.generics.lifetimes);
Some(ii.id)
}
ast::TypeImplItem(_) => None,
ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro")
ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro"),
_ => None,
}
}
_ => None

View File

@ -589,7 +589,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
match def {
def::DefStruct(..) | def::DefVariant(..) | def::DefConst(..) |
def::DefFn(..) | def::DefMethod(..) => {
def::DefAssociatedConst(..) | def::DefFn(..) | def::DefMethod(..) => {
Ok(self.cat_rvalue_node(id, span, expr_ty))
}
def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
@ -1286,7 +1286,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
try!(self.cat_pattern_(cmt_field, &**subpat, op));
}
}
Some(def::DefConst(..)) => {
Some(def::DefConst(..)) | Some(def::DefAssociatedConst(..)) => {
for subpat in subpats {
try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
}

View File

@ -62,7 +62,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) => true,
Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
_ => false
}
}

View File

@ -113,7 +113,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
// If this path leads to a constant, then we need to
// recurse into the constant to continue finding
// items that are reachable.
def::DefConst(..) => {
def::DefConst(..) | def::DefAssociatedConst(..) => {
self.worklist.push(def_id.node);
}
@ -183,12 +183,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
Some(ast_map::NodeTraitItem(trait_method)) => {
match trait_method.node {
ast::ConstTraitItem(_, ref default) => default.is_some(),
ast::MethodTraitItem(_, ref body) => body.is_some(),
ast::TypeTraitItem(..) => false,
}
}
Some(ast_map::NodeImplItem(impl_item)) => {
match impl_item.node {
ast::ConstImplItem(..) => true,
ast::MethodImplItem(ref sig, _) => {
if generics_require_inlining(&sig.generics) ||
attr::requests_inline(&impl_item.attrs) {
@ -303,9 +305,13 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
ast_map::NodeTraitItem(trait_method) => {
match trait_method.node {
ast::ConstTraitItem(_, None) |
ast::MethodTraitItem(_, None) => {
// Keep going, nothing to get exported
}
ast::ConstTraitItem(_, Some(ref expr)) => {
self.visit_expr(&*expr);
}
ast::MethodTraitItem(_, Some(ref body)) => {
visit::walk_block(self, body);
}
@ -314,6 +320,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
ast_map::NodeImplItem(impl_item) => {
match impl_item.node {
ast::ConstImplItem(_, ref expr) => {
self.visit_expr(&*expr);
}
ast::MethodImplItem(ref sig, ref body) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, sig, impl_item, did) {

View File

@ -100,9 +100,7 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
.map(|code| ObjectSafetyViolation::Method(m.clone(), code))
.into_iter()
}
ty::TypeTraitItem(_) => {
None.into_iter()
}
_ => None.into_iter(),
}
})
.collect();

View File

@ -863,7 +863,7 @@ fn confirm_impl_candidate<'cx,'tcx>(
for impl_item in impl_items {
let assoc_type = match *impl_or_trait_items_map.get(&impl_item.def_id()).unwrap() {
ty::TypeTraitItem(ref assoc_type) => assoc_type.clone(),
ty::MethodTraitItem(..) => { continue; }
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => { continue; }
};
if assoc_type.name != obligation.predicate.item_name {

View File

@ -434,7 +434,7 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>,
for trait_item in &**trait_items {
match *trait_item {
ty::MethodTraitItem(_) => method_count += 1,
ty::TypeTraitItem(_) => {}
_ => {}
}
}
}
@ -445,14 +445,14 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>,
for trait_item in trait_items.iter().take(method_offset_in_trait) {
match *trait_item {
ty::MethodTraitItem(_) => method_count += 1,
ty::TypeTraitItem(_) => {}
_ => {}
}
}
// the item at the offset we were given really ought to be a method
assert!(match trait_items[method_offset_in_trait] {
ty::MethodTraitItem(_) => true,
ty::TypeTraitItem(_) => false
_ => false
});
method_count

View File

@ -131,6 +131,7 @@ impl ImplOrTraitItemContainer {
#[derive(Clone, Debug)]
pub enum ImplOrTraitItem<'tcx> {
ConstTraitItem(Rc<AssociatedConst<'tcx>>),
MethodTraitItem(Rc<Method<'tcx>>),
TypeTraitItem(Rc<AssociatedType>),
}
@ -138,6 +139,9 @@ pub enum ImplOrTraitItem<'tcx> {
impl<'tcx> ImplOrTraitItem<'tcx> {
fn id(&self) -> ImplOrTraitItemId {
match *self {
ConstTraitItem(ref associated_const) => {
ConstTraitItemId(associated_const.def_id)
}
MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
TypeTraitItem(ref associated_type) => {
TypeTraitItemId(associated_type.def_id)
@ -147,6 +151,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
pub fn def_id(&self) -> ast::DefId {
match *self {
ConstTraitItem(ref associated_const) => associated_const.def_id,
MethodTraitItem(ref method) => method.def_id,
TypeTraitItem(ref associated_type) => associated_type.def_id,
}
@ -154,13 +159,23 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
pub fn name(&self) -> ast::Name {
match *self {
ConstTraitItem(ref associated_const) => associated_const.name,
MethodTraitItem(ref method) => method.name,
TypeTraitItem(ref associated_type) => associated_type.name,
}
}
pub fn vis(&self) -> ast::Visibility {
match *self {
ConstTraitItem(ref associated_const) => associated_const.vis,
MethodTraitItem(ref method) => method.vis,
TypeTraitItem(ref associated_type) => associated_type.vis,
}
}
pub fn container(&self) -> ImplOrTraitItemContainer {
match *self {
ConstTraitItem(ref associated_const) => associated_const.container,
MethodTraitItem(ref method) => method.container,
TypeTraitItem(ref associated_type) => associated_type.container,
}
@ -169,13 +184,14 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
match *self {
MethodTraitItem(ref m) => Some((*m).clone()),
TypeTraitItem(_) => None
_ => None,
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum ImplOrTraitItemId {
ConstTraitItemId(ast::DefId),
MethodTraitItemId(ast::DefId),
TypeTraitItemId(ast::DefId),
}
@ -183,6 +199,7 @@ pub enum ImplOrTraitItemId {
impl ImplOrTraitItemId {
pub fn def_id(&self) -> ast::DefId {
match *self {
ConstTraitItemId(def_id) => def_id,
MethodTraitItemId(def_id) => def_id,
TypeTraitItemId(def_id) => def_id,
}
@ -236,6 +253,16 @@ impl<'tcx> Method<'tcx> {
}
}
#[derive(Clone, Copy, Debug)]
pub struct AssociatedConst<'tcx> {
pub name: ast::Name,
pub ty: Ty<'tcx>,
pub vis: ast::Visibility,
pub def_id: ast::DefId,
pub container: ImplOrTraitItemContainer,
pub default: Option<ast::DefId>,
}
#[derive(Clone, Copy, Debug)]
pub struct AssociatedType {
pub name: ast::Name,
@ -2273,6 +2300,16 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
match cx.map.find(id) {
Some(ast_map::NodeImplItem(ref impl_item)) => {
match impl_item.node {
ast::ConstImplItem(_, _) => {
let def_id = ast_util::local_def(id);
let scheme = lookup_item_type(cx, def_id);
let predicates = lookup_predicates(cx, def_id);
construct_parameter_environment(cx,
impl_item.span,
&scheme.generics,
&predicates,
id)
}
ast::MethodImplItem(_, ref body) => {
let method_def_id = ast_util::local_def(id);
match ty::impl_or_trait_item(cx, method_def_id) {
@ -2286,11 +2323,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
method_bounds,
body.id)
}
TypeTraitItem(_) => {
_ => {
cx.sess
.bug("ParameterEnvironment::for_item(): \
can't create a parameter environment \
for type trait items")
got non-method item from impl method?!")
}
}
}
@ -2304,6 +2340,25 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
}
Some(ast_map::NodeTraitItem(trait_item)) => {
match trait_item.node {
ast::ConstTraitItem(_, ref default) => {
match *default {
Some(_) => {
let def_id = ast_util::local_def(id);
let scheme = lookup_item_type(cx, def_id);
let predicates = lookup_predicates(cx, def_id);
construct_parameter_environment(cx,
trait_item.span,
&scheme.generics,
&predicates,
id)
}
None => {
cx.sess.bug("ParameterEnvironment::from_item(): \
can't create a parameter environment \
for const trait items without defaults")
}
}
}
ast::MethodTraitItem(_, None) => {
cx.sess.span_bug(trait_item.span,
"ParameterEnvironment::for_item():
@ -2324,11 +2379,11 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
method_bounds,
body.id)
}
TypeTraitItem(_) => {
_ => {
cx.sess
.bug("ParameterEnvironment::for_item(): \
can't create a parameter environment \
for type trait items")
got non-method item from provided \
method?!")
}
}
}
@ -4700,7 +4755,8 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
def::DefUpvar(..) |
def::DefLocal(..) => LvalueExpr,
def::DefConst(..) => RvalueDatumExpr,
def::DefConst(..) |
def::DefAssociatedConst(..) => RvalueDatumExpr,
def => {
tcx.sess.span_bug(
@ -5051,10 +5107,10 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
if let ast::MethodTraitItem(_, Some(_)) = ti.node {
match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
MethodTraitItem(m) => Some(m),
TypeTraitItem(_) => {
_ => {
cx.sess.bug("provided_trait_methods(): \
associated type found from \
looking up ProvidedMethod?!")
non-method item found from \
looking up provided method?!")
}
}
} else {
@ -5155,7 +5211,7 @@ pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool {
Some(ref item) => {
match **item {
TypeTraitItem(_) => true,
MethodTraitItem(_) => false,
_ => false,
}
}
None => false,
@ -6169,7 +6225,7 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
.insert(method_def_id, source);
}
}
TypeTraitItem(_) => {}
_ => {}
}
}
@ -6221,7 +6277,7 @@ pub fn populate_implementations_for_trait_if_necessary(
.insert(method_def_id, source);
}
}
TypeTraitItem(_) => {}
_ => {}
}
}

View File

@ -830,6 +830,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
impl<'tcx> Repr<'tcx> for ast::TraitItem {
fn repr(&self, _tcx: &ctxt) -> String {
let kind = match self.node {
ast::ConstTraitItem(..) => "ConstTraitItem",
ast::MethodTraitItem(..) => "MethodTraitItem",
ast::TypeTraitItem(..) => "TypeTraitItem",
};
@ -1054,9 +1055,39 @@ impl<'tcx> Repr<'tcx> for ty::Variance {
}
}
impl<'tcx> Repr<'tcx> for ty::ImplOrTraitItem<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
format!("ImplOrTraitItem({})",
match *self {
ty::ImplOrTraitItem::MethodTraitItem(ref i) => i.repr(tcx),
ty::ImplOrTraitItem::ConstTraitItem(ref i) => i.repr(tcx),
ty::ImplOrTraitItem::TypeTraitItem(ref i) => i.repr(tcx),
})
}
}
impl<'tcx> Repr<'tcx> for ty::AssociatedConst<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
format!("AssociatedConst(name: {}, ty: {}, vis: {}, def_id: {})",
self.name.repr(tcx),
self.ty.repr(tcx),
self.vis.repr(tcx),
self.def_id.repr(tcx))
}
}
impl<'tcx> Repr<'tcx> for ty::AssociatedType {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
format!("AssociatedType(name: {}, vis: {}, def_id: {})",
self.name.repr(tcx),
self.vis.repr(tcx),
self.def_id.repr(tcx))
}
}
impl<'tcx> Repr<'tcx> for ty::Method<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
format!("method(name: {}, generics: {}, predicates: {}, fty: {}, \
format!("Method(name: {}, generics: {}, predicates: {}, fty: {}, \
explicit_self: {}, vis: {}, def_id: {})",
self.name.repr(tcx),
self.generics.repr(tcx),

View File

@ -1584,8 +1584,9 @@ impl LintPass for MissingDoc {
if self.private_traits.contains(&trait_item.id) { return }
let desc = match trait_item.node {
ast::ConstTraitItem(..) => "an associated constant",
ast::MethodTraitItem(..) => "a trait method",
ast::TypeTraitItem(..) => "an associated type"
ast::TypeTraitItem(..) => "an associated type",
};
self.check_missing_docs_attrs(cx, Some(trait_item.id),
@ -1600,9 +1601,10 @@ impl LintPass for MissingDoc {
}
let desc = match impl_item.node {
ast::ConstImplItem(..) => "an associated constant",
ast::MethodImplItem(..) => "a method",
ast::TypeImplItem(_) => "an associated type",
ast::MacImplItem(_) => "an impl item macro"
ast::MacImplItem(_) => "an impl item macro",
};
self.check_missing_docs_attrs(cx, Some(impl_item.id),
&impl_item.attrs,

View File

@ -272,6 +272,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
if public_ty || public_trait {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(_, _) => {}
ast::MethodImplItem(ref sig, _) => {
let meth_public = match sig.explicit_self.node {
ast::SelfStatic => public_ty,
@ -399,6 +400,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
debug!("privacy - is {:?} a public method", did);
return match self.tcx.impl_or_trait_items.borrow().get(&did) {
Some(&ty::ConstTraitItem(_)) => ExternallyDenied,
Some(&ty::MethodTraitItem(ref meth)) => {
debug!("privacy - well at least it's a method: {:?}",
*meth);
@ -490,6 +492,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// where the method was defined?
Some(ast_map::NodeImplItem(ii)) => {
match ii.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
let imp = self.tcx.map
.get_parent_did(closest_private_id);
@ -693,7 +696,11 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
ty::MethodTraitItem(method_type) => {
method_type.provided_source.unwrap_or(method_id)
}
ty::TypeTraitItem(_) => method_id,
_ => {
self.tcx.sess
.span_bug(span,
"got non-method item in check_static_method")
}
};
let string = token::get_name(name);
@ -1128,8 +1135,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
ast::MethodImplItem(..) => {
check_inherited(tcx, impl_item.span, impl_item.vis);
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
_ => {}
}
}
}
@ -1307,6 +1313,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
impl_items.iter()
.any(|impl_item| {
match impl_item.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
self.exported_items.contains(&impl_item.id)
}
@ -1330,6 +1337,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// don't erroneously report errors for private
// types in private items.
match impl_item.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..)
if self.item_is_public(&impl_item.id, impl_item.vis) =>
{
@ -1360,12 +1368,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// Those in 3. are warned with this call.
for impl_item in impl_items {
match impl_item.node {
ast::TypeImplItem(ref ty) => {
self.visit_ty(ty);
}
ast::MethodImplItem(..) |
ast::MacImplItem(_) => {},
if let ast::TypeImplItem(ref ty) = impl_item.node {
self.visit_ty(ty);
}
}
}
@ -1376,15 +1380,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
let mut found_pub_static = false;
for impl_item in impl_items {
match impl_item.node {
ast::MethodImplItem(ref sig, _) => {
if sig.explicit_self.node == ast::SelfStatic &&
self.item_is_public(&impl_item.id, impl_item.vis) {
ast::ConstImplItem(..) => {
if self.item_is_public(&impl_item.id, impl_item.vis) {
found_pub_static = true;
visit::walk_impl_item(self, impl_item);
}
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
ast::MethodImplItem(ref sig, _) => {
if sig.explicit_self.node == ast::SelfStatic &&
self.item_is_public(&impl_item.id, impl_item.vis) {
found_pub_static = true;
visit::walk_impl_item(self, impl_item);
}
}
_ => {}
}
}
if found_pub_static {

View File

@ -530,6 +530,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
trait_item.span);
match trait_item.node {
ast::ConstTraitItem(..) => {
let def = DefAssociatedConst(local_def(trait_item.id),
FromTrait(local_def(item.id)));
// NB: not IMPORTABLE
name_bindings.define_value(def, trait_item.span, PUBLIC);
}
ast::MethodTraitItem(..) => {
let def = DefMethod(local_def(trait_item.id),
FromTrait(local_def(item.id)));
@ -703,7 +709,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
.map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
}
DefFn(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
DefFn(..) | DefStatic(..) | DefConst(..) | DefAssociatedConst(..) |
DefMethod(..) => {
debug!("(building reduced graph for external \
crate) building value (fn/static) {}", final_ident);
// impl methods have already been defined with the correct importability modifier

View File

@ -60,7 +60,8 @@ use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
use rustc::util::lev_distance::lev_distance;
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block};
use syntax::ast::{ConstImplItem, Crate, CrateNum};
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
@ -1831,6 +1832,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// FIXME #4951: Do we need a node ID here?
let type_parameters = match trait_item.node {
ast::ConstTraitItem(..) => NoTypeParameters,
ast::MethodTraitItem(ref sig, _) => {
HasTypeParameters(&sig.generics,
FnSpace,
@ -2094,6 +2096,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
this.with_current_self_type(self_type, |this| {
for impl_item in impl_items {
match impl_item.node {
ConstImplItem(_, _) => {}
MethodImplItem(ref sig, _) => {
// If this is a trait impl, ensure the method
// exists in trait
@ -2466,7 +2469,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// This must be an enum variant, struct or const.
if let Some(path_res) = self.resolve_path(pat_id, path, 0, ValueNS, false) {
match path_res.base_def {
DefVariant(..) | DefStruct(..) | DefConst(..) => {
DefVariant(..) | DefStruct(..) | DefConst(..) |
DefAssociatedConst(..) => {
self.record_def(pattern.id, path_res);
}
DefStatic(..) => {
@ -2542,7 +2546,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
def @ DefVariant(..) | def @ DefStruct(..) => {
return FoundStructOrEnumVariant(def, LastMod(AllPublic));
}
def @ DefConst(..) => {
def @ DefConst(..) | def @ DefAssociatedConst(..) => {
return FoundConst(def, LastMod(AllPublic));
}
DefStatic(..) => {

View File

@ -242,6 +242,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
def::DefTrait(_) => Some(recorder::TypeRef),
def::DefStatic(_, _) |
def::DefConst(_) |
def::DefAssociatedConst(..) |
def::DefLocal(_) |
def::DefVariant(_, _, _) |
def::DefUpvar(..) => Some(recorder::VarRef),
@ -359,14 +360,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
// record the decl for this def (if it has one)
let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
ast_util::local_def(id))
.and_then(|def_id| {
if match def_id {
ty::MethodTraitItemId(def_id) => {
def_id.node != 0 && def_id != ast_util::local_def(id)
}
ty::TypeTraitItemId(_) => false,
} {
Some(def_id.def_id())
.and_then(|new_id| {
let def_id = new_id.def_id();
if def_id.node != 0 && def_id != ast_util::local_def(id) {
Some(def_id)
} else {
None
}
@ -800,6 +797,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
def::DefLocal(..) |
def::DefStatic(..) |
def::DefConst(..) |
def::DefAssociatedConst(..) |
def::DefVariant(..) => self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef),
span,
sub_span,
@ -883,6 +881,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
def::DefLocal(_) |
def::DefStatic(_,_) |
def::DefConst(..) |
def::DefAssociatedConst(..) |
def::DefStruct(_) |
def::DefVariant(..) |
def::DefFn(..) => self.write_sub_paths_truncated(path, false),
@ -966,7 +965,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
ty::MethodTraitItem(method) => {
method.provided_source.unwrap_or(def_id)
}
ty::TypeTraitItem(_) => def_id,
_ => self.sess
.span_bug(ex.span,
"save::process_method_call: non-method \
DefId in MethodStatic or MethodStaticClosure"),
};
(Some(def_id), decl_id)
}
@ -1008,7 +1010,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
let def = self.analysis.ty_cx.def_map.borrow().get(&p.id).unwrap().full_def();
let struct_def = match def {
def::DefConst(..) => None,
def::DefConst(..) | def::DefAssociatedConst(..) => None,
def::DefVariant(_, variant_id, _) => Some(variant_id),
_ => {
match ty::ty_to_def_id(ty::node_id_to_type(&self.analysis.ty_cx, p.id)) {
@ -1236,6 +1238,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
match trait_item.node {
ast::ConstTraitItem(..) => {}
ast::MethodTraitItem(ref sig, ref body) => {
self.process_method(sig, body.as_ref().map(|x| &**x),
trait_item.id, trait_item.ident.name, trait_item.span);
@ -1246,6 +1249,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
match impl_item.node {
ast::ConstImplItem(..) => {}
ast::MethodImplItem(ref sig, ref body) => {
self.process_method(sig, Some(body), impl_item.id,
impl_item.ident.name, impl_item.span);
@ -1432,8 +1436,9 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
paths_to_process.push((id, p.clone(), Some(ref_kind)))
}
// FIXME(nrc) what are these doing here?
def::DefStatic(_, _) => {}
def::DefConst(..) => {}
def::DefStatic(_, _) |
def::DefConst(..) |
def::DefAssociatedConst(..) => {}
_ => error!("unexpected definition kind when processing collected paths: {:?}",
def)
}

View File

@ -1078,25 +1078,17 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
Some(ast_map::NodeTraitItem(trait_item)) => {
match trait_item.node {
ast::MethodTraitItem(_, Some(ref body)) => body,
ast::MethodTraitItem(_, None) => {
tcx.sess.bug("unexpected variant: required trait method \
in has_nested_returns")
}
ast::TypeTraitItem(..) => {
tcx.sess.bug("unexpected variant: associated type trait item in \
has_nested_returns")
_ => {
tcx.sess.bug("unexpected variant: trait item other than a \
provided method in has_nested_returns")
}
}
}
Some(ast_map::NodeImplItem(impl_item)) => {
match impl_item.node {
ast::MethodImplItem(_, ref body) => body,
ast::TypeImplItem(_) => {
tcx.sess.bug("unexpected variant: associated type impl item in \
has_nested_returns")
}
ast::MacImplItem(_) => {
tcx.sess.bug("unexpected variant: unexpanded macro impl item in \
_ => {
tcx.sess.bug("unexpected variant: non-method impl item in \
has_nested_returns")
}
}
@ -2363,13 +2355,14 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
ast_map::NodeTraitItem(trait_item) => {
debug!("get_item_val(): processing a NodeTraitItem");
match trait_item.node {
ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => {
ccx.sess().span_bug(trait_item.span,
"unexpected variant: required trait method in get_item_val()");
}
ast::MethodTraitItem(_, Some(_)) => {
register_method(ccx, id, &trait_item.attrs, trait_item.span)
}
_ => {
ccx.sess().span_bug(trait_item.span,
"unexpected variant: trait item other than a provided \
method in get_item_val()");
}
}
}
@ -2378,13 +2371,10 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
ast::MethodImplItem(..) => {
register_method(ccx, id, &impl_item.attrs, impl_item.span)
}
ast::TypeImplItem(_) => {
_ => {
ccx.sess().span_bug(impl_item.span,
"unexpected variant: associated type in get_item_val()")
}
ast::MacImplItem(_) => {
ccx.sess().span_bug(impl_item.span,
"unexpected variant: unexpanded macro in get_item_val()")
"unexpected variant: non-method impl item in \
get_item_val()");
}
}
}

View File

@ -202,6 +202,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
}
def::DefStatic(..) |
def::DefConst(..) |
def::DefAssociatedConst(..) |
def::DefLocal(..) |
def::DefUpvar(..) => {
datum_callee(bcx, ref_expr)
@ -465,9 +466,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
(true, source_id, new_substs)
}
ty::TypeTraitItem(_) => {
_ => {
tcx.sess.bug("trans_fn_ref_with_vtables() tried \
to translate an associated type?!")
to translate a non-method?!")
}
}
}

View File

@ -1314,15 +1314,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
impl_item.span,
true)
}
ast::TypeImplItem(_) => {
_ => {
cx.sess().span_bug(impl_item.span,
"create_function_debug_context() \
called on associated type?!")
}
ast::MacImplItem(_) => {
cx.sess().span_bug(impl_item.span,
"create_function_debug_context() \
called on unexpanded macro?!")
called on non-method impl item?!")
}
}
}

View File

@ -74,8 +74,7 @@ pub fn trans_impl(ccx: &CrateContext,
ast::MethodImplItem(..) => {
visit::walk_impl_item(&mut v, impl_item);
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
_ => {}
}
}
return;
@ -98,8 +97,7 @@ pub fn trans_impl(ccx: &CrateContext,
}
visit::walk_impl_item(&mut v, impl_item);
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
_ => {}
}
}
}
@ -336,9 +334,9 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let impl_did = vtable_impl.impl_def_id;
let mname = match ty::trait_item(ccx.tcx(), trait_id, n_method) {
ty::MethodTraitItem(method) => method.name,
ty::TypeTraitItem(_) => {
bcx.tcx().sess.bug("can't monomorphize an associated \
type")
_ => {
bcx.tcx().sess.bug("can't monomorphize a non-method trait \
item")
}
};
let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
@ -579,8 +577,8 @@ pub fn trans_object_shim<'a, 'tcx>(
// Lookup the type of this method as declared in the trait and apply substitutions.
let method_ty = match ty::trait_item(tcx, trait_id, method_offset_in_trait) {
ty::MethodTraitItem(method) => method,
ty::TypeTraitItem(_) => {
tcx.sess.bug("can't create a method shim for an associated type")
_ => {
tcx.sess.bug("can't create a method shim for a non-method item")
}
};
let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty);
@ -789,11 +787,11 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trait_item_def_ids
.iter()
// Filter out the associated types.
// Filter out non-method items.
.filter_map(|item_def_id| {
match *item_def_id {
ty::MethodTraitItemId(def_id) => Some(def_id),
ty::TypeTraitItemId(_) => None,
_ => None,
}
})
@ -806,7 +804,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) {
ty::MethodTraitItem(m) => m,
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
_ => ccx.sess().bug("should be a method, not other assoc item"),
};
let name = trait_method_type.name;
@ -824,7 +822,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let impl_method_def_id = method_with_name(ccx, impl_id, name);
let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) {
ty::MethodTraitItem(m) => m,
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
_ => ccx.sess().bug("should be a method, not other assoc item"),
};
debug!("emit_vtable_methods: impl_method_type={}",

View File

@ -236,11 +236,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
d
}
ast::TypeImplItem(_) => {
ccx.sess().bug("can't monomorphize an associated type")
}
ast::MacImplItem(_) => {
ccx.sess().bug("can't monomorphize an unexpanded macro")
_ => {
ccx.sess().bug(&format!("can't monomorphize a {:?}",
map_node))
}
}
}

View File

@ -808,6 +808,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(_, _) => {}
ast::MethodImplItem(ref sig, ref body) => {
check_method_body(ccx, &impl_pty.generics, sig, body,
impl_item.id, impl_item.span);
@ -823,6 +824,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
for trait_item in trait_items {
match trait_item.node {
ast::ConstTraitItem(_, _) => {}
ast::MethodTraitItem(_, None) => {
// Nothing to do, since required methods don't have
// bodies to check.
@ -920,6 +922,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// and compatible with trait signature
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(_, _) => {}
ast::MethodImplItem(_, ref body) => {
let impl_method_def_id = local_def(impl_item.id);
let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
@ -979,13 +982,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
match (associated_type, &typedef_ty) {
(&ty::TypeTraitItem(_), &ty::TypeTraitItem(_)) => {}
_ => {
// This is `span_bug` as it should have
// already been caught in resolve.
tcx.sess.span_bug(
impl_item.span,
&format!("item `{}` is of a different kind from its trait `{}`",
token::get_name(typedef_ty.name()),
impl_trait_ref.repr(tcx)));
// Formerly `span_bug`, but it turns out that
// this is not checked in resolve, so this is
// the first place where we'll notice the
// mismatch.
span_err!(tcx.sess, impl_item.span, E0323,
"item `{}` is an associated type, \
which doesn't match its trait `{}`",
token::get_name(typedef_ty.name()),
impl_trait_ref.repr(tcx))
}
}
}
@ -1012,6 +1017,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let mut missing_methods = Vec::new();
for trait_item in &*trait_items {
match *trait_item {
ty::ConstTraitItem(_) => {}
ty::MethodTraitItem(ref trait_method) => {
let is_implemented =
impl_items.iter().any(|ii| {
@ -1019,8 +1025,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ast::MethodImplItem(..) => {
ii.ident.name == trait_method.name
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => false,
_ => false,
}
});
let is_provided =
@ -1035,8 +1040,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ast::TypeImplItem(_) => {
ii.ident.name == associated_type.name
}
ast::MethodImplItem(..) |
ast::MacImplItem(_) => false,
_ => false,
}
});
if !is_implemented {
@ -4208,7 +4212,7 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
}
def::DefFn(id, _) | def::DefMethod(id, _) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) | def::DefConst(id) => {
def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
(ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id))
}
def::DefTrait(_) |
@ -4351,6 +4355,10 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
}
}
def::DefAssociatedConst(..) => {
segment_spaces = repeat(None).take(segments.len()).collect();
}
// Other cases. Various nonsense that really shouldn't show up
// here. If they do, an error will have been reported
// elsewhere. (I hope)

View File

@ -20,8 +20,9 @@ use metadata::csearch::{each_impl, get_impl_trait};
use metadata::csearch;
use middle::subst::{self, Subst};
use middle::ty::RegionEscape;
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
use middle::ty::{ImplContainer, ImplOrTraitItemId, ConstTraitItemId};
use middle::ty::{MethodTraitItemId, TypeTraitItemId};
use middle::ty::{ParameterEnvironment, lookup_item_type};
use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
use middle::ty::{ty_param, TypeScheme, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
@ -278,6 +279,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
let mut items: Vec<ImplOrTraitItemId> =
impl_items.iter().map(|impl_item| {
match impl_item.node {
ast::ConstImplItem(..) => {
ConstTraitItemId(local_def(impl_item.id))
}
ast::MethodImplItem(..) => {
MethodTraitItemId(local_def(impl_item.id))
}
@ -348,7 +352,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
.insert(item_def_id.def_id(), source);
}
}
ty::TypeTraitItem(_) => {}
_ => {}
}
}

View File

@ -196,7 +196,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
let def_id = local_def(method_id);
match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
ty::MethodTraitItem(ref mty) => mty.clone(),
ty::TypeTraitItem(..) => {
_ => {
self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
}
}
@ -830,43 +830,37 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
// Convert all the associated types.
for impl_item in impl_items {
match impl_item.node {
ast::TypeImplItem(ref ty) => {
if opt_trait_ref.is_none() {
span_err!(tcx.sess, impl_item.span, E0202,
"associated items are not allowed in inherent impls");
}
as_refsociated_type(ccx, ImplContainer(local_def(it.id)),
impl_item.ident, impl_item.id, impl_item.vis);
let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
TypeScheme {
generics: ty::Generics::empty(),
ty: typ,
});
tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
ty::GenericPredicates::empty());
write_ty_to_tcx(tcx, impl_item.id, typ);
if let ast::TypeImplItem(ref ty) = impl_item.node {
if opt_trait_ref.is_none() {
span_err!(tcx.sess, impl_item.span, E0202,
"associated items are not allowed in inherent impls");
}
ast::MethodImplItem(..) |
ast::MacImplItem(_) => {}
as_refsociated_type(ccx, ImplContainer(local_def(it.id)),
impl_item.ident, impl_item.id, impl_item.vis);
let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
TypeScheme {
generics: ty::Generics::empty(),
ty: typ,
});
tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
ty::GenericPredicates::empty());
write_ty_to_tcx(tcx, impl_item.id, typ);
}
}
let methods = impl_items.iter().filter_map(|ii| {
match ii.node {
ast::MethodImplItem(ref sig, _) => {
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
// { fn foo(); }` is public, but private in `priv impl { fn
// foo(); }`).
let method_vis = ii.vis.inherit_from(parent_visibility);
Some((sig, ii.id, ii.ident, method_vis, ii.span))
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => None
if let ast::MethodImplItem(ref sig, _) = ii.node {
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
// { fn foo(); }` is public, but private in `priv impl { fn
// foo(); }`).
let method_vis = ii.vis.inherit_from(parent_visibility);
Some((sig, ii.id, ii.ident, method_vis, ii.span))
} else {
None
}
});
convert_methods(ccx,
@ -877,18 +871,14 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
&ty_predicates);
for impl_item in impl_items {
match impl_item.node {
ast::MethodImplItem(ref sig, ref body) => {
let body_id = body.id;
check_method_self_type(ccx,
&BindingRscope::new(),
ccx.method_ty(impl_item.id),
selfty,
&sig.explicit_self,
body_id);
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
if let ast::MethodImplItem(ref sig, ref body) = impl_item.node {
let body_id = body.id;
check_method_self_type(ccx,
&BindingRscope::new(),
ccx.method_ty(impl_item.id),
selfty,
&sig.explicit_self,
body_id);
}
}
@ -919,18 +909,18 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
// Convert all the associated types.
for trait_item in trait_items {
match trait_item.node {
ast::MethodTraitItem(..) => {}
ast::TypeTraitItem(..) => {
as_refsociated_type(ccx, TraitContainer(local_def(it.id)),
trait_item.ident, trait_item.id, ast::Public);
}
_ => {}
}
};
let methods = trait_items.iter().filter_map(|ti| {
let sig = match ti.node {
ast::MethodTraitItem(ref sig, _) => sig,
ast::TypeTraitItem(..) => return None,
_ => return None,
};
Some((sig, ti.id, ti.ident, ast::Inherited, ti.span))
});
@ -947,6 +937,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
let def_id = local_def(trait_item.id);
match trait_item.node {
ast::ConstTraitItem(..) => {
ty::ConstTraitItemId(def_id)
}
ast::MethodTraitItem(..) => {
ty::MethodTraitItemId(def_id)
}
@ -962,7 +955,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
for trait_item in trait_items {
let sig = match trait_item.node {
ast::MethodTraitItem(ref sig, _) => sig,
ast::TypeTraitItem(..) => continue
_ => continue
};
check_method_self_type(ccx,
&BindingRscope::new(),
@ -1185,8 +1178,8 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
match trait_item.node {
ast::MethodTraitItem(..) => None,
ast::TypeTraitItem(..) => Some(trait_item.ident.name),
_ => None,
}
}).collect();
@ -1260,7 +1253,7 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt,
trait_items.iter().any(|trait_item| {
match trait_item.node {
ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name,
ast::MethodTraitItem(..) => false,
_ => false,
}
})
}
@ -1320,7 +1313,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
trait_items.iter().flat_map(|trait_item| {
let bounds = match trait_item.node {
ast::TypeTraitItem(ref bounds, _) => bounds,
ast::MethodTraitItem(..) => {
_ => {
return vec!().into_iter();
}
};
@ -2227,7 +2220,8 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_items.iter()
.filter_map(|item| match item.node {
ast::TypeImplItem(..) => Some(ty::node_id_to_type(tcx, item.id)),
ast::MethodImplItem(..) | ast::MacImplItem(..) => None,
ast::ConstImplItem(..) | ast::MethodImplItem(..) |
ast::MacImplItem(..) => None,
})
.flat_map(|ty| ctp::parameters_for_type(ty).into_iter())
.filter_map(|p| match p {

View File

@ -176,6 +176,7 @@ register_diagnostics! {
E0320, // recursive overflow during dropck
E0321, // extended coherence rules for defaulted traits violated
E0322, // cannot implement Sized explicitly
E0323, // implemented trait where method should have been provided
E0366, // dropck forbid specialization to concrete type or region
E0367, // dropck forbid specialization to predicate not in struct/enum
E0368, // binary operation `<op>=` cannot be applied to types

View File

@ -312,6 +312,7 @@ pub fn build_impl(cx: &DocContext,
let did = did.def_id();
let impl_item = ty::impl_or_trait_item(tcx, did);
match impl_item {
ty::ConstTraitItem(_) => { return None }
ty::MethodTraitItem(method) => {
if method.vis != ast::Public && associated_trait.is_none() {
return None

View File

@ -361,6 +361,7 @@ pub enum ItemEnum {
ForeignStaticItem(Static),
MacroItem(Macro),
PrimitiveItem(PrimitiveType),
AssociatedConstItem(Type, Option<String>),
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
DefaultImplItem(DefaultImpl),
}
@ -1235,6 +1236,11 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
impl Clean<Item> for ast::TraitItem {
fn clean(&self, cx: &DocContext) -> Item {
let inner = match self.node {
ast::ConstTraitItem(ref ty, ref default) => {
AssociatedConstItem(ty.clean(cx),
default.as_ref().map(|expr|
expr.span.to_src(cx)))
}
ast::MethodTraitItem(ref sig, Some(_)) => {
MethodItem(sig.clean(cx))
}
@ -1260,6 +1266,12 @@ impl Clean<Item> for ast::TraitItem {
impl Clean<Item> for ast::ImplItem {
fn clean(&self, cx: &DocContext) -> Item {
let inner = match self.node {
ast::ConstImplItem(ref ty, ref expr) => {
ConstantItem(Constant{
type_: ty.clean(cx),
expr: expr.span.to_src(cx),
})
}
ast::MethodImplItem(ref sig, _) => {
MethodItem(sig.clean(cx))
}
@ -1363,6 +1375,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
impl<'tcx> Clean<Item> for ty::ImplOrTraitItem<'tcx> {
fn clean(&self, cx: &DocContext) -> Item {
match *self {
ty::ConstTraitItem(ref cti) => cti.clean(cx),
ty::MethodTraitItem(ref mti) => mti.clean(cx),
ty::TypeTraitItem(ref tti) => tti.clean(cx),
}
@ -2672,6 +2685,20 @@ impl Clean<Stability> for attr::Stability {
}
}
impl<'tcx> Clean<Item> for ty::AssociatedConst<'tcx> {
fn clean(&self, cx: &DocContext) -> Item {
Item {
source: DUMMY_SP.clean(cx),
name: Some(self.name.clean(cx)),
attrs: Vec::new(),
inner: AssociatedConstItem(self.ty.clean(cx), None),
visibility: None,
def_id: self.def_id,
stability: None,
}
}
}
impl Clean<Item> for ty::AssociatedType {
fn clean(&self, cx: &DocContext) -> Item {
// When loading a cross-crate associated type, the bounds for this type

View File

@ -39,6 +39,7 @@ pub enum ItemType {
Primitive = 15,
AssociatedType = 16,
Constant = 17,
AssociatedConst = 18,
}
impl ItemType {
@ -63,6 +64,7 @@ impl ItemType {
clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic
clean::MacroItem(..) => ItemType::Macro,
clean::PrimitiveItem(..) => ItemType::Primitive,
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
clean::DefaultImplItem(..) => ItemType::Impl,
}
@ -102,6 +104,7 @@ impl ItemType {
ItemType::Primitive => "primitive",
ItemType::AssociatedType => "associatedtype",
ItemType::Constant => "constant",
ItemType::AssociatedConst => "associatedconstant",
}
}
}

View File

@ -1629,6 +1629,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
ItemType::Macro => ("macros", "Macros"),
ItemType::Primitive => ("primitives", "Primitive Types"),
ItemType::AssociatedType => ("associated-types", "Associated Types"),
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
};
try!(write!(w,
"<h2 id='{id}' class='section-header'>\
@ -1799,7 +1800,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
try!(write!(w, "{{\n"));
for t in &types {
try!(write!(w, " "));
try!(render_method(w, t, MethodLink::Anchor));
try!(render_assoc_item(w, t, AssocItemLink::Anchor));
try!(write!(w, ";\n"));
}
if !types.is_empty() && !required.is_empty() {
@ -1807,7 +1808,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
}
for m in &required {
try!(write!(w, " "));
try!(render_method(w, m, MethodLink::Anchor));
try!(render_assoc_item(w, m, AssocItemLink::Anchor));
try!(write!(w, ";\n"));
}
if !required.is_empty() && !provided.is_empty() {
@ -1815,7 +1816,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
}
for m in &provided {
try!(write!(w, " "));
try!(render_method(w, m, MethodLink::Anchor));
try!(render_assoc_item(w, m, AssocItemLink::Anchor));
try!(write!(w, " {{ ... }}\n"));
}
try!(write!(w, "}}"));
@ -1831,7 +1832,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
ty = shortty(m),
name = *m.name.as_ref().unwrap(),
stab = m.stability_class()));
try!(render_method(w, m, MethodLink::Anchor));
try!(render_assoc_item(w, m, AssocItemLink::Anchor));
try!(write!(w, "</code></h3>"));
try!(document(w, m));
Ok(())
@ -1871,7 +1872,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
}
// If there are methods directly on this trait object, render them here.
try!(render_methods(w, it.def_id, MethodRender::All));
try!(render_assoc_items(w, it.def_id, AssocItemRender::All));
let cache = cache();
try!(write!(w, "
@ -1917,19 +1918,19 @@ fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
Ok(())
}
fn render_method(w: &mut fmt::Formatter, meth: &clean::Item,
link: MethodLink) -> fmt::Result {
fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
link: AssocItemLink) -> fmt::Result {
fn method(w: &mut fmt::Formatter, it: &clean::Item,
unsafety: ast::Unsafety, abi: abi::Abi,
g: &clean::Generics, selfty: &clean::SelfTy,
d: &clean::FnDecl, link: MethodLink) -> fmt::Result {
d: &clean::FnDecl, link: AssocItemLink) -> fmt::Result {
use syntax::abi::Abi;
let name = it.name.as_ref().unwrap();
let anchor = format!("#{}.{}", shortty(it), name);
let href = match link {
MethodLink::Anchor => anchor,
MethodLink::GotoSource(did) => {
AssocItemLink::Anchor => anchor,
AssocItemLink::GotoSource(did) => {
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
}
};
@ -1958,10 +1959,11 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item,
method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl,
link)
}
clean::AssociatedConstItem(_, _) => Ok(()),
clean::AssociatedTypeItem(ref bounds, ref default) => {
assoc_type(w, meth, bounds, default)
}
_ => panic!("render_method called on non-method")
_ => panic!("render_assoc_item called on non-associated-item")
}
}
@ -2001,7 +2003,7 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item,
try!(write!(w, "</table>"));
}
}
render_methods(w, it.def_id, MethodRender::All)
render_assoc_items(w, it.def_id, AssocItemRender::All)
}
fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
@ -2100,7 +2102,7 @@ fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
try!(write!(w, "</table>"));
}
try!(render_methods(w, it.def_id, MethodRender::All));
try!(render_assoc_items(w, it.def_id, AssocItemRender::All));
Ok(())
}
@ -2184,19 +2186,19 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
}
#[derive(Copy, Clone)]
enum MethodLink {
enum AssocItemLink {
Anchor,
GotoSource(ast::DefId),
}
enum MethodRender<'a> {
enum AssocItemRender<'a> {
All,
DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type },
}
fn render_methods(w: &mut fmt::Formatter,
it: ast::DefId,
what: MethodRender) -> fmt::Result {
fn render_assoc_items(w: &mut fmt::Formatter,
it: ast::DefId,
what: AssocItemRender) -> fmt::Result {
let c = cache();
let v = match c.impls.get(&it) {
Some(v) => v,
@ -2207,21 +2209,21 @@ fn render_methods(w: &mut fmt::Formatter,
});
if !non_trait.is_empty() {
let render_header = match what {
MethodRender::All => {
AssocItemRender::All => {
try!(write!(w, "<h2 id='methods'>Methods</h2>"));
true
}
MethodRender::DerefFor { trait_, type_ } => {
AssocItemRender::DerefFor { trait_, type_ } => {
try!(write!(w, "<h2 id='deref-methods'>Methods from \
{}&lt;Target={}&gt;</h2>", trait_, type_));
false
}
};
for i in &non_trait {
try!(render_impl(w, i, MethodLink::Anchor, render_header));
try!(render_impl(w, i, AssocItemLink::Anchor, render_header));
}
}
if let MethodRender::DerefFor { .. } = what {
if let AssocItemRender::DerefFor { .. } = what {
return Ok(())
}
if !traits.is_empty() {
@ -2243,7 +2245,7 @@ fn render_methods(w: &mut fmt::Formatter,
});
for i in &manual {
let did = i.trait_did().unwrap();
try!(render_impl(w, i, MethodLink::GotoSource(did), true));
try!(render_impl(w, i, AssocItemLink::GotoSource(did), true));
}
if !derived.is_empty() {
try!(write!(w, "<h3 id='derived_implementations'>\
@ -2251,7 +2253,7 @@ fn render_methods(w: &mut fmt::Formatter,
</h3>"));
for i in &derived {
let did = i.trait_did().unwrap();
try!(render_impl(w, i, MethodLink::GotoSource(did), true));
try!(render_impl(w, i, AssocItemLink::GotoSource(did), true));
}
}
}
@ -2266,14 +2268,14 @@ fn render_deref_methods(w: &mut fmt::Formatter, impl_: &Impl) -> fmt::Result {
_ => None,
}
}).next().unwrap();
let what = MethodRender::DerefFor { trait_: deref_type, type_: target };
let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target };
match *target {
clean::ResolvedPath { did, .. } => render_methods(w, did, what),
clean::ResolvedPath { did, .. } => render_assoc_items(w, did, what),
_ => {
if let Some(prim) = target.primitive_type() {
if let Some(c) = cache().primitive_locations.get(&prim) {
let did = ast::DefId { krate: *c, node: prim.to_node_id() };
try!(render_methods(w, did, what));
try!(render_assoc_items(w, did, what));
}
}
Ok(())
@ -2281,7 +2283,7 @@ fn render_deref_methods(w: &mut fmt::Formatter, impl_: &Impl) -> fmt::Result {
}
}
fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: AssocItemLink,
render_header: bool) -> fmt::Result {
if render_header {
try!(write!(w, "<h3 class='impl'><code>impl{} ",
@ -2300,13 +2302,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
}
fn doctraititem(w: &mut fmt::Formatter, item: &clean::Item,
link: MethodLink) -> fmt::Result {
link: AssocItemLink) -> fmt::Result {
match item.inner {
clean::MethodItem(..) | clean::TyMethodItem(..) => {
try!(write!(w, "<h4 id='method.{}' class='{}'><code>",
*item.name.as_ref().unwrap(),
shortty(item)));
try!(render_method(w, item, link));
try!(render_assoc_item(w, item, link));
try!(write!(w, "</code></h4>\n"));
}
clean::TypedefItem(ref tydef) => {
@ -2317,6 +2319,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
try!(write!(w, "type {} = {}", name, tydef.type_));
try!(write!(w, "</code></h4>\n"));
}
clean::AssociatedConstItem(_, _) => {}
clean::AssociatedTypeItem(ref bounds, ref default) => {
let name = item.name.as_ref().unwrap();
try!(write!(w, "<h4 id='assoc_type.{}' class='{}'><code>",
@ -2327,7 +2330,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
}
_ => panic!("can't make docs for trait item with name {:?}", item.name)
}
if let MethodLink::Anchor = link {
if let AssocItemLink::Anchor = link {
document(w, item)
} else {
Ok(())
@ -2339,10 +2342,10 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
try!(doctraititem(w, trait_item, link));
}
fn render_default_methods(w: &mut fmt::Formatter,
did: ast::DefId,
t: &clean::Trait,
i: &clean::Impl) -> fmt::Result {
fn render_default_items(w: &mut fmt::Formatter,
did: ast::DefId,
t: &clean::Trait,
i: &clean::Impl) -> fmt::Result {
for trait_item in &t.items {
let n = trait_item.name.clone();
match i.items.iter().find(|m| { m.name == n }) {
@ -2350,7 +2353,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
None => {}
}
try!(doctraititem(w, trait_item, MethodLink::GotoSource(did)));
try!(doctraititem(w, trait_item, AssocItemLink::GotoSource(did)));
}
Ok(())
}
@ -2361,7 +2364,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink,
// for them work.
if let Some(clean::ResolvedPath { did, .. }) = i.impl_.trait_ {
if let Some(t) = cache().traits.get(&did) {
try!(render_default_methods(w, did, t, &i.impl_));
try!(render_default_items(w, did, t, &i.impl_));
}
}
try!(write!(w, "</div>"));
@ -2458,7 +2461,7 @@ fn item_primitive(w: &mut fmt::Formatter,
it: &clean::Item,
_p: &clean::PrimitiveType) -> fmt::Result {
try!(document(w, it));
render_methods(w, it.def_id, MethodRender::All)
render_assoc_items(w, it.def_id, AssocItemRender::All)
}
fn get_basic_keywords() -> &'static str {

View File

@ -184,7 +184,8 @@ impl<'a> fold::DocFolder for Stripper<'a> {
// Primitives are never stripped
clean::PrimitiveItem(..) => {}
// Associated types are never stripped
// Associated consts and types are never stripped
clean::AssociatedConstItem(..) |
clean::AssociatedTypeItem(..) => {}
}

View File

@ -1236,6 +1236,7 @@ pub struct TraitItem {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TraitItem_ {
ConstTraitItem(P<Ty>, Option<P<Expr>>),
MethodTraitItem(MethodSig, Option<P<Block>>),
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
}
@ -1252,6 +1253,7 @@ pub struct ImplItem {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum ImplItem_ {
ConstImplItem(P<Ty>, P<Expr>),
MethodImplItem(MethodSig, P<Block>),
TypeImplItem(P<Ty>),
MacImplItem(Mac),

View File

@ -222,8 +222,7 @@ impl<'a> FnLikeNode<'a> {
ast::MethodImplItem(ref sig, ref body) => {
method(ii.id, ii.ident, sig, Some(ii.vis), body, ii.span)
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {
_ => {
panic!("impl method FnLikeNode that is not fn-like")
}
}

View File

@ -940,6 +940,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
}
Some(NodeImplItem(ii)) => {
match ii.node {
ConstImplItem(..) => {
format!("assoc const {} in {}{}",
token::get_ident(ii.ident),
map.path_to_string(id),
id_str)
}
MethodImplItem(..) => {
format!("method {} in {}{}",
token::get_ident(ii.ident),
@ -959,9 +965,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
}
Some(NodeTraitItem(ti)) => {
let kind = match ti.node {
ConstTraitItem(..) => "assoc constant",
MethodTraitItem(..) => "trait method",
TypeTraitItem(..) => "assoc type",
// ConstTraitItem(..) => "assoc constant"
};
format!("{} {} in {}{}",

View File

@ -973,6 +973,10 @@ pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
ident: folder.fold_ident(ident),
attrs: fold_attrs(attrs, folder),
node: match node {
ConstTraitItem(ty, default) => {
ConstTraitItem(folder.fold_ty(ty),
default.map(|x| folder.fold_expr(x)))
}
MethodTraitItem(sig, body) => {
MethodTraitItem(noop_fold_method_sig(sig, folder),
body.map(|x| folder.fold_block(x)))
@ -994,6 +998,9 @@ pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
attrs: fold_attrs(attrs, folder),
vis: vis,
node: match node {
ConstImplItem(ty, expr) => {
ConstImplItem(folder.fold_ty(ty), folder.fold_expr(expr))
}
MethodImplItem(sig, body) => {
MethodImplItem(noop_fold_method_sig(sig, folder),
folder.fold_block(body))

View File

@ -1269,6 +1269,7 @@ impl<'a> State<'a> {
try!(self.maybe_print_comment(ti.span.lo));
try!(self.print_outer_attributes(&ti.attrs));
match ti.node {
ast::ConstTraitItem(_, _) => Ok(()),
ast::MethodTraitItem(ref sig, ref body) => {
if body.is_some() {
try!(self.head(""));
@ -1295,6 +1296,7 @@ impl<'a> State<'a> {
try!(self.maybe_print_comment(ii.span.lo));
try!(self.print_outer_attributes(&ii.attrs));
match ii.node {
ast::ConstImplItem(_, _) => Ok(()),
ast::MethodImplItem(ref sig, ref body) => {
try!(self.head(""));
try!(self.print_method_sig(ii.ident, sig, ii.vis));

View File

@ -619,6 +619,12 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
visitor.visit_attribute(attr);
}
match trait_item.node {
ConstTraitItem(ref ty, ref default) => {
visitor.visit_ty(ty);
if let Some(ref expr) = *default {
visitor.visit_expr(expr);
}
}
MethodTraitItem(ref sig, None) => {
visitor.visit_explicit_self(&sig.explicit_self);
visitor.visit_generics(&sig.generics);
@ -641,6 +647,10 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
visitor.visit_attribute(attr);
}
match impl_item.node {
ConstImplItem(ref ty, ref expr) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
MethodImplItem(ref sig, ref body) => {
visitor.visit_fn(FkMethod(impl_item.ident, sig, Some(impl_item.vis)), &sig.decl,
body, impl_item.span, impl_item.id);