about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-16 18:57:44 +0000
committerbors <bors@rust-lang.org>2023-10-16 18:57:44 +0000
commita76ec181fba25f9fe64999ec2ae84bdc393560f2 (patch)
treed6f91587f1597b63f71878910320662db6eb54f8 /compiler
parent4af886f8ab94543caad689ee6bf6a93fa8bd4a98 (diff)
parentb0572f1a12f323c0f806f78d775bc4a7c29d80aa (diff)
Auto merge of #116804 - matthiaskrgr:rollup-m2qm8ul, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #114157 (Enable triagebot no-merges check)
 - #116257 (Suggest trait bounds for used associated type on type param)
 - #116430 (vendoring in tarball sources)
 - #116709 (Update minifier version to 0.2.3)
 - #116786 (Update my mailmap entry)
 - #116790 (opt-dist: disable unused features for tabled crate)
 - #116802 (Remove `DefiningAnchor::Bubble` from opaque wf check)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs58
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
5 files changed, 72 insertions, 24 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index ff04b0237c2..ee554370305 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::OpaqueTyOrigin;
 use rustc_infer::infer::InferCtxt;
@@ -308,20 +309,19 @@ fn check_opaque_type_well_formed<'tcx>(
         return Ok(definition_ty);
     };
     let param_env = tcx.param_env(def_id);
-    // HACK This bubble is required for this tests to pass:
-    // nested-return-type2-tait2.rs
-    // nested-return-type2-tait3.rs
+
+    let mut parent_def_id = def_id;
+    while tcx.def_kind(parent_def_id) == DefKind::OpaqueTy {
+        parent_def_id = tcx.local_parent(parent_def_id);
+    }
+
     // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
     // and prepopulate this `InferCtxt` with known opaque values, rather than
     // using the `Bind` anchor here. For now it's fine.
     let infcx = tcx
         .infer_ctxt()
         .with_next_trait_solver(next_trait_solver)
-        .with_opaque_type_inference(if next_trait_solver {
-            DefiningAnchor::Bind(def_id)
-        } else {
-            DefiningAnchor::Bubble
-        })
+        .with_opaque_type_inference(DefiningAnchor::Bind(parent_def_id))
         .build();
     let ocx = ObligationCtxt::new(&infcx);
     let identity_args = GenericArgs::identity_for_item(tcx, def_id);
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 45d174cbbbb..059dfc60450 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -284,6 +284,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
             self.one_bound_for_assoc_type(
                 || traits::supertraits(tcx, trait_ref),
                 trait_ref.skip_binder().print_only_trait_name(),
+                None,
                 binding.item_name,
                 path_span,
                 match binding.kind {
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index ed4dde419c4..9e18767a7c3 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -6,10 +6,9 @@ use crate::errors::{
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
-use rustc_middle::ty::TyCtxt;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt};
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::symbol::{sym, Ident};
@@ -102,6 +101,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         all_candidates: impl Fn() -> I,
         ty_param_name: &str,
+        ty_param_def_id: Option<LocalDefId>,
         assoc_name: Ident,
         span: Span,
     ) -> ErrorGuaranteed
@@ -190,13 +190,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 })
                 .collect::<Vec<_>>()[..]
             {
+                let trait_name = self.tcx().def_path_str(*best_trait);
+                let an = if suggested_name != assoc_name.name { "a similarly named" } else { "an" };
                 err.span_label(
                     assoc_name.span,
                     format!(
-                        "there is a similarly named associated type `{suggested_name}` in the trait `{}`",
-                        self.tcx().def_path_str(*best_trait)
+                        "there is {an} associated type `{suggested_name}` in the \
+                         trait `{trait_name}`",
                     ),
                 );
+                let hir = self.tcx().hir();
+                if let Some(def_id) = ty_param_def_id
+                    && let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id))
+                    && let Some(generics) = hir.get_generics(parent.def_id)
+                {
+                    if generics.bounds_for_param(def_id)
+                        .flat_map(|pred| pred.bounds.iter())
+                        .any(|b| match b {
+                            hir::GenericBound::Trait(t, ..) => {
+                                t.trait_ref.trait_def_id().as_ref() == Some(best_trait)
+                            }
+                            _ => false,
+                        })
+                    {
+                        // The type param already has a bound for `trait_name`, we just need to
+                        // change the associated type.
+                        err.span_suggestion_verbose(
+                            assoc_name.span,
+                            format!(
+                                "change the associated type name to use `{suggested_name}` from \
+                                 `{trait_name}`",
+                            ),
+                            suggested_name.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else if suggest_constraining_type_param(
+                            self.tcx(),
+                            generics,
+                            &mut err,
+                            &ty_param_name,
+                            &trait_name,
+                            None,
+                            None,
+                        )
+                        && suggested_name != assoc_name.name
+                    {
+                        // We suggested constraining a type parameter, but the associated type on it
+                        // was also not an exact match, so we also suggest changing it.
+                        err.span_suggestion_verbose(
+                            assoc_name.span,
+                            "and also change the associated type name",
+                            suggested_name.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
                 return err.emit();
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index ac97df0c087..6bcf33a1f6d 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1062,6 +1062,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 )
             },
             param_name,
+            Some(ty_param_def_id),
             assoc_name,
             span,
             None,
@@ -1075,6 +1076,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         all_candidates: impl Fn() -> I,
         ty_param_name: impl Display,
+        ty_param_def_id: Option<LocalDefId>,
         assoc_name: Ident,
         span: Span,
         is_equality: Option<ty::Term<'tcx>>,
@@ -1096,6 +1098,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let reported = self.complain_about_assoc_type_not_found(
                     all_candidates,
                     &ty_param_name.to_string(),
+                    ty_param_def_id,
                     assoc_name,
                     span,
                 );
@@ -1143,30 +1146,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     err.span_label(
                         bound_span,
                         format!(
-                            "ambiguous `{}` from `{}`",
-                            assoc_name,
+                            "ambiguous `{assoc_name}` from `{}`",
                             bound.print_only_trait_path(),
                         ),
                     );
                     if let Some(constraint) = &is_equality {
                         where_bounds.push(format!(
-                            "        T: {trait}::{assoc} = {constraint}",
+                            "        T: {trait}::{assoc_name} = {constraint}",
                             trait=bound.print_only_trait_path(),
-                            assoc=assoc_name,
-                            constraint=constraint,
                         ));
                     } else {
                         err.span_suggestion_verbose(
                             span.with_hi(assoc_name.span.lo()),
                             "use fully qualified syntax to disambiguate",
-                            format!("<{} as {}>::", ty_param_name, bound.print_only_trait_path()),
+                            format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
                             Applicability::MaybeIncorrect,
                         );
                     }
                 } else {
                     err.note(format!(
-                        "associated type `{}` could derive from `{}`",
-                        ty_param_name,
+                        "associated type `{ty_param_name}` could derive from `{}`",
                         bound.print_only_trait_path(),
                     ));
                 }
@@ -1174,8 +1173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             if !where_bounds.is_empty() {
                 err.help(format!(
                     "consider introducing a new type parameter `T` and adding `where` constraints:\
-                     \n    where\n        T: {},\n{}",
-                    ty_param_name,
+                     \n    where\n        T: {ty_param_name},\n{}",
                     where_bounds.join(",\n"),
                 ));
             }
@@ -1397,6 +1395,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         )
                     },
                     kw::SelfUpper,
+                    None,
                     assoc_ident,
                     span,
                     None,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ea8ceda87be..78f7f915f72 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -364,7 +364,7 @@ fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -
 /// Type parameter needs more bounds. The trivial case is `T` `where T: Bound`, but
 /// it can also be an `impl Trait` param that needs to be decomposed to a type
 /// param for cleaner code.
-fn suggest_restriction<'tcx>(
+pub fn suggest_restriction<'tcx>(
     tcx: TyCtxt<'tcx>,
     item_id: LocalDefId,
     hir_generics: &hir::Generics<'tcx>,