Skip to content

Commit ca3f5ae

Browse files
committed
Write the format string parserand split it from conditions parser
1 parent 199ee40 commit ca3f5ae

File tree

11 files changed

+614
-360
lines changed

11 files changed

+614
-360
lines changed

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ symbols! {
372372
SyncUnsafeCell,
373373
T,
374374
Target,
375+
This,
375376
ToOwned,
376377
ToString,
377378
TokenStream,
@@ -2082,6 +2083,7 @@ symbols! {
20822083
test_removed_feature,
20832084
test_runner,
20842085
test_unstable_lint,
2086+
20852087
thread,
20862088
thread_local,
20872089
thread_local_macro,

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

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod ambiguity;
22
pub mod call_kind;
33
mod fulfillment_errors;
44
pub mod on_unimplemented;
5+
pub mod on_unimplemented_condition;
56
pub mod on_unimplemented_format;
67
mod overflow;
78
pub mod suggestions;

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

+119-280
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use rustc_ast::MetaItemInner;
2+
use rustc_attr_parsing as attr;
3+
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_middle::ty::{self, TyCtxt};
5+
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
6+
use rustc_span::{Span, Symbol, sym};
7+
8+
pub static ALLOWED_CONDITION_SYMBOLS: &[Symbol] = &[
9+
sym::from_desugaring,
10+
sym::direct,
11+
sym::cause,
12+
sym::integral,
13+
sym::integer_,
14+
sym::float,
15+
sym::_Self,
16+
sym::crate_local,
17+
];
18+
19+
#[derive(Debug)]
20+
pub struct Condition {
21+
pub inner: MetaItemInner,
22+
}
23+
24+
impl Condition {
25+
pub fn span(&self) -> Span {
26+
self.inner.span()
27+
}
28+
29+
pub fn matches_predicate<'tcx>(
30+
&self,
31+
tcx: TyCtxt<'tcx>,
32+
options: &[(Symbol, Option<String>)],
33+
options_map: &FxHashMap<Symbol, String>,
34+
) -> bool {
35+
attr::eval_condition(&self.inner, tcx.sess, Some(tcx.features()), &mut |cfg| {
36+
let value = cfg.value.map(|v| {
37+
// `with_no_visible_paths` is also used when generating the options,
38+
// so we need to match it here.
39+
ty::print::with_no_visible_paths!({
40+
let mut parser = Parser::new(v.as_str(), None, None, false, ParseMode::Format);
41+
let constructed_message = (&mut parser)
42+
.map(|p| match p {
43+
Piece::Lit(s) => s.to_owned(),
44+
Piece::NextArgument(a) => match a.position {
45+
Position::ArgumentNamed(arg) => {
46+
let s = Symbol::intern(arg);
47+
match options_map.get(&s) {
48+
Some(val) => val.to_string(),
49+
None => format!("{{{arg}}}"),
50+
}
51+
}
52+
Position::ArgumentImplicitlyIs(_) => String::from("{}"),
53+
Position::ArgumentIs(idx) => format!("{{{idx}}}"),
54+
},
55+
})
56+
.collect();
57+
constructed_message
58+
})
59+
});
60+
61+
options.contains(&(cfg.name, value))
62+
})
63+
}
64+
}

0 commit comments

Comments
 (0)