]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/astconv.rs
Rollup merge of #66101 - estebank:break-tail-e0308, r=Centril
[rust.git] / src / librustc_typeck / astconv.rs
index 8eab9c4e67e3313ea4a17f3c90792ba88aaf01da..b14121da79f596059adc7e486ad70bf0b2b42dab 100644 (file)
@@ -43,6 +43,8 @@
 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.
@@ -131,7 +133,7 @@ pub fn ast_region_to_region(&self,
     {
         let tcx = self.tcx();
         let lifetime_name = |def_id| {
-            tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap()).as_interned_str()
+            tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap())
         };
 
         let r = match tcx.named_region(lifetime.hir_id) {
@@ -215,7 +217,6 @@ pub fn ast_path_substs_for_ty(&self,
     /// 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 {
@@ -228,14 +229,28 @@ fn check_impl_trait(
         });
 
         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();
         }
 
@@ -254,7 +269,7 @@ pub fn check_generic_arg_count_for_call(
         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,
@@ -1274,8 +1289,7 @@ fn conv_object_ty_poly_trait_ref(&self,
                     span,
                     item.trait_ref().def_id(),
                     object_safety_violations
-                )
-                    .map(|mut err| err.emit());
+                ).emit();
                 return tcx.types.err;
             }
         }
@@ -1747,17 +1761,41 @@ fn qpath_to_ty(&self,
                    -> 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,
             );
@@ -2023,7 +2061,7 @@ pub fn res_to_ty(&self,
                 let item_def_id = tcx.hir().local_def_id(item_id);
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id];
-                tcx.mk_ty_param(index, tcx.hir().name(hir_id).as_interned_str())
+                tcx.mk_ty_param(index, tcx.hir().name(hir_id))
             }
             Res::SelfTy(Some(_), None) => {
                 // `Self` in trait or type alias.
@@ -2204,7 +2242,7 @@ pub fn ast_const_to_const(
             let item_def_id = tcx.hir().local_def_id(item_id);
             let generics = tcx.generics_of(item_def_id);
             let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
-            let name = tcx.hir().name(hir_id).as_interned_str();
+            let name = tcx.hir().name(hir_id);
             const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
         }