@@ -62,6 +62,10 @@ impl<'tcx> OnUnimplementedDirective {
6262 let mut errored = false;
6363 let mut item_iter = items.iter();
6464
65+ let parse_value = |value_str| {
66+ OnUnimplementedFormatString::try_parse(tcx, trait_def_id, value_str, span).map(Some)
67+ };
68+
6569 let condition = if is_root {
6670 None
6771 } else {
@@ -86,7 +90,14 @@ impl<'tcx> OnUnimplementedDirective {
8690 None,
8791 )
8892 })?;
89- attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |_| true);
93+ attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| {
94+ if let Some(symbol) = item.value_str() {
95+ if parse_value(symbol).is_err() {
96+ errored = true;
97+ }
98+ }
99+ true
100+ });
90101 Some(cond.clone())
91102 };
92103
@@ -97,10 +108,6 @@ impl<'tcx> OnUnimplementedDirective {
97108 let mut subcommands = vec![];
98109 let mut append_const_msg = None;
99110
100- let parse_value = |value_str| {
101- OnUnimplementedFormatString::try_parse(tcx, trait_def_id, value_str, span).map(Some)
102- };
103-
104111 for item in item_iter {
105112 if item.has_name(sym::message) && message.is_none() {
106113 if let Some(message_) = item.value_str() {
@@ -221,6 +228,9 @@ impl<'tcx> OnUnimplementedDirective {
221228 let mut append_const_msg = None;
222229 info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
223230
231+ let options_map: FxHashMap<Symbol, String> =
232+ options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect();
233+
224234 for command in self.subcommands.iter().chain(Some(self)).rev() {
225235 if let Some(ref condition) = command.condition {
226236 if !attr::eval_condition(
@@ -229,7 +239,11 @@ impl<'tcx> OnUnimplementedDirective {
229239 Some(tcx.features()),
230240 &mut |c| {
231241 c.ident().map_or(false, |ident| {
232- options.contains(&(ident.name, c.value_str().map(|s| s.to_string())))
242+ let value = c.value_str().map(|s| {
243+ OnUnimplementedFormatString(s).format(tcx, trait_ref, &options_map)
244+ });
245+
246+ options.contains(&(ident.name, value))
233247 })
234248 },
235249 ) {
@@ -257,13 +271,11 @@ impl<'tcx> OnUnimplementedDirective {
257271 append_const_msg = command.append_const_msg.clone();
258272 }
259273
260- let options: FxHashMap<Symbol, String> =
261- options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect();
262274 OnUnimplementedNote {
263- label: label.map(|l| l.format(tcx, trait_ref, &options )),
264- message: message.map(|m| m.format(tcx, trait_ref, &options )),
265- note: note.map(|n| n.format(tcx, trait_ref, &options )),
266- enclosing_scope: enclosing_scope.map(|e_s| e_s.format(tcx, trait_ref, &options )),
275+ label: label.map(|l| l.format(tcx, trait_ref, &options_map )),
276+ message: message.map(|m| m.format(tcx, trait_ref, &options_map )),
277+ note: note.map(|n| n.format(tcx, trait_ref, &options_map )),
278+ enclosing_scope: enclosing_scope.map(|e_s| e_s.format(tcx, trait_ref, &options_map )),
267279 append_const_msg,
268280 }
269281 }
@@ -306,6 +318,12 @@ impl<'tcx> OnUnimplementedFormatString {
306318 Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
307319 // `{ItemContext}` is allowed
308320 Position::ArgumentNamed(s) if s == sym::ItemContext => (),
321+ // `{integral}` and `{integer}` and `{float}` are allowed
322+ Position::ArgumentNamed(s)
323+ if s == sym::integral || s == sym::integer_ || s == sym::float =>
324+ {
325+ ()
326+ }
309327 // So is `{A}` if A is a type parameter
310328 Position::ArgumentNamed(s) => {
311329 match generics.params.iter().find(|param| param.name == s) {
@@ -385,6 +403,12 @@ impl<'tcx> OnUnimplementedFormatString {
385403 &empty_string
386404 } else if s == sym::ItemContext {
387405 &item_context
406+ } else if s == sym::integral {
407+ "{integral}"
408+ } else if s == sym::integer_ {
409+ "{integer}"
410+ } else if s == sym::float {
411+ "{float}"
388412 } else {
389413 bug!(
390414 "broken on_unimplemented {:?} for {:?}: \
0 commit comments