use errors::{Applicability, DiagnosticId};
use crate::hir::{self, GenericArg, GenericArgs, ExprKind};
-use crate::hir::def::{CtorOf, Def};
+use crate::hir::def::{CtorOf, Def, DefKind};
use crate::hir::def_id::DefId;
use crate::hir::HirVec;
use crate::lint;
let r = match tcx.named_region(lifetime.hir_id) {
Some(rl::Region::Static) => {
- tcx.types.re_static
+ tcx.lifetimes.re_static
}
Some(rl::Region::LateBound(debruijn, id, _)) => {
// Supply some dummy value. We don't have an
// `re_error`, annoyingly, so use `'static`.
- tcx.types.re_static
+ tcx.lifetimes.re_static
})
}
};
// Provide substitutions for parameters for which arguments are inferred.
|substs, param, infer_types| {
match param.kind {
- GenericParamDefKind::Lifetime => tcx.types.re_static.into(),
+ GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
GenericParamDefKind::Type { has_default, .. } => {
if !infer_types && has_default {
// No type parameter provided, but a default exists.
span_err!(tcx.sess, span, E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound");
- tcx.types.re_static
+ tcx.lifetimes.re_static
})
}
})
qself_def: Def,
assoc_segment: &hir::PathSegment,
permit_variants: bool,
- ) -> (Ty<'tcx>, Def) {
+ ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorReported> {
let tcx = self.tcx();
let assoc_ident = assoc_segment.ident;
tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did)
});
if let Some(variant_def) = variant_def {
- let def = Def::Variant(variant_def.def_id);
if permit_variants {
check_type_alias_enum_variants_enabled(tcx, span);
tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span);
- return (qself_ty, def);
+ return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
} else {
- variant_resolution = Some(def);
+ variant_resolution = Some(variant_def.def_id);
}
}
}
Some(trait_ref) => trait_ref,
None => {
// A cycle error occurred, most likely.
- return (tcx.types.err, Def::Err);
+ return Err(ErrorReported);
}
};
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident));
- match self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span) {
- Ok(bound) => bound,
- Err(ErrorReported) => return (tcx.types.err, Def::Err),
- }
+ self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
}
(&ty::Param(_), Def::SelfTy(Some(param_did), None)) |
- (&ty::Param(_), Def::TyParam(param_did)) => {
- match self.find_bound_for_assoc_item(param_did, assoc_ident, span) {
- Ok(bound) => bound,
- Err(ErrorReported) => return (tcx.types.err, Def::Err),
- }
+ (&ty::Param(_), Def::Def(DefKind::TyParam, param_did)) => {
+ self.find_bound_for_assoc_item(param_did, assoc_ident, span)?
}
_ => {
if variant_resolution.is_some() {
&assoc_ident.as_str(),
);
}
- return (tcx.types.err, Def::Err);
+ return Err(ErrorReported);
}
};
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
let ty = self.normalize_ty(span, ty);
- let def = Def::AssociatedTy(item.def_id);
+ let kind = DefKind::AssociatedTy;
if !item.vis.is_accessible_from(def_scope, tcx) {
- let msg = format!("{} `{}` is private", def.kind_name(), assoc_ident);
+ let msg = format!("{} `{}` is private", kind.descr(), assoc_ident);
tcx.sess.span_err(span, &msg);
}
tcx.check_stability(item.def_id, Some(hir_ref_id), span);
- if let Some(variant_def) = variant_resolution {
+ if let Some(variant_def_id) = variant_resolution {
let mut err = tcx.struct_span_lint_hir(
AMBIGUOUS_ASSOCIATED_ITEMS,
hir_ref_id,
"ambiguous associated item",
);
- let mut could_refer_to = |def: Def, also| {
+ let mut could_refer_to = |kind: DefKind, def_id, also| {
let note_msg = format!("`{}` could{} refer to {} defined here",
- assoc_ident, also, def.kind_name());
- err.span_note(tcx.def_span(def.def_id()), ¬e_msg);
+ assoc_ident, also, kind.descr());
+ err.span_note(tcx.def_span(def_id), ¬e_msg);
};
- could_refer_to(variant_def, "");
- could_refer_to(def, " also");
+ could_refer_to(DefKind::Variant, variant_def_id, "");
+ could_refer_to(kind, item.def_id, " also");
err.span_suggestion(
span,
).emit();
}
- (ty, def)
+ Ok((ty, kind, item.def_id))
}
fn qpath_to_ty(&self,
err.span_label(span, "associated type not allowed here").emit();
}
- pub fn def_ids_for_path_segments(&self,
- segments: &[hir::PathSegment],
- self_ty: Option<Ty<'tcx>>,
- def: Def)
- -> Vec<PathSeg> {
+ // FIXME(eddyb, varkor) handle type paths here too, not just value ones.
+ pub fn def_ids_for_value_path_segments(
+ &self,
+ segments: &[hir::PathSegment],
+ self_ty: Option<Ty<'tcx>>,
+ kind: DefKind,
+ def_id: DefId,
+ ) -> Vec<PathSeg> {
// We need to extract the type parameters supplied by the user in
// the path `path`. Due to the current setup, this is a bit of a
// tricky-process; the problem is that resolve only tells us the
// `SomeStruct::<A>`, contains parameters in TypeSpace, and the
// final segment, `foo::<B>` contains parameters in fn space.
//
- // 5. Reference to a local variable
- //
- // Local variables can't have any type parameters.
- //
// The first step then is to categorize the segments appropriately.
let tcx = self.tcx();
let mut path_segs = vec![];
- match def {
+ match kind {
// Case 1. Reference to a struct constructor.
- Def::Ctor(def_id, CtorOf::Struct, ..) |
- Def::SelfCtor(.., def_id) => {
+ DefKind::Ctor(CtorOf::Struct, ..) => {
// Everything but the final segment should have no
// parameters at all.
let generics = tcx.generics_of(def_id);
}
// Case 2. Reference to a variant constructor.
- Def::Ctor(def_id, CtorOf::Variant, ..) | Def::Variant(def_id, ..) => {
+ DefKind::Ctor(CtorOf::Variant, ..)
+ | DefKind::Variant => {
let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
let (generics_def_id, index) = if let Some(adt_def) = adt_def {
debug_assert!(adt_def.is_enum());
// parameters at all.
let mut def_id = def_id;
- // `Def::Ctor` -> `Def::Variant`
- if let Def::Ctor(..) = def {
+ // `DefKind::Ctor` -> `DefKind::Variant`
+ if let DefKind::Ctor(..) = kind {
def_id = tcx.parent(def_id).unwrap()
}
- // `Def::Variant` -> `Def::Item` (enum)
+ // `DefKind::Variant` -> `DefKind::Enum`
let enum_def_id = tcx.parent(def_id).unwrap();
(enum_def_id, last - 1)
} else {
}
// Case 3. Reference to a top-level value.
- Def::Fn(def_id) |
- Def::Const(def_id) |
- Def::ConstParam(def_id) |
- Def::Static(def_id, _) => {
+ DefKind::Fn
+ | DefKind::Const
+ | DefKind::ConstParam
+ | DefKind::Static => {
path_segs.push(PathSeg(def_id, last));
}
// Case 4. Reference to a method or associated const.
- Def::Method(def_id) |
- Def::AssociatedConst(def_id) => {
+ DefKind::Method
+ | DefKind::AssociatedConst => {
if segments.len() >= 2 {
let generics = tcx.generics_of(def_id);
path_segs.push(PathSeg(generics.parent.unwrap(), last - 1));
path_segs.push(PathSeg(def_id, last));
}
- // Case 5. Local variable, no generics.
- Def::Local(..) | Def::Upvar(..) => {}
-
- _ => bug!("unexpected definition: {:?}", def),
+ kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
}
debug!("path_segs = {:?}", path_segs);
let span = path.span;
match path.def {
- Def::Existential(did) => {
+ Def::Def(DefKind::Existential, did) => {
// Check for desugared impl trait.
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
let item_segment = path.segments.split_last().unwrap();
tcx.mk_opaque(did, substs),
)
}
- Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) |
- Def::Union(did) | Def::ForeignTy(did) => {
+ Def::Def(DefKind::Enum, did)
+ | Def::Def(DefKind::TyAlias, did)
+ | Def::Def(DefKind::Struct, did)
+ | Def::Def(DefKind::Union, did)
+ | Def::Def(DefKind::ForeignTy, did) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments.split_last().unwrap().1);
self.ast_path_to_ty(span, did, path.segments.last().unwrap())
}
- Def::Variant(_) if permit_variants => {
+ Def::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
// Convert "variant type" as if it were a real type.
// The resulting `Ty` is type of the variant's enum for now.
assert_eq!(opt_self_ty, None);
- let path_segs = self.def_ids_for_path_segments(&path.segments, None, path.def);
+ let path_segs =
+ self.def_ids_for_value_path_segments(&path.segments, None, kind, def_id);
let generic_segs: FxHashSet<_> =
path_segs.iter().map(|PathSeg(_, index)| index).collect();
self.prohibit_generics(path.segments.iter().enumerate().filter_map(|(index, seg)| {
let PathSeg(def_id, index) = path_segs.last().unwrap();
self.ast_path_to_ty(span, *def_id, &path.segments[*index])
}
- Def::TyParam(did) => {
+ Def::Def(DefKind::TyParam, did) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(&path.segments);
self.prohibit_generics(&path.segments);
tcx.mk_self_type()
}
- Def::AssociatedTy(def_id) => {
+ Def::Def(DefKind::AssociatedTy, def_id) => {
debug_assert!(path.segments.len() >= 2);
self.prohibit_generics(&path.segments[..path.segments.len() - 2]);
self.qpath_to_ty(span,
} else {
Def::Err
};
- self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, def, segment, false).0
+ self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, def, segment, false)
+ .map(|(ty, _, _)| ty).unwrap_or(tcx.types.err)
}
hir::TyKind::Array(ref ty, ref length) => {
let length = self.ast_const_to_const(length, tcx.types.usize);
let expr = &tcx.hir().body(ast_const.body).value;
if let ExprKind::Path(ref qpath) = expr.node {
if let hir::QPath::Resolved(_, ref path) = qpath {
- if let Def::ConstParam(def_id) = path.def {
+ if let Def::Def(DefKind::ConstParam, def_id) = path.def {
let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
let item_id = tcx.hir().get_parent_node(node_id);
let item_def_id = tcx.hir().local_def_id(item_id);
// Replace all parent lifetimes with 'static.
match param.kind {
GenericParamDefKind::Lifetime => {
- tcx.types.re_static.into()
+ tcx.lifetimes.re_static.into()
}
_ => tcx.mk_param_from_def(param)
}
// If any of the derived region bounds are 'static, that is always
// the best choice.
if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
- return Some(tcx.types.re_static);
+ return Some(tcx.lifetimes.re_static);
}
// Determine whether there is exactly one unique region in the set
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
// Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
match bound.trait_ref.path.def {
- Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => {
+ Def::Def(DefKind::Trait, trait_did) if tcx.trait_is_auto(trait_did) => {
true
}
_ => false
});
let auto_traits = auto_traits.into_iter().map(|tr| {
- if let Def::Trait(trait_did) = tr.trait_ref.path.def {
+ if let Def::Def(DefKind::Trait, trait_did) = tr.trait_ref.path.def {
trait_did
} else {
unreachable!()