Skip to content

Commit 7dbdbaa

Browse files
Fix ICEs in diagnostic::on_unimplemented
1 parent a8f2e33 commit 7dbdbaa

File tree

2 files changed

+203
-51
lines changed

2 files changed

+203
-51
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

+69-51
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,14 @@ impl IgnoredDiagnosticOption {
350350
option_name: &'static str,
351351
) {
352352
if let (Some(new_item), Some(old_item)) = (new, old) {
353-
tcx.emit_node_span_lint(
354-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
355-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
356-
new_item,
357-
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
358-
);
353+
if let Some(item_def_id) = item_def_id.as_local() {
354+
tcx.emit_node_span_lint(
355+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
356+
tcx.local_def_id_to_hir_id(item_def_id),
357+
new_item,
358+
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
359+
);
360+
}
359361
}
360362
}
361363
}
@@ -639,30 +641,38 @@ impl<'tcx> OnUnimplementedDirective {
639641
AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span),
640642
};
641643

642-
tcx.emit_node_span_lint(
643-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
644-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
645-
report_span,
646-
MalformedOnUnimplementedAttrLint::new(report_span),
647-
);
644+
if let Some(item_def_id) = item_def_id.as_local() {
645+
tcx.emit_node_span_lint(
646+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
647+
tcx.local_def_id_to_hir_id(item_def_id),
648+
report_span,
649+
MalformedOnUnimplementedAttrLint::new(report_span),
650+
);
651+
}
648652
Ok(None)
649653
}
650654
} else if is_diagnostic_namespace_variant {
651655
match &attr.kind {
652656
AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => {
653-
tcx.emit_node_span_lint(
654-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
655-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
656-
attr.span,
657-
MalformedOnUnimplementedAttrLint::new(attr.span),
658-
);
657+
if let Some(item_def_id) = item_def_id.as_local() {
658+
tcx.emit_node_span_lint(
659+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
660+
tcx.local_def_id_to_hir_id(item_def_id),
661+
attr.span,
662+
MalformedOnUnimplementedAttrLint::new(attr.span),
663+
);
664+
}
665+
}
666+
_ => {
667+
if let Some(item_def_id) = item_def_id.as_local() {
668+
tcx.emit_node_span_lint(
669+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
670+
tcx.local_def_id_to_hir_id(item_def_id),
671+
attr.span,
672+
MissingOptionsForOnUnimplementedAttr,
673+
)
674+
}
659675
}
660-
_ => tcx.emit_node_span_lint(
661-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
662-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
663-
attr.span,
664-
MissingOptionsForOnUnimplementedAttr,
665-
),
666676
};
667677

668678
Ok(None)
@@ -791,12 +801,14 @@ impl<'tcx> OnUnimplementedFormatString {
791801
|| format_spec.precision_span.is_some()
792802
|| format_spec.fill_span.is_some())
793803
{
794-
tcx.emit_node_span_lint(
795-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
796-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
797-
self.span,
798-
InvalidFormatSpecifier,
799-
);
804+
if let Some(item_def_id) = item_def_id.as_local() {
805+
tcx.emit_node_span_lint(
806+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
807+
tcx.local_def_id_to_hir_id(item_def_id),
808+
self.span,
809+
InvalidFormatSpecifier,
810+
);
811+
}
800812
}
801813
match a.position {
802814
Position::ArgumentNamed(s) => {
@@ -812,15 +824,17 @@ impl<'tcx> OnUnimplementedFormatString {
812824
s if generics.params.iter().any(|param| param.name == s) => (),
813825
s => {
814826
if self.is_diagnostic_namespace_variant {
815-
tcx.emit_node_span_lint(
816-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
817-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
818-
self.span,
819-
UnknownFormatParameterForOnUnimplementedAttr {
820-
argument_name: s,
821-
trait_name,
822-
},
823-
);
827+
if let Some(item_def_id) = item_def_id.as_local() {
828+
tcx.emit_node_span_lint(
829+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
830+
tcx.local_def_id_to_hir_id(item_def_id),
831+
self.span,
832+
UnknownFormatParameterForOnUnimplementedAttr {
833+
argument_name: s,
834+
trait_name,
835+
},
836+
);
837+
}
824838
} else {
825839
result = Err(struct_span_code_err!(
826840
tcx.dcx(),
@@ -842,12 +856,14 @@ impl<'tcx> OnUnimplementedFormatString {
842856
// `{:1}` and `{}` are not to be used
843857
Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => {
844858
if self.is_diagnostic_namespace_variant {
845-
tcx.emit_node_span_lint(
846-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
847-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
848-
self.span,
849-
DisallowedPositionalArgument,
850-
);
859+
if let Some(item_def_id) = item_def_id.as_local() {
860+
tcx.emit_node_span_lint(
861+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
862+
tcx.local_def_id_to_hir_id(item_def_id),
863+
self.span,
864+
DisallowedPositionalArgument,
865+
);
866+
}
851867
} else {
852868
let reported = struct_span_code_err!(
853869
tcx.dcx(),
@@ -870,12 +886,14 @@ impl<'tcx> OnUnimplementedFormatString {
870886
// so that users are aware that something is not correct
871887
for e in parser.errors {
872888
if self.is_diagnostic_namespace_variant {
873-
tcx.emit_node_span_lint(
874-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
875-
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
876-
self.span,
877-
WrappedParserError { description: e.description, label: e.label },
878-
);
889+
if let Some(item_def_id) = item_def_id.as_local() {
890+
tcx.emit_node_span_lint(
891+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
892+
tcx.local_def_id_to_hir_id(item_def_id),
893+
self.span,
894+
WrappedParserError { description: e.description, label: e.label },
895+
);
896+
}
879897
} else {
880898
let reported =
881899
struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,).emit();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
error[E0277]: the trait bound `(): bad_on_unimplemented::MissingAttr` is not satisfied
2+
--> $DIR/malformed_foreign_on_unimplemented.rs:22:18
3+
|
4+
LL | missing_attr(());
5+
| ------------ ^^ the trait `bad_on_unimplemented::MissingAttr` is not implemented for `()`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
note: required by a bound in `missing_attr`
10+
--> $DIR/malformed_foreign_on_unimplemented.rs:11:20
11+
|
12+
LL | fn missing_attr<T: MissingAttr>(_: T) {}
13+
| ^^^^^^^^^^^ required by this bound in `missing_attr`
14+
15+
error[E0277]: the trait bound `(): bad_on_unimplemented::DuplicateAttr` is not satisfied
16+
--> $DIR/malformed_foreign_on_unimplemented.rs:23:20
17+
|
18+
LL | duplicate_attr(());
19+
| -------------- ^^ a
20+
| |
21+
| required by a bound introduced by this call
22+
|
23+
= help: the trait `bad_on_unimplemented::DuplicateAttr` is not implemented for `()`
24+
note: required by a bound in `duplicate_attr`
25+
--> $DIR/malformed_foreign_on_unimplemented.rs:12:22
26+
|
27+
LL | fn duplicate_attr<T: DuplicateAttr>(_: T) {}
28+
| ^^^^^^^^^^^^^ required by this bound in `duplicate_attr`
29+
30+
error[E0277]: the trait bound `(): bad_on_unimplemented::NotMetaList` is not satisfied
31+
--> $DIR/malformed_foreign_on_unimplemented.rs:24:19
32+
|
33+
LL | not_meta_list(());
34+
| ------------- ^^ the trait `bad_on_unimplemented::NotMetaList` is not implemented for `()`
35+
| |
36+
| required by a bound introduced by this call
37+
|
38+
note: required by a bound in `not_meta_list`
39+
--> $DIR/malformed_foreign_on_unimplemented.rs:13:21
40+
|
41+
LL | fn not_meta_list<T: NotMetaList>(_: T) {}
42+
| ^^^^^^^^^^^ required by this bound in `not_meta_list`
43+
44+
error[E0277]: the trait bound `(): bad_on_unimplemented::Empty` is not satisfied
45+
--> $DIR/malformed_foreign_on_unimplemented.rs:25:11
46+
|
47+
LL | empty(());
48+
| ----- ^^ the trait `bad_on_unimplemented::Empty` is not implemented for `()`
49+
| |
50+
| required by a bound introduced by this call
51+
|
52+
note: required by a bound in `empty`
53+
--> $DIR/malformed_foreign_on_unimplemented.rs:14:13
54+
|
55+
LL | fn empty<T: Empty>(_: T) {}
56+
| ^^^^^ required by this bound in `empty`
57+
58+
error[E0277]: the trait bound `(): bad_on_unimplemented::WrongDelim` is not satisfied
59+
--> $DIR/malformed_foreign_on_unimplemented.rs:26:17
60+
|
61+
LL | wrong_delim(());
62+
| ----------- ^^ the trait `bad_on_unimplemented::WrongDelim` is not implemented for `()`
63+
| |
64+
| required by a bound introduced by this call
65+
|
66+
note: required by a bound in `wrong_delim`
67+
--> $DIR/malformed_foreign_on_unimplemented.rs:15:19
68+
|
69+
LL | fn wrong_delim<T: WrongDelim>(_: T) {}
70+
| ^^^^^^^^^^ required by this bound in `wrong_delim`
71+
72+
error[E0277]: the trait bound `(): bad_on_unimplemented::BadFormatter<()>` is not satisfied
73+
--> $DIR/malformed_foreign_on_unimplemented.rs:27:19
74+
|
75+
LL | bad_formatter(());
76+
| ------------- ^^ ()
77+
| |
78+
| required by a bound introduced by this call
79+
|
80+
= help: the trait `bad_on_unimplemented::BadFormatter<()>` is not implemented for `()`
81+
note: required by a bound in `bad_formatter`
82+
--> $DIR/malformed_foreign_on_unimplemented.rs:16:21
83+
|
84+
LL | fn bad_formatter<T: BadFormatter<()>>(_: T) {}
85+
| ^^^^^^^^^^^^^^^^ required by this bound in `bad_formatter`
86+
87+
error[E0277]: the trait bound `(): bad_on_unimplemented::NoImplicitArgs` is not satisfied
88+
--> $DIR/malformed_foreign_on_unimplemented.rs:28:22
89+
|
90+
LL | no_implicit_args(());
91+
| ---------------- ^^ test {}
92+
| |
93+
| required by a bound introduced by this call
94+
|
95+
= help: the trait `bad_on_unimplemented::NoImplicitArgs` is not implemented for `()`
96+
note: required by a bound in `no_implicit_args`
97+
--> $DIR/malformed_foreign_on_unimplemented.rs:17:24
98+
|
99+
LL | fn no_implicit_args<T: NoImplicitArgs>(_: T) {}
100+
| ^^^^^^^^^^^^^^ required by this bound in `no_implicit_args`
101+
102+
error[E0277]: the trait bound `(): bad_on_unimplemented::MissingArg` is not satisfied
103+
--> $DIR/malformed_foreign_on_unimplemented.rs:29:17
104+
|
105+
LL | missing_arg(());
106+
| ----------- ^^ {missing}
107+
| |
108+
| required by a bound introduced by this call
109+
|
110+
= help: the trait `bad_on_unimplemented::MissingArg` is not implemented for `()`
111+
note: required by a bound in `missing_arg`
112+
--> $DIR/malformed_foreign_on_unimplemented.rs:18:19
113+
|
114+
LL | fn missing_arg<T: MissingArg>(_: T) {}
115+
| ^^^^^^^^^^ required by this bound in `missing_arg`
116+
117+
error[E0277]: the trait bound `(): bad_on_unimplemented::BadArg` is not satisfied
118+
--> $DIR/malformed_foreign_on_unimplemented.rs:30:13
119+
|
120+
LL | bad_arg(());
121+
| ------- ^^ {_}
122+
| |
123+
| required by a bound introduced by this call
124+
|
125+
= help: the trait `bad_on_unimplemented::BadArg` is not implemented for `()`
126+
note: required by a bound in `bad_arg`
127+
--> $DIR/malformed_foreign_on_unimplemented.rs:19:15
128+
|
129+
LL | fn bad_arg<T: BadArg>(_: T) {}
130+
| ^^^^^^ required by this bound in `bad_arg`
131+
132+
error: aborting due to 9 previous errors
133+
134+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)