Skip to content

Commit 8e7783b

Browse files
Fix opaque_hidden_inferred_bound lint ICE
1 parent 24ac6a2 commit 8e7783b

File tree

3 files changed

+61
-19
lines changed

3 files changed

+61
-19
lines changed

compiler/rustc_error_messages/locales/en-US/lint.ftl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,4 +436,5 @@ lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not
436436
437437
lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its associated type bounds
438438
.specifically = this associated type bound is unsatisfied for `{$proj_ty}`
439-
.suggestion = add this bound
439+
440+
lint_opaque_hidden_inferred_bound_sugg = add this bound

compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use rustc_errors::DecorateLint;
12
use rustc_hir as hir;
23
use rustc_infer::infer::TyCtxtInferExt;
3-
use rustc_macros::LintDiagnostic;
4-
use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable};
4+
use rustc_macros::{LintDiagnostic, Subdiagnostic};
5+
use rustc_middle::ty::{
6+
self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable,
7+
};
58
use rustc_span::Span;
69
use rustc_trait_selection::traits;
710
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -117,23 +120,29 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
117120
)) {
118121
// If it's a trait bound and an opaque that doesn't satisfy it,
119122
// then we can emit a suggestion to add the bound.
120-
let (suggestion, suggest_span) =
123+
let sugg =
121124
match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
122-
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => (
123-
format!(" + {}", trait_pred.print_modifiers_and_trait_path()),
124-
Some(cx.tcx.def_span(def_id).shrink_to_hi()),
125-
),
126-
_ => (String::new(), None),
125+
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound {
126+
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
127+
trait_ref: trait_pred.print_modifiers_and_trait_path(),
128+
}),
129+
_ => None,
127130
};
128-
cx.emit_spanned_lint(
131+
let lint = OpaqueHiddenInferredBoundLint {
132+
ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)),
133+
proj_ty: proj_term,
134+
assoc_pred_span,
135+
};
136+
cx.struct_span_lint(
129137
OPAQUE_HIDDEN_INFERRED_BOUND,
130138
pred_span,
131-
OpaqueHiddenInferredBoundLint {
132-
ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)),
133-
proj_ty: proj_term,
134-
assoc_pred_span,
135-
suggestion,
136-
suggest_span,
139+
lint.msg(),
140+
|diag| {
141+
lint.decorate_lint(diag);
142+
if let Some(sugg) = sugg {
143+
diag.subdiagnostic(sugg);
144+
}
145+
diag
137146
},
138147
);
139148
}
@@ -150,7 +159,17 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
150159
proj_ty: Ty<'tcx>,
151160
#[label(lint::specifically)]
152161
assoc_pred_span: Span,
153-
#[suggestion_verbose(applicability = "machine-applicable", code = "{suggestion}")]
154-
suggest_span: Option<Span>,
155-
suggestion: String,
162+
}
163+
164+
#[derive(Subdiagnostic)]
165+
#[suggestion_verbose(
166+
lint::opaque_hidden_inferred_bound_sugg,
167+
applicability = "machine-applicable",
168+
code = " + {trait_ref}"
169+
)]
170+
struct AddBound<'tcx> {
171+
#[primary_span]
172+
suggest_span: Span,
173+
#[skip_arg]
174+
trait_ref: TraitPredPrintModifiersAndPath<'tcx>,
156175
}

src/test/ui/lint/issue-102705.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-pass
2+
3+
#![allow(opaque_hidden_inferred_bound)]
4+
#![allow(dead_code)]
5+
6+
trait Duh {}
7+
8+
impl Duh for i32 {}
9+
10+
trait Trait {
11+
type Assoc: Duh;
12+
}
13+
14+
impl<R: Duh, F: FnMut() -> R> Trait for F {
15+
type Assoc = R;
16+
}
17+
18+
fn foo() -> impl Trait<Assoc = impl Send> {
19+
|| 42
20+
}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)