about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-06-22 23:58:03 +0000
committerbors <bors@rust-lang.org>2021-06-22 23:58:03 +0000
commit574c9dd6f293784da0d89837f85abb1777a729ad (patch)
treeebad3f21153b5ddd37b398d0c17934cb158a4c7b /compiler
parent6a758ea7e48416b968955535094479dc2e7cc9e1 (diff)
parentbd04f4caffcc4a702e62a9a913a93541455eba0d (diff)
downloadrust-574c9dd6f293784da0d89837f85abb1777a729ad.tar.gz
rust-574c9dd6f293784da0d89837f85abb1777a729ad.zip
Auto merge of #86559 - Dylan-DPC:rollup-aixg3q5, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #86223 (Specify the kind of the item for E0121)
 - #86521 (Add comments around code where ordering is important due for panic-safety)
 - #86523 (Improvements to intra-doc link macro disambiguators)
 - #86542 (Line numbers aligned with content)
 - #86549 (Add destructuring example of E0508)
 - #86557 (Update books)

Failed merges:

 - #86548 (Fix crate filter search reset)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0508.md13
-rw-r--r--compiler/rustc_hir/src/hir.rs21
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs1
-rw-r--r--compiler/rustc_typeck/src/collect.rs51
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs37
5 files changed, 103 insertions, 20 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0508.md b/compiler/rustc_error_codes/src/error_codes/E0508.md
index 33572fca6a3..91865907bf2 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0508.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0508.md
@@ -39,3 +39,16 @@ fn main() {
     let _value = array[0].clone();
 }
 ```
+
+If you really want to move the value out, you can use a destructuring array
+pattern to move it:
+
+```
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    // Destructuring the array
+    let [_value] = array;
+}
+```
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index bb8d6386d8a..a7ce92ea579 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2815,6 +2815,27 @@ impl ItemKind<'_> {
             _ => return None,
         })
     }
+
+    pub fn descr(&self) -> &'static str {
+        match self {
+            ItemKind::ExternCrate(..) => "extern crate",
+            ItemKind::Use(..) => "`use` import",
+            ItemKind::Static(..) => "static item",
+            ItemKind::Const(..) => "constant item",
+            ItemKind::Fn(..) => "function",
+            ItemKind::Mod(..) => "module",
+            ItemKind::ForeignMod { .. } => "extern block",
+            ItemKind::GlobalAsm(..) => "global asm item",
+            ItemKind::TyAlias(..) => "type alias",
+            ItemKind::OpaqueTy(..) => "opaque type",
+            ItemKind::Enum(..) => "enum",
+            ItemKind::Struct(..) => "struct",
+            ItemKind::Union(..) => "union",
+            ItemKind::Trait(..) => "trait",
+            ItemKind::TraitAlias(..) => "trait alias",
+            ItemKind::Impl(..) => "implementation",
+        }
+    }
 }
 
 /// A reference from an trait to one of its associated items. This
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index ef195621044..10a7d69d5d3 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2418,6 +2418,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 visitor.0,
                 true,
                 hir_ty,
+                "function",
             );
         }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index ae61dd1cfce..91e65cffc58 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -145,6 +145,7 @@ crate fn placeholder_type_error(
     placeholder_types: Vec<Span>,
     suggest: bool,
     hir_ty: Option<&hir::Ty<'_>>,
+    kind: &'static str,
 ) {
     if placeholder_types.is_empty() {
         return;
@@ -174,7 +175,7 @@ crate fn placeholder_type_error(
         ));
     }
 
-    let mut err = bad_placeholder_type(tcx, placeholder_types);
+    let mut err = bad_placeholder_type(tcx, placeholder_types, kind);
 
     // Suggest, but only if it is not a function in const or static
     if suggest {
@@ -236,7 +237,15 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
     let mut visitor = PlaceholderHirTyCollector::default();
     visitor.visit_item(item);
 
-    placeholder_type_error(tcx, Some(generics.span), generics.params, visitor.0, suggest, None);
+    placeholder_type_error(
+        tcx,
+        Some(generics.span),
+        generics.params,
+        visitor.0,
+        suggest,
+        None,
+        item.kind.descr(),
+    );
 }
 
 impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
@@ -302,13 +311,17 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
 fn bad_placeholder_type(
     tcx: TyCtxt<'tcx>,
     mut spans: Vec<Span>,
+    kind: &'static str,
 ) -> rustc_errors::DiagnosticBuilder<'tcx> {
+    let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) };
+
     spans.sort();
     let mut err = struct_span_err!(
         tcx.sess,
         spans.clone(),
         E0121,
-        "the type placeholder `_` is not allowed within types on item signatures",
+        "the type placeholder `_` is not allowed within types on item signatures for {}",
+        kind
     );
     for span in spans {
         err.span_label(span, "not allowed in type signatures");
@@ -382,7 +395,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
         _: Option<&ty::GenericParamDef>,
         span: Span,
     ) -> &'tcx Const<'tcx> {
-        bad_placeholder_type(self.tcx(), vec![span]).emit();
+        bad_placeholder_type(self.tcx(), vec![span], "generic").emit();
         // Typeck doesn't expect erased regions to be returned from `type_of`.
         let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
             ty::ReErased => self.tcx.lifetimes.re_static,
@@ -746,7 +759,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
                     hir::ForeignItemKind::Static(..) => {
                         let mut visitor = PlaceholderHirTyCollector::default();
                         visitor.visit_foreign_item(item);
-                        placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+                        placeholder_type_error(
+                            tcx,
+                            None,
+                            &[],
+                            visitor.0,
+                            false,
+                            None,
+                            "static variable",
+                        );
                     }
                     _ => (),
                 }
@@ -818,7 +839,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
                     if let hir::TyKind::TraitObject(..) = ty.kind {
                         let mut visitor = PlaceholderHirTyCollector::default();
                         visitor.visit_item(it);
-                        placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+                        placeholder_type_error(
+                            tcx,
+                            None,
+                            &[],
+                            visitor.0,
+                            false,
+                            None,
+                            it.kind.descr(),
+                        );
                     }
                 }
                 _ => (),
@@ -846,7 +875,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
             // Account for `const C: _;`.
             let mut visitor = PlaceholderHirTyCollector::default();
             visitor.visit_trait_item(trait_item);
-            placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+            placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
         }
 
         hir::TraitItemKind::Type(_, Some(_)) => {
@@ -855,7 +884,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
             // Account for `type T = _;`.
             let mut visitor = PlaceholderHirTyCollector::default();
             visitor.visit_trait_item(trait_item);
-            placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+            placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
         }
 
         hir::TraitItemKind::Type(_, None) => {
@@ -865,7 +894,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
             let mut visitor = PlaceholderHirTyCollector::default();
             visitor.visit_trait_item(trait_item);
 
-            placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+            placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
         }
     };
 
@@ -887,7 +916,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
             let mut visitor = PlaceholderHirTyCollector::default();
             visitor.visit_impl_item(impl_item);
 
-            placeholder_type_error(tcx, None, &[], visitor.0, false, None);
+            placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
         }
         hir::ImplItemKind::Const(..) => {}
     }
@@ -1711,7 +1740,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
 
                     let mut visitor = PlaceholderHirTyCollector::default();
                     visitor.visit_ty(ty);
-                    let mut diag = bad_placeholder_type(tcx, visitor.0);
+                    let mut diag = bad_placeholder_type(tcx, visitor.0, "return type");
                     let ret_ty = fn_sig.output();
                     if ret_ty != tcx.ty_error() {
                         if !ret_ty.is_closure() {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index abe5d69a3b3..78fa8074a64 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -285,7 +285,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             TraitItemKind::Const(ref ty, body_id) => body_id
                 .and_then(|body_id| {
                     if is_suggestable_infer_ty(ty) {
-                        Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident))
+                        Some(infer_placeholder_type(
+                            tcx, def_id, body_id, ty.span, item.ident, "constant",
+                        ))
                     } else {
                         None
                     }
@@ -304,7 +306,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             }
             ImplItemKind::Const(ref ty, body_id) => {
                 if is_suggestable_infer_ty(ty) {
-                    infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
+                    infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
                 } else {
                     icx.to_ty(ty)
                 }
@@ -320,9 +322,25 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
         Node::Item(item) => {
             match item.kind {
-                ItemKind::Static(ref ty, .., body_id) | ItemKind::Const(ref ty, body_id) => {
+                ItemKind::Static(ref ty, .., body_id) => {
                     if is_suggestable_infer_ty(ty) {
-                        infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
+                        infer_placeholder_type(
+                            tcx,
+                            def_id,
+                            body_id,
+                            ty.span,
+                            item.ident,
+                            "static variable",
+                        )
+                    } else {
+                        icx.to_ty(ty)
+                    }
+                }
+                ItemKind::Const(ref ty, body_id) => {
+                    if is_suggestable_infer_ty(ty) {
+                        infer_placeholder_type(
+                            tcx, def_id, body_id, ty.span, item.ident, "constant",
+                        )
                     } else {
                         icx.to_ty(ty)
                     }
@@ -742,13 +760,14 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty
     concrete_ty
 }
 
-fn infer_placeholder_type(
-    tcx: TyCtxt<'_>,
+fn infer_placeholder_type<'a>(
+    tcx: TyCtxt<'a>,
     def_id: LocalDefId,
     body_id: hir::BodyId,
     span: Span,
     item_ident: Ident,
-) -> Ty<'_> {
+    kind: &'static str,
+) -> Ty<'a> {
     // Attempts to make the type nameable by turning FnDefs into FnPtrs.
     struct MakeNameable<'tcx> {
         success: bool,
@@ -802,7 +821,7 @@ fn infer_placeholder_type(
             if let Some(sugg_ty) = sugg_ty {
                 err.span_suggestion(
                     span,
-                    "provide a type for the item",
+                    &format!("provide a type for the {item}", item = kind),
                     format!("{}: {}", item_ident, sugg_ty),
                     Applicability::MachineApplicable,
                 );
@@ -816,7 +835,7 @@ fn infer_placeholder_type(
             err.emit_unless(ty.references_error());
         }
         None => {
-            let mut diag = bad_placeholder_type(tcx, vec![span]);
+            let mut diag = bad_placeholder_type(tcx, vec![span], kind);
 
             if !ty.references_error() {
                 let mut mk_nameable = MakeNameable::new(tcx);