]> git.lizzy.rs Git - rust.git/commitdiff
Various changes to `rustc_on_unimplemented`
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 12 Aug 2018 19:26:38 +0000 (12:26 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Sun, 12 Aug 2018 19:26:38 +0000 (12:26 -0700)
- Add `from_method` and `from_desugaring` to formatting options
- Change wording of errors slightly

src/librustc/traits/on_unimplemented.rs
src/test/ui/error-codes/E0232.stderr
src/test/ui/on-unimplemented/bad-annotation.rs
src/test/ui/on-unimplemented/bad-annotation.stderr

index e1395c3fa442723c2bba781ea5918aee35bd902d..280ce75720bcfef8d309c0caefbc6197b6648102 100644 (file)
@@ -131,7 +131,7 @@ pub fn parse(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             parse_error(tcx, item.span,
                         "this attribute must have a valid value",
                         "expected value here",
-                        Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#));
+                        Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#));
         }
 
         if errored {
@@ -170,7 +170,7 @@ pub fn of_item(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             return Err(parse_error(tcx, attr.span,
                                    "`#[rustc_on_unimplemented]` requires a value",
                                    "value required here",
-                                   Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#)));
+                                   Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)));
         };
         debug!("of_item({:?}/{:?}) = {:?}", trait_def_id, impl_def_id, result);
         result
@@ -213,10 +213,13 @@ pub fn evaluate(&self,
             }
         }
 
+        let options: FxHashMap<String, String> = options.into_iter()
+            .filter_map(|(k, v)| v.as_ref().map(|v| (k.to_owned(), v.to_owned())))
+            .collect();
         OnUnimplementedNote {
-            label: label.map(|l| l.format(tcx, trait_ref)),
-            message: message.map(|m| m.format(tcx, trait_ref)),
-            note: note.map(|n| n.format(tcx, trait_ref)),
+            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)),
         }
     }
 }
@@ -251,6 +254,10 @@ fn verify(&self,
                     Position::ArgumentNamed(s) if s == "Self" => (),
                     // `{ThisTraitsName}` is allowed
                     Position::ArgumentNamed(s) if s == name => (),
+                    // `{from_method}` is allowed
+                    Position::ArgumentNamed(s) if s == "from_method" => (),
+                    // `{from_desugaring}` is allowed
+                    Position::ArgumentNamed(s) if s == "from_desugaring" => (),
                     // So is `{A}` if A is a type parameter
                     Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
                         param.name == s
@@ -258,17 +265,14 @@ fn verify(&self,
                         Some(_) => (),
                         None => {
                             span_err!(tcx.sess, span, E0230,
-                                      "there is no parameter \
-                                       {} on trait {}",
-                                      s, name);
+                                      "there is no parameter `{}` on trait `{}`", s, name);
                             result = Err(ErrorReported);
                         }
                     },
                     // `{:1}` and `{}` are not to be used
                     Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => {
                         span_err!(tcx.sess, span, E0231,
-                                  "only named substitution \
-                                   parameters are allowed");
+                                  "only named substitution parameters are allowed");
                         result = Err(ErrorReported);
                     }
                 }
@@ -280,7 +284,8 @@ fn verify(&self,
 
     pub fn format(&self,
                   tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                  trait_ref: ty::TraitRef<'tcx>)
+                  trait_ref: ty::TraitRef<'tcx>,
+                  options: &FxHashMap<String, String>)
                   -> String
     {
         let name = tcx.item_name(trait_ref.def_id);
@@ -296,6 +301,7 @@ pub fn format(&self,
             let name = param.name.to_string();
             Some((name, value))
         }).collect::<FxHashMap<String, String>>();
+        let empty_string = String::new();
 
         let parser = Parser::new(&self.0, None);
         parser.map(|p| {
@@ -308,14 +314,20 @@ pub fn format(&self,
                             &trait_str
                         }
                         None => {
-                            bug!("broken on_unimplemented {:?} for {:?}: \
-                                  no argument matching {:?}",
-                                 self.0, trait_ref, s)
+                            if let Some(val) = options.get(s) {
+                                val
+                            } else if s == "from_desugaring" || s == "from_method" {
+                                // don't break messages using these two arguments incorrectly
+                                &empty_string
+                            } else {
+                                bug!("broken on_unimplemented {:?} for {:?}: \
+                                      no argument matching {:?}",
+                                     self.0, trait_ref, s)
+                            }
                         }
                     },
                     _ => {
-                        bug!("broken on_unimplemented {:?} - bad \
-                              format arg", self.0)
+                        bug!("broken on_unimplemented {:?} - bad format arg", self.0)
                     }
                 }
             }
index cb6cc44a73597686f222eeb76d9fcbc3721f6d35..613b359c299b80238f2a9ab34803032d6147204e 100644 (file)
@@ -4,7 +4,7 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
 LL | #[rustc_on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error: aborting due to previous error
 
index 7ef155e5f2ebece26ddc962389863f4f1bc7d023..286c71bb2990847078ba45170003511a9958ae17 100644 (file)
@@ -28,7 +28,7 @@ trait BadAnnotation1
 {}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
-//~^ ERROR there is no parameter C on trait BadAnnotation2
+//~^ ERROR there is no parameter `C` on trait `BadAnnotation2`
 trait BadAnnotation2<A,B>
 {}
 
index 1c5d4d603afc662d6cae88914ec8a29104a74eb9..212eb125f85b386e715b6c59c1b31df7b2f131c0 100644 (file)
@@ -4,9 +4,9 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
 LL | #[rustc_on_unimplemented] //~ ERROR `#[rustc_on_unimplemented]` requires a value
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
-error[E0230]: there is no parameter C on trait BadAnnotation2
+error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
   --> $DIR/bad-annotation.rs:30:1
    |
 LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
@@ -24,7 +24,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(lorem="")]
    |                          ^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: this attribute must have a valid value
   --> $DIR/bad-annotation.rs:44:26
@@ -32,7 +32,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
    |                          ^^^^^^^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: this attribute must have a valid value
   --> $DIR/bad-annotation.rs:48:39
@@ -40,7 +40,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(message="x", message="y")]
    |                                       ^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: this attribute must have a valid value
   --> $DIR/bad-annotation.rs:52:39
@@ -48,7 +48,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))]
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]`
   --> $DIR/bad-annotation.rs:56:26
@@ -62,7 +62,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(on="x", message="y")]
    |                          ^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: this attribute must have a valid value
   --> $DIR/bad-annotation.rs:67:40
@@ -70,7 +70,7 @@ error[E0232]: this attribute must have a valid value
 LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")]
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented = "foo"]`
+   = note: eg `#[rustc_on_unimplemented(message="foo")]`
 
 error: aborting due to 10 previous errors