Fix ICEs in diagnostic::on_unimplemented

This commit is contained in:
Michael Goulet 2024-05-07 23:12:36 -04:00
parent a8f2e33eec
commit 7dbdbaaa8e
2 changed files with 203 additions and 51 deletions

View file

@ -350,12 +350,14 @@ fn maybe_emit_warning<'tcx>(
option_name: &'static str,
) {
if let (Some(new_item), Some(old_item)) = (new, old) {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
}
}
}
}
@ -639,30 +641,38 @@ fn parse_attribute(
AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span),
};
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
report_span,
MalformedOnUnimplementedAttrLint::new(report_span),
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
report_span,
MalformedOnUnimplementedAttrLint::new(report_span),
);
}
Ok(None)
}
} else if is_diagnostic_namespace_variant {
match &attr.kind {
AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
attr.span,
MalformedOnUnimplementedAttrLint::new(attr.span),
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span,
MalformedOnUnimplementedAttrLint::new(attr.span),
);
}
}
_ => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span,
MissingOptionsForOnUnimplementedAttr,
)
}
}
_ => tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
attr.span,
MissingOptionsForOnUnimplementedAttr,
),
};
Ok(None)
@ -791,12 +801,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara
|| format_spec.precision_span.is_some()
|| format_spec.fill_span.is_some())
{
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
InvalidFormatSpecifier,
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
InvalidFormatSpecifier,
);
}
}
match a.position {
Position::ArgumentNamed(s) => {
@ -812,15 +824,17 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara
s if generics.params.iter().any(|param| param.name == s) => (),
s => {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
UnknownFormatParameterForOnUnimplementedAttr {
argument_name: s,
trait_name,
},
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
UnknownFormatParameterForOnUnimplementedAttr {
argument_name: s,
trait_name,
},
);
}
} else {
result = Err(struct_span_code_err!(
tcx.dcx(),
@ -842,12 +856,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara
// `{:1}` and `{}` are not to be used
Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
DisallowedPositionalArgument,
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
DisallowedPositionalArgument,
);
}
} else {
let reported = struct_span_code_err!(
tcx.dcx(),
@ -870,12 +886,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara
// so that users are aware that something is not correct
for e in parser.errors {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
WrappedParserError { description: e.description, label: e.label },
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
WrappedParserError { description: e.description, label: e.label },
);
}
} else {
let reported =
struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,).emit();

View file

@ -0,0 +1,134 @@
error[E0277]: the trait bound `(): bad_on_unimplemented::MissingAttr` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:22:18
|
LL | missing_attr(());
| ------------ ^^ the trait `bad_on_unimplemented::MissingAttr` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `missing_attr`
--> $DIR/malformed_foreign_on_unimplemented.rs:11:20
|
LL | fn missing_attr<T: MissingAttr>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `missing_attr`
error[E0277]: the trait bound `(): bad_on_unimplemented::DuplicateAttr` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:23:20
|
LL | duplicate_attr(());
| -------------- ^^ a
| |
| required by a bound introduced by this call
|
= help: the trait `bad_on_unimplemented::DuplicateAttr` is not implemented for `()`
note: required by a bound in `duplicate_attr`
--> $DIR/malformed_foreign_on_unimplemented.rs:12:22
|
LL | fn duplicate_attr<T: DuplicateAttr>(_: T) {}
| ^^^^^^^^^^^^^ required by this bound in `duplicate_attr`
error[E0277]: the trait bound `(): bad_on_unimplemented::NotMetaList` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:24:19
|
LL | not_meta_list(());
| ------------- ^^ the trait `bad_on_unimplemented::NotMetaList` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `not_meta_list`
--> $DIR/malformed_foreign_on_unimplemented.rs:13:21
|
LL | fn not_meta_list<T: NotMetaList>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `not_meta_list`
error[E0277]: the trait bound `(): bad_on_unimplemented::Empty` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:25:11
|
LL | empty(());
| ----- ^^ the trait `bad_on_unimplemented::Empty` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `empty`
--> $DIR/malformed_foreign_on_unimplemented.rs:14:13
|
LL | fn empty<T: Empty>(_: T) {}
| ^^^^^ required by this bound in `empty`
error[E0277]: the trait bound `(): bad_on_unimplemented::WrongDelim` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:26:17
|
LL | wrong_delim(());
| ----------- ^^ the trait `bad_on_unimplemented::WrongDelim` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `wrong_delim`
--> $DIR/malformed_foreign_on_unimplemented.rs:15:19
|
LL | fn wrong_delim<T: WrongDelim>(_: T) {}
| ^^^^^^^^^^ required by this bound in `wrong_delim`
error[E0277]: the trait bound `(): bad_on_unimplemented::BadFormatter<()>` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:27:19
|
LL | bad_formatter(());
| ------------- ^^ ()
| |
| required by a bound introduced by this call
|
= help: the trait `bad_on_unimplemented::BadFormatter<()>` is not implemented for `()`
note: required by a bound in `bad_formatter`
--> $DIR/malformed_foreign_on_unimplemented.rs:16:21
|
LL | fn bad_formatter<T: BadFormatter<()>>(_: T) {}
| ^^^^^^^^^^^^^^^^ required by this bound in `bad_formatter`
error[E0277]: the trait bound `(): bad_on_unimplemented::NoImplicitArgs` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:28:22
|
LL | no_implicit_args(());
| ---------------- ^^ test {}
| |
| required by a bound introduced by this call
|
= help: the trait `bad_on_unimplemented::NoImplicitArgs` is not implemented for `()`
note: required by a bound in `no_implicit_args`
--> $DIR/malformed_foreign_on_unimplemented.rs:17:24
|
LL | fn no_implicit_args<T: NoImplicitArgs>(_: T) {}
| ^^^^^^^^^^^^^^ required by this bound in `no_implicit_args`
error[E0277]: the trait bound `(): bad_on_unimplemented::MissingArg` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:29:17
|
LL | missing_arg(());
| ----------- ^^ {missing}
| |
| required by a bound introduced by this call
|
= help: the trait `bad_on_unimplemented::MissingArg` is not implemented for `()`
note: required by a bound in `missing_arg`
--> $DIR/malformed_foreign_on_unimplemented.rs:18:19
|
LL | fn missing_arg<T: MissingArg>(_: T) {}
| ^^^^^^^^^^ required by this bound in `missing_arg`
error[E0277]: the trait bound `(): bad_on_unimplemented::BadArg` is not satisfied
--> $DIR/malformed_foreign_on_unimplemented.rs:30:13
|
LL | bad_arg(());
| ------- ^^ {_}
| |
| required by a bound introduced by this call
|
= help: the trait `bad_on_unimplemented::BadArg` is not implemented for `()`
note: required by a bound in `bad_arg`
--> $DIR/malformed_foreign_on_unimplemented.rs:19:15
|
LL | fn bad_arg<T: BadArg>(_: T) {}
| ^^^^^^ required by this bound in `bad_arg`
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0277`.