]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/astconv.rs
Auto merge of #69550 - RalfJung:scalar, r=oli-obk
[rust.git] / src / librustc_typeck / astconv.rs
index 98f4c509b5d8c44a36e7b98791c7ba15bd1a2723..199b476cb9a3e74ff44d0d081d9a0ee472a9f243 100644 (file)
@@ -16,6 +16,8 @@
 use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
 use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
+use rustc_ast::ast;
+use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
 use rustc_hir as hir;
@@ -32,8 +34,6 @@
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use smallvec::SmallVec;
-use syntax::ast;
-use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::collections::BTreeSet;
 use std::iter;
@@ -514,7 +514,7 @@ pub fn create_substs_for_generic_args<'b>(
         self_ty: Option<Ty<'tcx>>,
         arg_count_correct: bool,
         args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool),
-        provided_kind: impl Fn(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
+        mut provided_kind: impl FnMut(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
         mut inferred_kind: impl FnMut(
             Option<&[subst::GenericArg<'tcx>]>,
             &GenericParamDef,
@@ -751,6 +751,7 @@ fn create_substs_for_ast_path<'a>(
         };
 
         let mut missing_type_params = vec![];
+        let mut inferred_params = vec![];
         let substs = Self::create_substs_for_generic_args(
             tcx,
             def_id,
@@ -773,7 +774,12 @@ fn create_substs_for_ast_path<'a>(
                     self.ast_region_to_region(&lt, Some(param)).into()
                 }
                 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
-                    self.ast_ty_to_ty(&ty).into()
+                    if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
+                        inferred_params.push(ty.span);
+                        tcx.types.err.into()
+                    } else {
+                        self.ast_ty_to_ty(&ty).into()
+                    }
                 }
                 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
                     self.ast_const_to_const(&ct.value, tcx.type_of(param.def_id)).into()
@@ -832,6 +838,18 @@ fn create_substs_for_ast_path<'a>(
                 }
             },
         );
+        if !inferred_params.is_empty() {
+            // We always collect the spans for placeholder types when evaluating `fn`s, but we
+            // only want to emit an error complaining about them if infer types (`_`) are not
+            // allowed. `allow_ty_infer` gates this behavior.
+            crate::collect::placeholder_type_error(
+                tcx,
+                inferred_params[0],
+                &[],
+                inferred_params,
+                false,
+            );
+        }
 
         self.complain_about_missing_type_params(
             missing_type_params,
@@ -1634,7 +1652,7 @@ fn conv_object_ty_poly_trait_ref(
         }
 
         for (projection_bound, _) in &bounds.projection_bounds {
-            for (_, def_ids) in &mut associated_types {
+            for def_ids in associated_types.values_mut() {
                 def_ids.remove(&projection_bound.projection_def_id());
             }
         }
@@ -1743,7 +1761,7 @@ fn complain_about_missing_associated_types(
         potential_assoc_types: Vec<Span>,
         trait_bounds: &[hir::PolyTraitRef<'_>],
     ) {
-        if !associated_types.values().any(|v| v.len() > 0) {
+        if !associated_types.values().any(|v| !v.is_empty()) {
             return;
         }
         let tcx = self.tcx();