use hir::def::Def;
use hir::def_id::DefId;
use middle::resolve_lifetime as rl;
+use namespace::Namespace;
use rustc::ty::subst::{Kind, Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
let trait_did = bound.0.def_id;
let (assoc_ident, def_scope) = tcx.adjust(assoc_name, trait_did, ref_id);
- let item = tcx.associated_items(trait_did).find(|i| i.name.to_ident() == assoc_ident)
- .expect("missing associated type");
+ let item = tcx.associated_items(trait_did).find(|i| {
+ Namespace::from(i.kind) == Namespace::Type &&
+ i.name.to_ident() == assoc_ident
+ })
+ .expect("missing associated type");
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
let ty = self.normalize_ty(span, ty);
use check::FnCtxt;
use hir::def::Def;
use hir::def_id::DefId;
+use namespace::Namespace;
use rustc::ty::subst::Substs;
use rustc::traits;
use rustc::ty::{self, Ty, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let tcx = self.tcx;
- let method_item = self.associated_item(trait_def_id, m_name).unwrap();
+ let method_item = self.associated_item(trait_def_id, m_name, Namespace::Value).unwrap();
let def_id = method_item.def_id;
let generics = tcx.generics_of(def_id);
assert_eq!(generics.types.len(), 0);
/// Find item with name `item_name` defined in impl/trait `def_id`
/// and return it, or `None`, if no such item was defined there.
- pub fn associated_item(&self, def_id: DefId, item_name: ast::Name)
+ pub fn associated_item(&self, def_id: DefId, item_name: ast::Name, ns: Namespace)
-> Option<ty::AssociatedItem> {
self.tcx.associated_items(def_id)
- .find(|item| self.tcx.hygienic_eq(item_name, item.name, def_id))
-
+ .find(|item| Namespace::from(item.kind) == ns &&
+ self.tcx.hygienic_eq(item_name, item.name, def_id))
}
}
use check::FnCtxt;
use hir::def_id::DefId;
use hir::def::Def;
+use namespace::Namespace;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, ObligationCause};
use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable};
self.tcx.associated_items(def_id)
.filter(|x| {
let dist = lev_distance(&*name.as_str(), &x.name.as_str());
- dist > 0 && dist <= max_dist
+ Namespace::from(x.kind) == Namespace::Value && dist > 0
+ && dist <= max_dist
})
.collect()
} else {
- self.fcx.associated_item(def_id, name).map_or(Vec::new(), |x| vec![x])
+ self.fcx
+ .associated_item(def_id, name, Namespace::Value)
+ .map_or(Vec::new(), |x| vec![x])
}
} else {
self.tcx.associated_items(def_id).collect()
use hir::def::Def;
use hir::def_id::{CRATE_DEF_INDEX, DefId};
use middle::lang_items::FnOnceTraitLangItem;
+use namespace::Namespace;
use rustc::traits::{Obligation, SelectionContext};
use util::nodemap::FxHashSet;
CandidateSource::ImplSource(impl_did) => {
// Provide the best span we can. Use the item, if local to crate, else
// the impl, if local to crate (item may be defaulted), else nothing.
- let item = self.associated_item(impl_did, item_name)
+ let item = self.associated_item(impl_did, item_name, Namespace::Value)
.or_else(|| {
self.associated_item(
self.tcx.impl_trait_ref(impl_did).unwrap().def_id,
-
- item_name
+ item_name,
+ Namespace::Value,
)
}).unwrap();
let note_span = self.tcx.hir.span_if_local(item.def_id).or_else(|| {
}
}
CandidateSource::TraitSource(trait_did) => {
- let item = self.associated_item(trait_did, item_name).unwrap();
+ let item = self
+ .associated_item(trait_did, item_name, Namespace::Value)
+ .unwrap();
let item_span = self.tcx.def_span(item.def_id);
span_note!(err,
item_span,
// implementing a trait would be legal but is rejected
// here).
(type_is_local || info.def_id.is_local())
- && self.associated_item(info.def_id, item_name).is_some()
+ && self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
})
.collect::<Vec<_>>();
use hir::def::{Def, CtorKind};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_back::slice::ref_slice;
+use namespace::Namespace;
use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
use rustc::infer::type_variable::{TypeVariableOrigin};
use rustc::middle::region;
for impl_item in impl_items() {
let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
- .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id));
+ .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
+ tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
+ .or_else(|| {
+ // Not compatible, but needed for the error message
+ tcx.associated_items(impl_trait_ref.def_id)
+ .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
+ });
// Check that impl definition matches trait definition
if let Some(ty_trait_item) = ty_trait_item {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use namespace::Namespace;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::traits;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::TyCtxt;
pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum) {
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
overlap: traits::OverlapResult) {
- #[derive(Copy, Clone, PartialEq)]
- enum Namespace {
- Type,
- Value,
- }
let name_and_namespace = |def_id| {
let item = self.tcx.associated_item(def_id);
- (item.name, match item.kind {
- ty::AssociatedKind::Type => Namespace::Type,
- ty::AssociatedKind::Const |
- ty::AssociatedKind::Method => Namespace::Value,
- })
+ (item.name, Namespace::from(item.kind))
};
let impl_items1 = self.tcx.associated_item_def_ids(impl1);
mod impl_wf_check;
mod coherence;
mod variance;
+mod namespace;
pub struct TypeAndSubsts<'tcx> {
substs: &'tcx Substs<'tcx>,
--- /dev/null
+// Copyright 2017 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.
+
+use rustc::hir;
+use rustc::ty;
+
+// Whether an item exists in the type or value namespace.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Namespace {
+ Type,
+ Value,
+}
+
+impl From<ty::AssociatedKind> for Namespace {
+ fn from(a_kind: ty::AssociatedKind) -> Self {
+ match a_kind {
+ ty::AssociatedKind::Type => Namespace::Type,
+ ty::AssociatedKind::Const |
+ ty::AssociatedKind::Method => Namespace::Value,
+ }
+ }
+}
+
+impl<'a> From <&'a hir::ImplItemKind> for Namespace {
+ fn from(impl_kind: &'a hir::ImplItemKind) -> Self {
+ match *impl_kind {
+ hir::ImplItemKind::Type(..) => Namespace::Type,
+ hir::ImplItemKind::Const(..) |
+ hir::ImplItemKind::Method(..) => Namespace::Value,
+ }
+ }
+}
--- /dev/null
+// Copyright 2017 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.
+
+trait Foo {
+ type bar;
+ fn bar();
+}
+
+impl Foo for () {
+ type bar = ();
+ fn bar() {}
+}
+
+fn main() {
+ let x: <() as Foo>::bar = ();
+ <()>::bar();
+}
--- /dev/null
+// Copyright 2017 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.
+
+trait T {
+ type X;
+ const X: Self::X;
+}
+fn foo<X: T>() {
+ let _: X::X = X::X;
+}
+
+trait S {
+ const X: Self::X;
+ type X;
+}
+fn bar<X: S>() {
+ let _: X::X = X::X;
+}
+
+fn main() {}