]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc/traits/on_unimplemented.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc / traits / on_unimplemented.rs
index b39c00a56e349ad13c5933b9f6e55c9f69d1b176..604f39dcf293b3503a82355461208a10251be27b 100644 (file)
@@ -10,6 +10,8 @@ use syntax::attr;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::Span;
 
+use rustc_error_codes::*;
+
 #[derive(Clone, Debug)]
 pub struct OnUnimplementedFormatString(Symbol);
 
@@ -20,18 +22,15 @@ pub struct OnUnimplementedDirective {
     pub message: Option<OnUnimplementedFormatString>,
     pub label: Option<OnUnimplementedFormatString>,
     pub note: Option<OnUnimplementedFormatString>,
+    pub enclosing_scope: Option<OnUnimplementedFormatString>,
 }
 
+#[derive(Default)]
 pub struct OnUnimplementedNote {
     pub message: Option<String>,
     pub label: Option<String>,
     pub note: Option<String>,
-}
-
-impl OnUnimplementedNote {
-    pub fn empty() -> Self {
-        OnUnimplementedNote { message: None, label: None, note: None }
-    }
+    pub enclosing_scope: Option<String>,
 }
 
 fn parse_error(
@@ -83,24 +82,33 @@ impl<'tcx> OnUnimplementedDirective {
         let mut message = None;
         let mut label = None;
         let mut note = None;
+        let mut enclosing_scope = None;
         let mut subcommands = vec![];
+
+        let parse_value = |value_str| {
+                OnUnimplementedFormatString::try_parse(tcx, trait_def_id, value_str, span)
+                    .map(Some)
+            };
+
         for item in item_iter {
             if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
-                    message = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, message_, span)?);
+                    message = parse_value(message_)?;
                     continue;
                 }
             } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
-                    label = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, label_, span)?);
+                    label = parse_value(label_)?;
                     continue;
                 }
             } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
-                    note = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, note_, span)?);
+                    note = parse_value(note_)?;
+                    continue;
+                }
+            } else if item.check_name(sym::enclosing_scope) && enclosing_scope.is_none() {
+                if let Some(enclosing_scope_) = item.value_str() {
+                    enclosing_scope = parse_value(enclosing_scope_)?;
                     continue;
                 }
             } else if item.check_name(sym::on) && is_root &&
@@ -128,7 +136,14 @@ impl<'tcx> OnUnimplementedDirective {
         if errored {
             Err(ErrorReported)
         } else {
-            Ok(OnUnimplementedDirective { condition, message, label, subcommands, note })
+            Ok(OnUnimplementedDirective {
+                condition,
+                subcommands,
+                message,
+                label,
+                note,
+                enclosing_scope
+            })
         }
     }
 
@@ -155,6 +170,7 @@ impl<'tcx> OnUnimplementedDirective {
                 label: Some(OnUnimplementedFormatString::try_parse(
                     tcx, trait_def_id, value, attr.span)?),
                 note: None,
+                enclosing_scope: None,
             }))
         } else {
             return Err(ErrorReported);
@@ -172,6 +188,7 @@ impl<'tcx> OnUnimplementedDirective {
         let mut message = None;
         let mut label = None;
         let mut note = None;
+        let mut enclosing_scope = None;
         info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
 
         for command in self.subcommands.iter().chain(Some(self)).rev() {
@@ -180,7 +197,7 @@ impl<'tcx> OnUnimplementedDirective {
                     c.ident().map_or(false, |ident| {
                         options.contains(&(
                             ident.name,
-                            c.value_str().map(|s| s.as_str().to_string())
+                            c.value_str().map(|s| s.to_string())
                         ))
                     })
                 }) {
@@ -200,6 +217,10 @@ impl<'tcx> OnUnimplementedDirective {
             if let Some(ref note_) = command.note {
                 note = Some(note_.clone());
             }
+
+            if let Some(ref enclosing_scope_) = command.enclosing_scope {
+                enclosing_scope = Some(enclosing_scope_.clone());
+            }
         }
 
         let options: FxHashMap<Symbol, String> = options.into_iter()
@@ -209,6 +230,7 @@ impl<'tcx> OnUnimplementedDirective {
             label: label.map(|l| l.format(tcx, trait_ref, &options)),
             message: message.map(|m| m.format(tcx, trait_ref, &options)),
             note: note.map(|n| n.format(tcx, trait_ref, &options)),
+            enclosing_scope: enclosing_scope.map(|e_s| e_s.format(tcx, trait_ref, &options)),
         }
     }
 }