about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-15 11:01:28 -0700
committerGitHub <noreply@github.com>2020-07-15 11:01:28 -0700
commitbee28990d3d3c43f1c6dd83e4623cfa3e5f65caf (patch)
tree84b180231f02053d59d7aafb8ce2de2ec1465a7e
parentf4bbd0e607d3f302342b835999105d4a2ad4025d (diff)
parentc44ca17a4425b9bbd5d6219c8cf5d75bf670e667 (diff)
Rollup merge of #74344 - estebank:stringly-wobbly, r=eddyb
Remove string comparison and use diagnostic item instead

r? @eddyb
-rw-r--r--src/libcore/option.rs1
-rw-r--r--src/librustc_span/symbol.rs1
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs18
3 files changed, 13 insertions, 7 deletions
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 7aca6af3de6..a27e8d2a724 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1681,6 +1681,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
 /// to allow `x?` (where `x` is an `Option<T>`) to be converted into your error type, you can
 /// implement `impl From<NoneError>` for `YourErrorType`. In that case, `x?` within a function that
 /// returns `Result<_, YourErrorType>` will translate a `None` value into an `Err` result.
+#[rustc_diagnostic_item = "none_error"]
 #[unstable(feature = "try_trait", issue = "42327")]
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 pub struct NoneError;
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index d7651879a8a..86b770104ea 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -632,6 +632,7 @@ symbols! {
         nomem,
         non_ascii_idents,
         None,
+        none_error,
         non_exhaustive,
         no_niche,
         non_modrs_mods,
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 4ade1ce9163..79d5c148ce4 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -26,6 +26,7 @@ use rustc_middle::ty::{
     TypeFoldable, WithConstness,
 };
 use rustc_session::DiagnosticMessageId;
+use rustc_span::symbol::sym;
 use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP};
 use std::fmt;
 
@@ -283,8 +284,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             .span_to_snippet(span)
                             .map(|s| &s == "?")
                             .unwrap_or(false);
-                        let is_from = format!("{}", trait_ref.print_only_trait_path())
-                            .starts_with("std::convert::From<");
+                        let is_from = self.tcx.get_diagnostic_item(sym::from_trait)
+                            == Some(trait_ref.def_id());
                         let is_unsize =
                             { Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
                         let (message, note) = if is_try && is_from {
@@ -315,12 +316,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             ))
                         );
 
-                        let should_convert_option_to_result =
-                            format!("{}", trait_ref.print_only_trait_path())
-                                .starts_with("std::convert::From<std::option::NoneError");
-                        let should_convert_result_to_option = format!("{}", trait_ref)
-                            .starts_with("<std::option::NoneError as std::convert::From<");
                         if is_try && is_from {
+                            let none_error = self
+                                .tcx
+                                .get_diagnostic_item(sym::none_error)
+                                .map(|def_id| tcx.type_of(def_id));
+                            let should_convert_option_to_result =
+                                Some(trait_ref.skip_binder().substs.type_at(1)) == none_error;
+                            let should_convert_result_to_option =
+                                Some(trait_ref.self_ty().skip_binder()) == none_error;
                             if should_convert_option_to_result {
                                 err.span_suggestion_verbose(
                                     span.shrink_to_lo(),