MethodCall,
}
-/// Dummy type used for the `Self` of a `TraitRef` created for converting
-/// a trait object, and which gets removed in `ExistentialTraitRef`.
-/// This type must not appear anywhere in other converted types.
-const TRAIT_OBJECT_DUMMY_SELF: ty::TyKind<'static> = ty::Infer(ty::FreshTy(0));
-
impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
pub fn ast_region_to_region(&self,
lifetime: &hir::Lifetime,
infer_types,
);
- let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
+ let is_object = self_ty.map_or(false, |ty| {
+ ty == self.tcx().types.trait_object_dummy_self
+ });
let default_needs_object_self = |param: &ty::GenericParamDef| {
if let GenericParamDefKind::Type { has_default, .. } = param.kind {
if is_object && has_default {
}
/// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
- /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
+ /// removing the dummy `Self` type (`trait_object_dummy_self`).
fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
-> ty::ExistentialTraitRef<'tcx> {
- if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF {
+ if trait_ref.self_ty() != self.tcx().types.trait_object_dummy_self {
bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
}
ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
}
let mut projection_bounds = Vec::new();
- let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
+ let dummy_self = self.tcx().types.trait_object_dummy_self;
let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref(
&trait_bounds[0],
dummy_self,
}
ty::Predicate::Projection(pred) => {
// A `Self` within the original bound will be substituted with a
- // `TRAIT_OBJECT_DUMMY_SELF`, so check for that.
+ // `trait_object_dummy_self`, so check for that.
let references_self =
pred.skip_binder().ty.walk().any(|t| t == dummy_self);
err.emit();
}
- // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
+ // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_principal = principal.map_bound(|trait_ref| {
self.trait_ref_to_existential(trait_ref)
});
let msg = format!("expected type, found variant `{}`", assoc_ident);
tcx.sess.span_err(span, &msg);
} else if qself_ty.is_enum() {
- // Report as incorrect enum variant rather than ambiguous type.
let mut err = tcx.sess.struct_span_err(
- span,
- &format!("no variant `{}` on enum `{}`", &assoc_ident.as_str(), qself_ty),
+ assoc_ident.span,
+ &format!("no variant `{}` in enum `{}`", assoc_ident, qself_ty),
);
- // Check if it was a typo.
+
let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
if let Some(suggested_name) = find_best_match_for_name(
adt_def.variants.iter().map(|variant| &variant.ident.name),
None,
) {
err.span_suggestion(
- span,
- "did you mean",
- format!("{}::{}", qself_ty, suggested_name),
+ assoc_ident.span,
+ "there is a variant with a similar name",
+ suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
} else {
- err.span_label(span, "unknown variant");
+ err.span_label(span, format!("variant not found in `{}`", qself_ty));
}
+
+ if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
+ let sp = tcx.sess.source_map().def_span(sp);
+ err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
+ }
+
err.emit();
} else if !qself_ty.references_error() {
// Don't print `TyErr` to the user.
self.def_to_ty(opt_self_ty, path, false)
}
hir::TyKind::Def(item_id, ref lifetimes) => {
- let did = tcx.hir().local_def_id(item_id.id);
+ let did = tcx.hir().local_def_id_from_hir_id(item_id.id);
self.impl_trait_ty_to_ty(did, lifetimes)
},
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {