Remove string comparison and use diagnostic item instead

This commit is contained in:
Esteban Küber 2020-07-14 16:08:02 -07:00
parent c724b67e1b
commit c44ca17a44
3 changed files with 13 additions and 7 deletions

View file

@ -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;

View file

@ -564,6 +564,7 @@ symbols! {
nomem,
non_ascii_idents,
None,
none_error,
non_exhaustive,
non_modrs_mods,
nontemporal_store,

View file

@ -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(),