|
1 | 1 | use super::{ObligationCauseCode, PredicateObligation};
|
2 | 2 | use crate::infer::error_reporting::TypeErrCtxt;
|
3 |
| -use rustc_ast::{MetaItem, NestedMetaItem}; |
| 3 | +use rustc_ast::{Attribute, MetaItem, NestedMetaItem}; |
4 | 4 | use rustc_attr as attr;
|
5 | 5 | use rustc_data_structures::fx::FxHashMap;
|
6 | 6 | use rustc_errors::{struct_span_err, ErrorGuaranteed};
|
@@ -474,18 +474,40 @@ impl<'tcx> OnUnimplementedDirective {
|
474 | 474 | }
|
475 | 475 |
|
476 | 476 | pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<Option<Self>, ErrorGuaranteed> {
|
477 |
| - let mut is_diagnostic_namespace_variant = false; |
478 |
| - let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented).or_else(|| { |
479 |
| - if tcx.features().diagnostic_namespace { |
480 |
| - is_diagnostic_namespace_variant = true; |
481 |
| - tcx.get_attrs_by_path(item_def_id, &[sym::diagnostic, sym::on_unimplemented]).next() |
482 |
| - } else { |
483 |
| - None |
484 |
| - } |
485 |
| - }) else { |
486 |
| - return Ok(None); |
487 |
| - }; |
| 477 | + if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) { |
| 478 | + return Self::parse_attribute(attr, false, tcx, item_def_id); |
| 479 | + } else if tcx.features().diagnostic_namespace { |
| 480 | + tcx.get_attrs_by_path(item_def_id, &[sym::diagnostic, sym::on_unimplemented]) |
| 481 | + .filter_map(|attr| Self::parse_attribute(attr, true, tcx, item_def_id).transpose()) |
| 482 | + .try_fold(None, |aggr: Option<Self>, directive| { |
| 483 | + let directive = directive?; |
| 484 | + if let Some(aggr) = aggr { |
| 485 | + let mut subcommands = aggr.subcommands; |
| 486 | + subcommands.extend(directive.subcommands); |
| 487 | + Ok(Some(Self { |
| 488 | + condition: aggr.condition.or(directive.condition), |
| 489 | + subcommands, |
| 490 | + message: aggr.message.or(directive.message), |
| 491 | + label: aggr.label.or(directive.label), |
| 492 | + note: aggr.note.or(directive.note), |
| 493 | + parent_label: aggr.parent_label.or(directive.parent_label), |
| 494 | + append_const_msg: aggr.append_const_msg.or(directive.append_const_msg), |
| 495 | + })) |
| 496 | + } else { |
| 497 | + Ok(Some(directive)) |
| 498 | + } |
| 499 | + }) |
| 500 | + } else { |
| 501 | + Ok(None) |
| 502 | + } |
| 503 | + } |
488 | 504 |
|
| 505 | + fn parse_attribute( |
| 506 | + attr: &Attribute, |
| 507 | + is_diagnostic_namespace_variant: bool, |
| 508 | + tcx: TyCtxt<'tcx>, |
| 509 | + item_def_id: DefId, |
| 510 | + ) -> Result<Option<Self>, ErrorGuaranteed> { |
489 | 511 | let result = if let Some(items) = attr.meta_item_list() {
|
490 | 512 | Self::parse(tcx, item_def_id, &items, attr.span, true, is_diagnostic_namespace_variant)
|
491 | 513 | } else if let Some(value) = attr.value_str() {
|
|
0 commit comments