]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/astconv.rs
Take Const into account in HIR
[rust.git] / src / librustc_typeck / astconv.rs
index 757385aeb3edc8f0934e4fde066764c6ea539f66..cde6eb22bb8aed7cd1e28555b9c9cae1b52230cb 100644 (file)
@@ -3,13 +3,13 @@
 //! instance of `AstConv`.
 
 use errors::{Applicability, DiagnosticId};
-use hir::{self, GenericArg, GenericArgs};
-use hir::def::Def;
-use hir::def_id::DefId;
-use hir::HirVec;
-use lint;
-use middle::resolve_lifetime as rl;
-use namespace::Namespace;
+use crate::hir::{self, GenericArg, GenericArgs};
+use crate::hir::def::Def;
+use crate::hir::def_id::DefId;
+use crate::hir::HirVec;
+use crate::lint;
+use crate::middle::resolve_lifetime as rl;
+use crate::namespace::Namespace;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::wf::object_region_bounds;
 use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi;
-use require_c_abi_if_variadic;
+use crate::require_c_abi_if_variadic;
 use smallvec::SmallVec;
 use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{DUMMY_SP, Span, MultiSpan};
-use util::common::ErrorReported;
-use util::nodemap::FxHashMap;
+use crate::util::common::ErrorReported;
+use crate::util::nodemap::FxHashMap;
 
 use std::collections::BTreeSet;
 use std::iter;
@@ -111,7 +111,7 @@ pub fn ast_region_to_region(&self,
     {
         let tcx = self.tcx();
         let lifetime_name = |def_id| {
-            tcx.hir().name(tcx.hir().as_local_node_id(def_id).unwrap()).as_interned_str()
+            tcx.hir().name_by_hir_id(tcx.hir().as_local_hir_id(def_id).unwrap()).as_interned_str()
         };
 
         let r = match tcx.named_region(lifetime.hir_id) {
@@ -224,7 +224,7 @@ fn check_impl_trait(
         impl_trait
     }
 
-    /// Check that the correct number of generic arguments have been provided.
+    /// Checks that the correct number of generic arguments have been provided.
     /// Used specifically for function calls.
     pub fn check_generic_arg_count_for_call(
         tcx: TyCtxt,
@@ -256,7 +256,7 @@ pub fn check_generic_arg_count_for_call(
         ).0
     }
 
-    /// Check that the correct number of generic arguments have been provided.
+    /// Checks that the correct number of generic arguments have been provided.
     /// This is used both for datatypes and function calls.
     fn check_generic_arg_count(
         tcx: TyCtxt,
@@ -400,8 +400,8 @@ fn check_generic_arg_count(
 
     /// Creates the relevant generic argument substitutions
     /// corresponding to a set of generic parameters. This is a
-    /// rather complex little function. Let me try to explain the
-    /// role of each of its parameters:
+    /// rather complex function. Let us try to explain the role
+    /// of each of its parameters:
     ///
     /// To start, we are given the `def_id` of the thing we are
     /// creating the substitutions for, and a partial set of
@@ -417,9 +417,9 @@ fn check_generic_arg_count(
     /// we can append those and move on. Otherwise, it invokes the
     /// three callback functions:
     ///
-    /// - `args_for_def_id`: given the def-id `P`, supplies back the
+    /// - `args_for_def_id`: given the `DefId` `P`, supplies back the
     ///   generic arguments that were given to that parent from within
-    ///   the path; so e.g., if you have `<T as Foo>::Bar`, the def-id
+    ///   the path; so e.g., if you have `<T as Foo>::Bar`, the `DefId`
     ///   might refer to the trait `Foo`, and the arguments might be
     ///   `[T]`. The boolean value indicates whether to infer values
     ///   for arguments whose values were not explicitly provided.
@@ -500,19 +500,20 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                                 args.next();
                                 params.next();
                             }
-                            (GenericArg::Lifetime(_), GenericParamDefKind::Type { .. }) => {
-                                // We expected a type argument, but got a lifetime
-                                // argument. This is an error, but we need to handle it
-                                // gracefully so we can report sensible errors. In this
-                                // case, we're simply going to infer this argument.
-                                args.next();
-                            }
-                            (GenericArg::Type(_), GenericParamDefKind::Lifetime) => {
-                                // We expected a lifetime argument, but got a type
+                            (GenericArg::Type(_), GenericParamDefKind::Lifetime)
+                            | (GenericArg::Const(_), GenericParamDefKind::Lifetime) => {
+                                // We expected a lifetime argument, but got a type or const
                                 // argument. That means we're inferring the lifetimes.
                                 substs.push(inferred_kind(None, param, infer_types));
                                 params.next();
                             }
+                            (_, _) => {
+                                // We expected one kind of parameter, but the user provided
+                                // another. This is an error, but we need to handle it
+                                // gracefully so we can report sensible errors.
+                                // In this case, we're simply going to infer this argument.
+                                args.next();
+                            }
                         }
                     }
                     (Some(_), None) => {
@@ -524,12 +525,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                     (None, Some(&param)) => {
                         // If there are fewer arguments than parameters, it means
                         // we're inferring the remaining arguments.
-                        match param.kind {
-                            GenericParamDefKind::Lifetime | GenericParamDefKind::Type { .. } => {
-                                let kind = inferred_kind(Some(&substs), param, infer_types);
-                                substs.push(kind);
-                            }
-                        }
+                        substs.push(inferred_kind(Some(&substs), param, infer_types));
                         args.next();
                         params.next();
                     }
@@ -680,7 +676,7 @@ fn create_substs_for_ast_path(&self,
     /// bound to a valid trait type. Returns the def_id for the defining trait.
     /// The type _cannot_ be a type other than a trait type.
     ///
-    /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
+    /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T = X>`
     /// are disallowed. Otherwise, they are pushed onto the vector given.
     pub fn instantiate_mono_trait_ref(&self,
         trait_ref: &hir::TraitRef,
@@ -878,8 +874,9 @@ fn ast_type_binding_to_poly_projection_predicate(
                                           binding.item_name, binding.span)
         }?;
 
+        let hir_ref_id = self.tcx().hir().node_to_hir_id(ref_id);
         let (assoc_ident, def_scope) =
-            tcx.adjust_ident(binding.item_name, candidate.def_id(), ref_id);
+            tcx.adjust_ident(binding.item_name, candidate.def_id(), hir_ref_id);
         let assoc_ty = tcx.associated_items(candidate.def_id()).find(|i| {
             i.kind == ty::AssociatedKind::Type && i.ident.modern() == assoc_ident
         }).expect("missing associated type");
@@ -1373,7 +1370,8 @@ pub fn associated_path_to_ty(
         };
 
         let trait_did = bound.def_id();
-        let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, ref_id);
+        let hir_ref_id = self.tcx().hir().node_to_hir_id(ref_id);
+        let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, hir_ref_id);
         let item = tcx.associated_items(trait_did).find(|i| {
             Namespace::from(i.kind) == Namespace::Type &&
                 i.ident.modern() == assoc_ident
@@ -1457,9 +1455,10 @@ pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment>>(
         let mut has_err = false;
         for segment in segments {
             segment.with_generic_args(|generic_args| {
-                let (mut err_for_lt, mut err_for_ty) = (false, false);
+                let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
                 for arg in &generic_args.args {
                     let (mut span_err, span, kind) = match arg {
+                        // FIXME(varkor): unify E0109, E0110 and E0111.
                         hir::GenericArg::Lifetime(lt) => {
                             if err_for_lt { continue }
                             err_for_lt = true;
@@ -1478,10 +1477,18 @@ pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment>>(
                              ty.span,
                              "type")
                         }
+                        hir::GenericArg::Const(ct) => {
+                            if err_for_ct { continue }
+                            err_for_ct = true;
+                            (struct_span_err!(self.tcx().sess, ct.span, E0111,
+                                              "const parameters are not allowed on this type"),
+                             ct.span,
+                             "const")
+                        }
                     };
                     span_err.span_label(span, format!("{} argument not allowed", kind))
                             .emit();
-                    if err_for_lt && err_for_ty {
+                    if err_for_lt && err_for_ty && err_for_ct {
                         break;
                     }
                 }
@@ -1682,12 +1689,13 @@ pub fn def_to_ty(&self,
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
 
-                let node_id = tcx.hir().as_local_node_id(did).unwrap();
-                let item_id = tcx.hir().get_parent_node(node_id);
-                let item_def_id = tcx.hir().local_def_id(item_id);
+                let hir_id = tcx.hir().as_local_hir_id(did).unwrap();
+                let item_id = tcx.hir().get_parent_node_by_hir_id(hir_id);
+                let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
                 let generics = tcx.generics_of(item_def_id);
-                let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
-                tcx.mk_ty_param(index, tcx.hir().name(node_id).as_interned_str())
+                let index = generics.param_def_id_to_index[
+                    &tcx.hir().local_def_id_from_hir_id(hir_id)];
+                tcx.mk_ty_param(index, tcx.hir().name_by_hir_id(hir_id).as_interned_str())
             }
             Def::SelfTy(_, Some(def_id)) => {
                 // `Self` in impl (we know the concrete type).