about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-13 23:20:03 +0000
committerbors <bors@rust-lang.org>2023-02-13 23:20:03 +0000
commit5348a89a77a49f6f57c13c0edf7f493fd410159a (patch)
treeed4cb2e46a8cc7e1ae301dc7b76a503dc5b64260 /compiler
parent065852def0903296da33a9eaf557f230bcf3a61a (diff)
parentf1a349457fe7c064cd63d14c20bc5d9519d20dc6 (diff)
downloadrust-5348a89a77a49f6f57c13c0edf7f493fd410159a.tar.gz
rust-5348a89a77a49f6f57c13c0edf7f493fd410159a.zip
Auto merge of #108015 - matthiaskrgr:rollup-qerohjn, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #107902 (fix: improve the suggestion on future not awaited)
 - #107913 (Update broken link in cargo style guide)
 - #107942 (Tighter spans for bad inherent `impl` self types)
 - #107948 (Allow shortcuts to directories to be used for ./x.py fmt)
 - #107971 (Clearly document intentional UB in mir-opt tests)
 - #107985 (Added another error to be processed in fallback)
 - #108002 (Update books)
 - #108013 (rustdoc: use a string with one-character codes for search index types)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs33
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs34
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs31
-rw-r--r--compiler/rustc_middle/src/ty/error.rs2
4 files changed, 56 insertions, 44 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index c1b0237b2d1..940a450101c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -57,7 +57,7 @@ const ADD_ATTR: &str =
     "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items";
 
 impl<'tcx> InherentCollect<'tcx> {
-    fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) {
+    fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) {
         let impl_def_id = item.owner_id;
         if let Some(def_id) = def_id.as_local() {
             // Add the implementation to the mapping from implementation to base
@@ -76,12 +76,12 @@ impl<'tcx> InherentCollect<'tcx> {
             if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
                 struct_span_err!(
                     self.tcx.sess,
-                    item.span,
+                    span,
                     E0390,
                     "cannot define inherent `impl` for a type outside of the crate where the type is defined",
                 )
                 .help(INTO_DEFINING_CRATE)
-                .span_help(item.span, ADD_ATTR_TO_TY)
+                .span_help(span, ADD_ATTR_TO_TY)
                 .emit();
                 return;
             }
@@ -93,12 +93,12 @@ impl<'tcx> InherentCollect<'tcx> {
                 {
                     struct_span_err!(
                         self.tcx.sess,
-                        item.span,
+                        span,
                         E0390,
                         "cannot define inherent `impl` for a type outside of the crate where the type is defined",
                     )
                     .help(INTO_DEFINING_CRATE)
-                    .span_help(impl_item.span, ADD_ATTR)
+                    .span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR)
                     .emit();
                     return;
                 }
@@ -112,12 +112,12 @@ impl<'tcx> InherentCollect<'tcx> {
         } else {
             struct_span_err!(
                 self.tcx.sess,
-                item.span,
+                span,
                 E0116,
                 "cannot define inherent `impl` for a type outside of the crate \
                               where the type is defined"
             )
-            .span_label(item.span, "impl for type defined outside of crate.")
+            .span_label(span, "impl for type defined outside of crate.")
             .note("define and implement a trait or new type instead")
             .emit();
         }
@@ -182,29 +182,30 @@ impl<'tcx> InherentCollect<'tcx> {
         }
 
         let item = self.tcx.hir().item(id);
-        let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items, .. }) = item.kind else {
+        let impl_span = self.tcx.hir().span(id.hir_id());
+        let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else {
             return;
         };
 
         let self_ty = self.tcx.type_of(item.owner_id);
         match *self_ty.kind() {
             ty::Adt(def, _) => {
-                self.check_def_id(item, self_ty, def.did());
+                self.check_def_id(item, self_ty, def.did(), impl_span);
             }
             ty::Foreign(did) => {
-                self.check_def_id(item, self_ty, did);
+                self.check_def_id(item, self_ty, did, impl_span);
             }
             ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
-                self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
+                self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span);
             }
             ty::Dynamic(..) => {
                 struct_span_err!(
                     self.tcx.sess,
-                    ty.span,
+                    impl_span,
                     E0785,
                     "cannot define inherent `impl` for a dyn auto trait"
                 )
-                .span_label(ty.span, "impl requires at least one non-auto trait")
+                .span_label(impl_span, "impl requires at least one non-auto trait")
                 .note("define and implement a new trait or type instead")
                 .emit();
             }
@@ -221,17 +222,17 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Never
             | ty::FnPtr(_)
             | ty::Tuple(..) => {
-                self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
+                self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span)
             }
             ty::Alias(..) | ty::Param(_) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
-                    ty.span,
+                    impl_span,
                     E0118,
                     "no nominal type found for inherent implementation"
                 );
 
-                err.span_label(ty.span, "impl requires a nominal type")
+                err.span_label(impl_span, "impl requires a nominal type")
                     .note("either implement a trait on it or create a newtype to wrap it instead");
 
                 err.emit();
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 9841c3141c9..c56149c1149 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1783,14 +1783,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             }
                         }))
                     {
-                        diag.note_expected_found_extra(
-                            &expected_label,
-                            expected,
-                            &found_label,
-                            found,
-                            &sort_string(values.expected, exp_p),
-                            &sort_string(values.found, found_p),
-                        );
+                        if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
+                            // `Future` is a special opaque type that the compiler
+                            // will try to hide in some case such as `async fn`, so
+                            // to make an error more use friendly we will
+                            // avoid to suggest a mismatch type with a
+                            // type that the user usually are not usign
+                            // directly such as `impl Future<Output = u8>`.
+                            if !self.tcx.ty_is_opaque_future(found_ty) {
+                                diag.note_expected_found_extra(
+                                    &expected_label,
+                                    expected,
+                                    &found_label,
+                                    found,
+                                    &sort_string(values.expected, exp_p),
+                                    &sort_string(values.found, found_p),
+                                );
+                            }
+                        }
                     }
                 }
                 _ => {
@@ -2854,6 +2864,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
 pub enum TyCategory {
     Closure,
     Opaque,
+    OpaqueFuture,
     Generator(hir::GeneratorKind),
     Foreign,
 }
@@ -2863,6 +2874,7 @@ impl TyCategory {
         match self {
             Self::Closure => "closure",
             Self::Opaque => "opaque type",
+            Self::OpaqueFuture => "future",
             Self::Generator(gk) => gk.descr(),
             Self::Foreign => "foreign type",
         }
@@ -2871,7 +2883,11 @@ impl TyCategory {
     pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> {
         match *ty.kind() {
             ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => Some((Self::Opaque, def_id)),
+            ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
+                let kind =
+                    if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
+                Some((kind, def_id))
+            }
             ty::Generator(def_id, ..) => {
                 Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id))
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 73859aca424..7d9a53d1c02 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -238,31 +238,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
             },
             (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => {
-                diag.span_suggestion_verbose(
-                    exp_span.shrink_to_hi(),
-                    "consider `await`ing on the `Future`",
-                    ".await",
-                    Applicability::MaybeIncorrect,
-                );
+                self.suggest_await_on_future(diag, exp_span);
+                diag.span_note(exp_span, "calling an async function returns a future");
             }
             (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
             {
                 ObligationCauseCode::Pattern { span: Some(then_span), .. } => {
-                    diag.span_suggestion_verbose(
-                        then_span.shrink_to_hi(),
-                        "consider `await`ing on the `Future`",
-                        ".await",
-                        Applicability::MaybeIncorrect,
-                    );
+                    self.suggest_await_on_future(diag, then_span.shrink_to_hi());
                 }
                 ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => {
                     let then_span = self.find_block_span_from_hir_id(*then_id);
-                    diag.span_suggestion_verbose(
-                        then_span.shrink_to_hi(),
-                        "consider `await`ing on the `Future`",
-                        ".await",
-                        Applicability::MaybeIncorrect,
-                    );
+                    self.suggest_await_on_future(diag, then_span.shrink_to_hi());
                 }
                 ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
                     ref prior_arms,
@@ -283,6 +269,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
     }
 
+    pub fn suggest_await_on_future(&self, diag: &mut Diagnostic, sp: Span) {
+        diag.span_suggestion_verbose(
+            sp.shrink_to_hi(),
+            "consider `await`ing on the `Future`",
+            ".await",
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     pub(super) fn suggest_accessing_field_where_appropriate(
         &self,
         cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index bd78705cdb5..9c171a69d06 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -271,7 +271,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
             ty::Alias(ty::Projection, _) => "associated type".into(),
             ty::Param(p) => format!("type parameter `{p}`").into(),
-            ty::Alias(ty::Opaque, ..) => "opaque type".into(),
+            ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() },
             ty::Error(_) => "type error".into(),
             _ => {
                 let width = tcx.sess.diagnostic_width();