]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_errors/src/tests.rs
Rollup merge of #106703 - compiler-errors:impl-derived-span, r=estebank
[rust.git] / compiler / rustc_errors / src / tests.rs
1 use crate::error::{TranslateError, TranslateErrorKind};
2 use crate::fluent_bundle::*;
3 use crate::translation::Translate;
4 use crate::FluentBundle;
5 use rustc_data_structures::sync::Lrc;
6 use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError};
7 use rustc_error_messages::langid;
8 use rustc_error_messages::DiagnosticMessage;
9
10 struct Dummy {
11     bundle: FluentBundle,
12 }
13
14 impl Translate for Dummy {
15     fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
16         None
17     }
18
19     fn fallback_fluent_bundle(&self) -> &FluentBundle {
20         &self.bundle
21     }
22 }
23
24 fn make_dummy(ftl: &'static str) -> Dummy {
25     let resource = FluentResource::try_new(ftl.into()).expect("Failed to parse an FTL string.");
26
27     let langid_en = langid!("en-US");
28
29     #[cfg(parallel_compiler)]
30     let mut bundle = FluentBundle::new_concurrent(vec![langid_en]);
31
32     #[cfg(not(parallel_compiler))]
33     let mut bundle = FluentBundle::new(vec![langid_en]);
34
35     bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle.");
36
37     Dummy { bundle }
38 }
39
40 #[test]
41 fn wellformed_fluent() {
42     let dummy = make_dummy("mir_build_borrow_of_moved_value = borrow of moved value
43     .label = value moved into `{$name}` here
44     .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait
45     .value_borrowed_label = value borrowed here after move
46     .suggestion = borrow this binding in the pattern to avoid moving the value");
47
48     let mut args = FluentArgs::new();
49     args.set("name", "Foo");
50     args.set("ty", "std::string::String");
51     {
52         let message = DiagnosticMessage::FluentIdentifier(
53             "mir_build_borrow_of_moved_value".into(),
54             Some("suggestion".into()),
55         );
56
57         assert_eq!(
58             dummy.translate_message(&message, &args).unwrap(),
59             "borrow this binding in the pattern to avoid moving the value"
60         );
61     }
62
63     {
64         let message = DiagnosticMessage::FluentIdentifier(
65             "mir_build_borrow_of_moved_value".into(),
66             Some("value_borrowed_label".into()),
67         );
68
69         assert_eq!(
70             dummy.translate_message(&message, &args).unwrap(),
71             "value borrowed here after move"
72         );
73     }
74
75     {
76         let message = DiagnosticMessage::FluentIdentifier(
77             "mir_build_borrow_of_moved_value".into(),
78             Some("occurs_because_label".into()),
79         );
80
81         assert_eq!(
82             dummy.translate_message(&message, &args).unwrap(),
83             "move occurs because `\u{2068}Foo\u{2069}` has type `\u{2068}std::string::String\u{2069}` which does not implement the `Copy` trait"
84         );
85
86         {
87             let message = DiagnosticMessage::FluentIdentifier(
88                 "mir_build_borrow_of_moved_value".into(),
89                 Some("label".into()),
90             );
91
92             assert_eq!(
93                 dummy.translate_message(&message, &args).unwrap(),
94                 "value moved into `\u{2068}Foo\u{2069}` here"
95             );
96         }
97     }
98 }
99
100 #[test]
101 fn misformed_fluent() {
102     let dummy = make_dummy("mir_build_borrow_of_moved_value = borrow of moved value
103     .label = value moved into `{name}` here
104     .occurs_because_label = move occurs because `{$oops}` has type `{$ty}` which does not implement the `Copy` trait
105     .suggestion = borrow this binding in the pattern to avoid moving the value");
106
107     let mut args = FluentArgs::new();
108     args.set("name", "Foo");
109     args.set("ty", "std::string::String");
110     {
111         let message = DiagnosticMessage::FluentIdentifier(
112             "mir_build_borrow_of_moved_value".into(),
113             Some("value_borrowed_label".into()),
114         );
115
116         let err = dummy.translate_message(&message, &args).unwrap_err();
117         assert!(
118             matches!(
119                 &err,
120                 TranslateError::Two {
121                     primary: box TranslateError::One {
122                         kind: TranslateErrorKind::PrimaryBundleMissing,
123                         ..
124                     },
125                     fallback: box TranslateError::One {
126                         kind: TranslateErrorKind::AttributeMissing { attr: "value_borrowed_label" },
127                         ..
128                     }
129                 }
130             ),
131             "{err:#?}"
132         );
133         assert_eq!(
134             format!("{err}"),
135             "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nthe attribute `value_borrowed_label` was missing\nhelp: add `.value_borrowed_label = <message>`\n"
136         );
137     }
138
139     {
140         let message = DiagnosticMessage::FluentIdentifier(
141             "mir_build_borrow_of_moved_value".into(),
142             Some("label".into()),
143         );
144
145         let err = dummy.translate_message(&message, &args).unwrap_err();
146         if let TranslateError::Two {
147             primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. },
148             fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. },
149         } = &err
150             && let [FluentError::ResolverError(ResolverError::Reference(
151                 ReferenceKind::Message { id, .. }
152                     | ReferenceKind::Variable { id, .. },
153             ))] = &**errs
154             && id == "name"
155         {} else {
156             panic!("{err:#?}")
157         };
158         assert_eq!(
159             format!("{err}"),
160             "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nargument `name` exists but was not referenced correctly\nhelp: try using `{$name}` instead\n"
161         );
162     }
163
164     {
165         let message = DiagnosticMessage::FluentIdentifier(
166             "mir_build_borrow_of_moved_value".into(),
167             Some("occurs_because_label".into()),
168         );
169
170         let err = dummy.translate_message(&message, &args).unwrap_err();
171         if let TranslateError::Two {
172             primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. },
173             fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. },
174         } = &err
175             && let [FluentError::ResolverError(ResolverError::Reference(
176                 ReferenceKind::Message { id, .. }
177                     | ReferenceKind::Variable { id, .. },
178             ))] = &**errs
179             && id == "oops"
180         {} else {
181             panic!("{err:#?}")
182         };
183         assert_eq!(
184             format!("{err}"),
185             "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nthe fluent string has an argument `oops` that was not found.\nhelp: the arguments `name` and `ty` are available\n"
186         );
187     }
188 }