Rollup merge of #102718 - compiler-errors:opaque-bound-lint-ice, r=fee1-dead

Fix `opaque_hidden_inferred_bound` lint ICE

Fixes #102705
This commit is contained in:
Matthias Krüger 2022-10-06 16:29:44 +02:00 committed by GitHub
commit 045fc18cde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 14 deletions

View File

@ -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 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}` .specifically = this associated type bound is unsatisfied for `{$proj_ty}`
.suggestion = add this bound
lint_opaque_hidden_inferred_bound_sugg = add this bound

View File

@ -1,7 +1,9 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_macros::LintDiagnostic; use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; use rustc_middle::ty::{
self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable,
};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits; use rustc_trait_selection::traits;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@ -117,13 +119,13 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
)) { )) {
// If it's a trait bound and an opaque that doesn't satisfy it, // If it's a trait bound and an opaque that doesn't satisfy it,
// then we can emit a suggestion to add the bound. // then we can emit a suggestion to add the bound.
let (suggestion, suggest_span) = let add_bound =
match (proj_term.kind(), assoc_pred.kind().skip_binder()) { match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => ( (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound {
format!(" + {}", trait_pred.print_modifiers_and_trait_path()), suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
Some(cx.tcx.def_span(def_id).shrink_to_hi()), trait_ref: trait_pred.print_modifiers_and_trait_path(),
), }),
_ => (String::new(), None), _ => None,
}; };
cx.emit_spanned_lint( cx.emit_spanned_lint(
OPAQUE_HIDDEN_INFERRED_BOUND, OPAQUE_HIDDEN_INFERRED_BOUND,
@ -132,8 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)),
proj_ty: proj_term, proj_ty: proj_term,
assoc_pred_span, assoc_pred_span,
suggestion, add_bound,
suggest_span,
}, },
); );
} }
@ -150,7 +151,19 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
proj_ty: Ty<'tcx>, proj_ty: Ty<'tcx>,
#[label(lint::specifically)] #[label(lint::specifically)]
assoc_pred_span: Span, assoc_pred_span: Span,
#[suggestion_verbose(applicability = "machine-applicable", code = "{suggestion}")] #[subdiagnostic]
suggest_span: Option<Span>, add_bound: Option<AddBound<'tcx>>,
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>,
} }

View File

@ -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: Duh, F: FnMut() -> R> Trait for F {
type Assoc = R;
}
fn foo() -> impl Trait<Assoc = impl Send> {
|| 42
}
fn main() {}