Skip to content

Commit 676611e

Browse files
committed
Make diagnostics for uncovered type params non-translateable
1 parent ae9173d commit 676611e

File tree

3 files changed

+55
-100
lines changed

3 files changed

+55
-100
lines changed

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -540,16 +540,6 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
540540
541541
hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}`
542542
543-
hir_analysis_ty_param_first_local = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
544-
.label = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
545-
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
546-
.case_note = in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
547-
548-
hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param}>`)
549-
.label = type parameter `{$param}` must be used as the type parameter for some local type
550-
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
551-
.only_note = only traits defined in the current crate can be implemented for a type parameter
552-
553543
hir_analysis_type_of = {$ty}
554544
555545
hir_analysis_typeof_reserved_keyword_used =

compiler/rustc_hir_analysis/src/coherence/orphan.rs

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
//! crate or pertains to a type defined in this crate.
33
44
use rustc_data_structures::fx::FxIndexSet;
5-
use rustc_errors::ErrorGuaranteed;
5+
use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed};
66
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
77
use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
88
use rustc_middle::ty::{
99
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
1010
};
1111
use rustc_middle::{bug, span_bug};
1212
use rustc_span::def_id::{DefId, LocalDefId};
13+
use rustc_span::{Ident, Span};
1314
use rustc_trait_selection::traits::{
1415
self, IsFirstInputType, OrphanCheckErr, OrphanCheckMode, UncoveredTyParams,
1516
};
@@ -30,7 +31,25 @@ pub(crate) fn orphan_check_impl(
3031
Err(err) => match orphan_check(tcx, impl_def_id, OrphanCheckMode::Compat) {
3132
Ok(()) => match err {
3233
OrphanCheckErr::UncoveredTyParams(uncovered_ty_params) => {
33-
lint_uncovered_ty_params(tcx, uncovered_ty_params, impl_def_id)
34+
let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
35+
36+
for param_def_id in uncovered_ty_params.uncovered {
37+
let ident = tcx.item_ident(param_def_id);
38+
39+
tcx.node_span_lint(
40+
UNCOVERED_PARAM_IN_PROJECTION,
41+
hir_id,
42+
ident.span,
43+
|diag| {
44+
decorate_uncovered_ty_params_diag(
45+
diag,
46+
ident.span,
47+
ident,
48+
uncovered_ty_params.local_ty,
49+
)
50+
},
51+
);
52+
}
3453
}
3554
OrphanCheckErr::NonLocalInputType(_) => {
3655
bug!("orphanck: shouldn't've gotten non-local input tys in compat mode")
@@ -469,51 +488,47 @@ fn emit_orphan_check_error<'tcx>(
469488
diag.emit()
470489
}
471490
traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
472-
let mut reported = None;
491+
let mut guar = None;
473492
for param_def_id in uncovered {
474-
let name = tcx.item_ident(param_def_id);
475-
let span = name.span;
476-
477-
reported.get_or_insert(match local_ty {
478-
Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal {
479-
span,
480-
note: (),
481-
param: name,
482-
local_type,
483-
}),
484-
None => tcx.dcx().emit_err(errors::TyParamSome { span, note: (), param: name }),
485-
});
493+
let ident = tcx.item_ident(param_def_id);
494+
let mut diag = tcx.dcx().struct_span_err(ident.span, "");
495+
decorate_uncovered_ty_params_diag(&mut diag, ident.span, ident, local_ty);
496+
guar.get_or_insert(diag.emit());
486497
}
487-
reported.unwrap() // FIXME(fmease): This is very likely reachable.
498+
guar.unwrap()
488499
}
489500
}
490501
}
491502

492-
fn lint_uncovered_ty_params<'tcx>(
493-
tcx: TyCtxt<'tcx>,
494-
UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams<TyCtxt<'tcx>, FxIndexSet<DefId>>,
495-
impl_def_id: LocalDefId,
503+
fn decorate_uncovered_ty_params_diag(
504+
diag: &mut Diag<'_, impl EmissionGuarantee>,
505+
span: Span,
506+
param: Ident,
507+
local_ty: Option<Ty<'_>>,
496508
) {
497-
let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
498-
499-
for param_def_id in uncovered {
500-
let span = tcx.def_ident_span(param_def_id).unwrap();
501-
let name = tcx.item_ident(param_def_id);
502-
503-
match local_ty {
504-
Some(local_type) => tcx.emit_node_span_lint(
505-
UNCOVERED_PARAM_IN_PROJECTION,
506-
hir_id,
507-
span,
508-
errors::TyParamFirstLocalLint { span, note: (), param: name, local_type },
509-
),
510-
None => tcx.emit_node_span_lint(
511-
UNCOVERED_PARAM_IN_PROJECTION,
512-
hir_id,
513-
span,
514-
errors::TyParamSomeLint { span, note: (), param: name },
515-
),
516-
};
509+
diag.code(rustc_errors::E0210);
510+
511+
let note = "implementing a foreign trait is only possible if at least one of the types for which it is implemented is local";
512+
if let Some(local_ty) = local_ty {
513+
let msg = format!(
514+
"type parameter `{param}` must be covered by another type when it appears before the first local type (`{local_ty}`)"
515+
);
516+
diag.primary_message(msg.clone());
517+
diag.span_label(span, msg);
518+
diag.note(format!(
519+
"{note}, and no uncovered type parameters appear before that first local type"
520+
));
521+
diag.note("in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last");
522+
} else {
523+
let msg = format!(
524+
"type parameter `{param}` must be used as the type parameter for some local type"
525+
);
526+
diag.primary_message(format!("{msg} (e.g., `MyStruct<{param}>`)"));
527+
diag.span_label(span, msg);
528+
diag.note(note);
529+
diag.note(
530+
"only traits defined in the current crate can be implemented for a type parameter",
531+
);
517532
}
518533
}
519534

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,56 +1365,6 @@ pub struct NoVariantNamed<'tcx> {
13651365
pub ty: Ty<'tcx>,
13661366
}
13671367

1368-
// FIXME(fmease): Deduplicate:
1369-
1370-
#[derive(Diagnostic)]
1371-
#[diag(hir_analysis_ty_param_first_local, code = E0210)]
1372-
#[note]
1373-
pub(crate) struct TyParamFirstLocal<'tcx> {
1374-
#[primary_span]
1375-
#[label]
1376-
pub span: Span,
1377-
#[note(hir_analysis_case_note)]
1378-
pub note: (),
1379-
pub param: Ident,
1380-
pub local_type: Ty<'tcx>,
1381-
}
1382-
1383-
#[derive(LintDiagnostic)]
1384-
#[diag(hir_analysis_ty_param_first_local, code = E0210)]
1385-
#[note]
1386-
pub(crate) struct TyParamFirstLocalLint<'tcx> {
1387-
#[label]
1388-
pub span: Span,
1389-
#[note(hir_analysis_case_note)]
1390-
pub note: (),
1391-
pub param: Ident,
1392-
pub local_type: Ty<'tcx>,
1393-
}
1394-
1395-
#[derive(Diagnostic)]
1396-
#[diag(hir_analysis_ty_param_some, code = E0210)]
1397-
#[note]
1398-
pub(crate) struct TyParamSome {
1399-
#[primary_span]
1400-
#[label]
1401-
pub span: Span,
1402-
#[note(hir_analysis_only_note)]
1403-
pub note: (),
1404-
pub param: Ident,
1405-
}
1406-
1407-
#[derive(LintDiagnostic)]
1408-
#[diag(hir_analysis_ty_param_some, code = E0210)]
1409-
#[note]
1410-
pub(crate) struct TyParamSomeLint {
1411-
#[label]
1412-
pub span: Span,
1413-
#[note(hir_analysis_only_note)]
1414-
pub note: (),
1415-
pub param: Ident,
1416-
}
1417-
14181368
#[derive(Diagnostic)]
14191369
pub(crate) enum OnlyCurrentTraits {
14201370
#[diag(hir_analysis_only_current_traits_outside, code = E0117)]

0 commit comments

Comments
 (0)