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::Def(DefKind::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::Def(DefKind::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),
- }
+ 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::Def(DefKind::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::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) |
- 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::Def(DefKind::Ctor(CtorOf::Variant, ..), def_id)
- | Def::Def(DefKind::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());
let mut def_id = def_id;
// `DefKind::Ctor` -> `DefKind::Variant`
- if let Def::Def(DefKind::Ctor(..), _) = def {
+ if let DefKind::Ctor(..) = kind {
def_id = tcx.parent(def_id).unwrap()
}
- // `DefKind::Variant` -> `DefKind::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::Def(DefKind::Fn, def_id) |
- Def::Def(DefKind::Const, def_id) |
- Def::Def(DefKind::ConstParam, def_id) |
- Def::Def(DefKind::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::Def(DefKind::Method, def_id) |
- Def::Def(DefKind::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);
self.prohibit_generics(path.segments.split_last().unwrap().1);
self.ast_path_to_ty(span, did, path.segments.last().unwrap())
}
- Def::Def(DefKind::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)| {
} 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);