pub trait AstConv<'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
+ fn item_def_id(&self) -> Option<DefId>;
+
/// Returns predicates in scope of the form `X: Foo`, where `X` is
/// a type parameter `X` with the given id `def_id`. This is a
/// subset of the full set of predicates.
/// Report error if there is an explicit type parameter when using `impl Trait`.
fn check_impl_trait(
tcx: TyCtxt<'_>,
- span: Span,
seg: &hir::PathSegment,
generics: &ty::Generics,
) -> bool {
});
if explicit && impl_trait {
+ let spans =
+ seg.generic_args().args
+ .iter()
+ .filter_map(|arg|
+ match arg {
+ GenericArg::Type(_) => Some(arg.span()),
+ _ => None
+ })
+ .collect::<Vec<_>>();
+
let mut err = struct_span_err! {
tcx.sess,
- span,
+ spans.clone(),
E0632,
"cannot provide explicit generic arguments when `impl Trait` is \
- used in argument position"
+ used in argument position"
};
+ for span in spans {
+ err.span_label(span, "explicit generic argument not allowed");
+ }
+
err.emit();
}
let empty_args = P(hir::GenericArgs {
args: HirVec::new(), bindings: HirVec::new(), parenthesized: false,
});
- let suppress_mismatch = Self::check_impl_trait(tcx, span, seg, &def);
+ let suppress_mismatch = Self::check_impl_trait(tcx, seg, &def);
Self::check_generic_arg_count(
tcx,
span,
-> Ty<'tcx>
{
let tcx = self.tcx();
+
let trait_def_id = tcx.parent(item_def_id).unwrap();
+ debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
+
self.prohibit_generics(slice::from_ref(item_segment));
let self_ty = if let Some(ty) = opt_self_ty {
ty
} else {
let path_str = tcx.def_path_str(trait_def_id);
+
+ let def_id = self.item_def_id();
+
+ debug!("qpath_to_ty: self.item_def_id()={:?}", def_id);
+
+ let parent_def_id = def_id.and_then(|def_id| tcx.hir().as_local_hir_id(def_id))
+ .map(|hir_id| tcx.hir().get_parent_did(hir_id));
+
+ debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id);
+
+ // If the trait in segment is the same as the trait defining the item,
+ // use the `<Self as ..>` syntax in the error.
+ let is_part_of_self_trait_constraints = def_id == Some(trait_def_id);
+ let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id);
+
+ let type_name = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
+ "Self"
+ } else {
+ "Type"
+ };
+
self.report_ambiguous_associated_type(
span,
- "Type",
+ type_name,
&path_str,
item_segment.ident.name,
);