File: diagnostics.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (127 lines) | stat: -rw-r--r-- 4,329 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//@ compile-flags: -Z unstable-options
//@ ignore-stage1

#![crate_type = "lib"]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

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

use rustc_errors::{
    Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level,
    LintDiagnostic, SubdiagMessage, SubdiagMessageOp, Subdiagnostic,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;

rustc_fluent_macro::fluent_messages! { "./diagnostics.ftl" }

#[derive(Diagnostic)]
#[diag(no_crate_example)]
struct DeriveDiagnostic {
    #[primary_span]
    span: Span,
}

#[derive(Subdiagnostic)]
#[note(no_crate_example)]
struct Note {
    #[primary_span]
    span: Span,
}

pub struct UntranslatableInDiagnostic;

impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UntranslatableInDiagnostic {
    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
        Diag::new(dcx, level, "untranslatable diagnostic")
        //~^ ERROR diagnostics should be created using translatable messages
    }
}

pub struct TranslatableInDiagnostic;

impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for TranslatableInDiagnostic {
    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
        Diag::new(dcx, level, crate::fluent_generated::no_crate_example)
    }
}

pub struct UntranslatableInAddtoDiag;

impl Subdiagnostic for UntranslatableInAddtoDiag {
    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
        self,
        diag: &mut Diag<'_, G>,
        f: &F,
    ) {
        diag.note("untranslatable diagnostic");
        //~^ ERROR diagnostics should be created using translatable messages
    }
}

pub struct TranslatableInAddtoDiag;

impl Subdiagnostic for TranslatableInAddtoDiag {
    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
        self,
        diag: &mut Diag<'_, G>,
        f: &F,
    ) {
        diag.note(crate::fluent_generated::no_crate_note);
    }
}

pub struct UntranslatableInLintDiagnostic;

impl<'a> LintDiagnostic<'a, ()> for UntranslatableInLintDiagnostic {
    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
        diag.note("untranslatable diagnostic");
        //~^ ERROR diagnostics should be created using translatable messages
    }
}

pub struct TranslatableInLintDiagnostic;

impl<'a> LintDiagnostic<'a, ()> for TranslatableInLintDiagnostic {
    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
        diag.note(crate::fluent_generated::no_crate_note);
    }
}

pub fn make_diagnostics<'a>(dcx: DiagCtxtHandle<'a>) {
    let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
    //~^ ERROR diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls

    let _diag = dcx.struct_err("untranslatable diagnostic");
    //~^ ERROR diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
    //~^^ ERROR diagnostics should be created using translatable messages
}

// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted for
// `diagnostic_outside_of_impl`.
#[rustc_lint_diagnostics]
pub fn skipped_because_of_annotation<'a>(dcx: DiagCtxtHandle<'a>) {
    #[allow(rustc::untranslatable_diagnostic)]
    let _diag = dcx.struct_err("untranslatable diagnostic"); // okay!
}

// Check that multiple translatable params are allowed in a single function (at one point they
// weren't).
fn f(_x: impl Into<DiagMessage>, _y: impl Into<SubdiagMessage>) {}
fn g() {
    f(crate::fluent_generated::no_crate_example, crate::fluent_generated::no_crate_example);
    f("untranslatable diagnostic", crate::fluent_generated::no_crate_example);
    //~^ ERROR diagnostics should be created using translatable messages
    f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic");
    //~^ ERROR diagnostics should be created using translatable messages
    f("untranslatable diagnostic", "untranslatable diagnostic");
    //~^ ERROR diagnostics should be created using translatable messages
    //~^^ ERROR diagnostics should be created using translatable messages
}