From 8e7783bd131e7e5a326985765b7f4399c497f7bb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Oct 2022 19:46:40 +0000 Subject: [PATCH 1/2] Fix opaque_hidden_inferred_bound lint ICE --- .../locales/en-US/lint.ftl | 3 +- .../src/opaque_hidden_inferred_bound.rs | 55 +++++++++++++------ src/test/ui/lint/issue-102705.rs | 22 ++++++++ 3 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/lint/issue-102705.rs diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 0fd9b0ead167c..7e28f22c0ba8b 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -436,4 +436,5 @@ lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its associated type bounds .specifically = this associated type bound is unsatisfied for `{$proj_ty}` - .suggestion = add this bound + +lint_opaque_hidden_inferred_bound_sugg = add this bound diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index d8ce20db37ce9..4ff3b2e2c4a76 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -1,7 +1,10 @@ +use rustc_errors::DecorateLint; use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; -use rustc_macros::LintDiagnostic; -use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; +use rustc_macros::{LintDiagnostic, Subdiagnostic}; +use rustc_middle::ty::{ + self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, +}; use rustc_span::Span; use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -117,23 +120,29 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { )) { // If it's a trait bound and an opaque that doesn't satisfy it, // then we can emit a suggestion to add the bound. - let (suggestion, suggest_span) = + let sugg = match (proj_term.kind(), assoc_pred.kind().skip_binder()) { - (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => ( - format!(" + {}", trait_pred.print_modifiers_and_trait_path()), - Some(cx.tcx.def_span(def_id).shrink_to_hi()), - ), - _ => (String::new(), None), + (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound { + suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(), + trait_ref: trait_pred.print_modifiers_and_trait_path(), + }), + _ => None, }; - cx.emit_spanned_lint( + let lint = OpaqueHiddenInferredBoundLint { + ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), + proj_ty: proj_term, + assoc_pred_span, + }; + cx.struct_span_lint( OPAQUE_HIDDEN_INFERRED_BOUND, pred_span, - OpaqueHiddenInferredBoundLint { - ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), - proj_ty: proj_term, - assoc_pred_span, - suggestion, - suggest_span, + lint.msg(), + |diag| { + lint.decorate_lint(diag); + if let Some(sugg) = sugg { + diag.subdiagnostic(sugg); + } + diag }, ); } @@ -150,7 +159,17 @@ struct OpaqueHiddenInferredBoundLint<'tcx> { proj_ty: Ty<'tcx>, #[label(lint::specifically)] assoc_pred_span: Span, - #[suggestion_verbose(applicability = "machine-applicable", code = "{suggestion}")] - suggest_span: Option, - suggestion: String, +} + +#[derive(Subdiagnostic)] +#[suggestion_verbose( + lint::opaque_hidden_inferred_bound_sugg, + applicability = "machine-applicable", + code = " + {trait_ref}" +)] +struct AddBound<'tcx> { + #[primary_span] + suggest_span: Span, + #[skip_arg] + trait_ref: TraitPredPrintModifiersAndPath<'tcx>, } diff --git a/src/test/ui/lint/issue-102705.rs b/src/test/ui/lint/issue-102705.rs new file mode 100644 index 0000000000000..5bcc8950adafb --- /dev/null +++ b/src/test/ui/lint/issue-102705.rs @@ -0,0 +1,22 @@ +// check-pass + +#![allow(opaque_hidden_inferred_bound)] +#![allow(dead_code)] + +trait Duh {} + +impl Duh for i32 {} + +trait Trait { + type Assoc: Duh; +} + +impl R> Trait for F { + type Assoc = R; +} + +fn foo() -> impl Trait { + || 42 +} + +fn main() {} From fe0533638c058c0c159804ce91887304ca16a640 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Oct 2022 19:55:19 +0000 Subject: [PATCH 2/2] Use proper subdiagnostic --- .../src/opaque_hidden_inferred_bound.rs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 4ff3b2e2c4a76..31705624a7fef 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -1,4 +1,3 @@ -use rustc_errors::DecorateLint; use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{LintDiagnostic, Subdiagnostic}; @@ -120,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { )) { // If it's a trait bound and an opaque that doesn't satisfy it, // then we can emit a suggestion to add the bound. - let sugg = + let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) { (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound { suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(), @@ -128,21 +127,14 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { }), _ => None, }; - let lint = OpaqueHiddenInferredBoundLint { - ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), - proj_ty: proj_term, - assoc_pred_span, - }; - cx.struct_span_lint( + cx.emit_spanned_lint( OPAQUE_HIDDEN_INFERRED_BOUND, pred_span, - lint.msg(), - |diag| { - lint.decorate_lint(diag); - if let Some(sugg) = sugg { - diag.subdiagnostic(sugg); - } - diag + OpaqueHiddenInferredBoundLint { + ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), + proj_ty: proj_term, + assoc_pred_span, + add_bound, }, ); } @@ -159,6 +151,8 @@ struct OpaqueHiddenInferredBoundLint<'tcx> { proj_ty: Ty<'tcx>, #[label(lint::specifically)] assoc_pred_span: Span, + #[subdiagnostic] + add_bound: Option>, } #[derive(Subdiagnostic)]