Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Diagnostic args are still args if they're documented
  • Loading branch information
compiler-errors committed May 8, 2023
commit 2b9279f3131056a1a1dd5de7513de4eb98987770
12 changes: 5 additions & 7 deletions compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ use crate::diagnostics::error::{
invalid_attr, span_err, throw_invalid_attr, throw_span_err, DiagnosticDeriveError,
};
use crate::diagnostics::utils::{
build_field_mapping, is_doc_comment, new_code_ident,
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo,
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
build_field_mapping, build_suggestion_code, is_doc_comment, new_code_ident,
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span,
should_generate_set_arg, AllowMultipleAlternatives, FieldInfo, FieldInnerTy, FieldMap,
HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::{spanned::Spanned, Attribute, Meta, MetaList, Path};
use synstructure::{BindingInfo, Structure, VariantInfo};

use super::utils::{build_suggestion_code, AllowMultipleAlternatives};

/// The central struct for constructing the `add_to_diagnostic` method from an annotated struct.
pub(crate) struct SubdiagnosticDeriveBuilder {
diag: syn::Ident,
Expand Down Expand Up @@ -212,7 +211,6 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
/// Generates the code for a field with no attributes.
fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
let ast = binding.ast();
assert_eq!(ast.attrs.len(), 0, "field with attribute used as diagnostic arg");

let diag = &self.parent.diag;
let ident = ast.ident.as_ref().unwrap();
Expand Down Expand Up @@ -580,7 +578,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
.variant
.bindings()
.iter()
.filter(|binding| binding.ast().attrs.is_empty())
.filter(|binding| should_generate_set_arg(binding.ast()))
.map(|binding| self.generate_field_set_arg(binding))
.collect();

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,8 @@ impl quote::IdentFragment for SubdiagnosticKind {
/// Returns `true` if `field` should generate a `set_arg` call rather than any other diagnostic
/// call (like `span_label`).
pub(super) fn should_generate_set_arg(field: &Field) -> bool {
field.attrs.is_empty()
// Perhaps this should be an exhaustive list...
field.attrs.iter().all(|attr| is_doc_comment(attr))
}

pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// check-fail
// Tests that a doc comment will not preclude a field from being considered a diagnostic argument

// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler
// the test is just ignored on stable and beta:
// ignore-stage1
// ignore-beta
// ignore-stable

#![feature(rustc_private)]
#![crate_type = "lib"]

extern crate rustc_errors;
extern crate rustc_fluent_macro;
extern crate rustc_macros;
extern crate rustc_session;
extern crate rustc_span;

use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;

fluent_messages! { "./example.ftl" }

struct NotIntoDiagnosticArg;

#[derive(Diagnostic)]
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
#[diag(no_crate_example)]
struct Test {
#[primary_span]
span: Span,
/// A doc comment
arg: NotIntoDiagnosticArg,
}

#[derive(Subdiagnostic)]
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
#[label(no_crate_example)]
struct SubTest {
#[primary_span]
span: Span,
/// A doc comment
arg: NotIntoDiagnosticArg,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
--> $DIR/diagnostic-derive-doc-comment-field.rs:29:10
|
LL | #[derive(Diagnostic)]
| ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
|
= help: the following other types implement trait `IntoDiagnosticArg`:
&'a T
&'a std::path::Path
&'a str
&rustc_target::spec::TargetTriple
Box<(dyn std::error::Error + 'static)>
CString
CguReuse
Cow<'a, str>
and 42 others
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:747:5
= note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
--> $DIR/diagnostic-derive-doc-comment-field.rs:39:10
|
LL | #[derive(Subdiagnostic)]
| ^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
|
= help: the following other types implement trait `IntoDiagnosticArg`:
&'a T
&'a std::path::Path
&'a str
&rustc_target::spec::TargetTriple
Box<(dyn std::error::Error + 'static)>
CString
CguReuse
Cow<'a, str>
and 42 others
note: required by a bound in `Diagnostic::set_arg`
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:964:5
= note: this error originates in the derive macro `Subdiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.