]> git.lizzy.rs Git - rust.git/commitdiff
Take Const into account in HIR
authorvarkor <github@varkor.com>
Fri, 15 Feb 2019 22:25:42 +0000 (22:25 +0000)
committervarkor <github@varkor.com>
Fri, 15 Feb 2019 22:29:24 +0000 (22:29 +0000)
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
src/librustc/hir/intravisit.rs
src/librustc/hir/map/mod.rs
src/librustc/ich/impls_hir.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc_lint/builtin.rs
src/librustc_metadata/encoder.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/compare_method.rs

index 9436c600c9fd3a06c20f269d3a93a02ce6f8163d..94b036fded5a156e68431ea26de2e2ff7ca562b6 100644 (file)
@@ -334,6 +334,7 @@ fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg) {
         match generic_arg {
             GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
             GenericArg::Type(ty) => self.visit_ty(ty),
+            GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
         }
     }
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
@@ -752,6 +753,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
     match param.kind {
         GenericParamKind::Lifetime { .. } => {}
         GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
+        GenericParamKind::Const { ref ty } => visitor.visit_ty(ty),
     }
     walk_list!(visitor, visit_param_bound, &param.bounds);
 }
index b6cf4c1b84d0c6454b91bfb8374518c31eef8756..e933e4b7180c49c525460f394a28a4f6c206e17b 100644 (file)
@@ -398,6 +398,7 @@ pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
                 Some(match param.kind {
                     GenericParamKind::Lifetime { .. } => Def::Local(param.id),
                     GenericParamKind::Type { .. } => Def::TyParam(self.local_def_id(param.id)),
+                    GenericParamKind::Const { .. } => Def::ConstParam(self.local_def_id(param.id)),
                 })
             }
         }
index b10e89373259798624d97801c4f5939b5967094b..727c441b0e8dba59e462567d577b13bcc00dc993 100644 (file)
@@ -179,9 +179,15 @@ fn hash_stable<W: StableHasherResult>(&self,
     args
 });
 
+impl_stable_hash_for!(struct hir::ConstArg {
+    value,
+    span,
+});
+
 impl_stable_hash_for!(enum hir::GenericArg {
     Lifetime(lt),
-    Type(ty)
+    Type(ty),
+    Const(ct),
 });
 
 impl_stable_hash_for!(struct hir::GenericArgs {
@@ -231,6 +237,9 @@ fn hash_stable<W: StableHasherResult>(&self,
                 default.hash_stable(hcx, hasher);
                 synthetic.hash_stable(hcx, hasher);
             }
+            hir::GenericParamKind::Const { ref ty } => {
+                ty.hash_stable(hcx, hasher);
+            }
         }
     }
 }
index 231dcc9bfd272af8d1db2709639b5ceb4e89529a..56e7d789356989f7ab1027209686df687657b329 100644 (file)
@@ -704,7 +704,7 @@ pub fn cat_def(&self,
                hir_id, expr_ty, def);
 
         match def {
-            Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
+            Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) | Def::ConstParam(..) |
             Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
                 Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
             }
index 5f7b9cc33660f95191937e15d15573612d058579..08da74f47d450eed321978173dc969e7c38e5659 100644 (file)
@@ -527,23 +527,20 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 } else {
                     0
                 };
-                let mut type_count = 0;
-                let lifetimes = generics
-                    .params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir(), &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            type_count += 1;
-                            None
-                        }
-                    })
-                    .collect();
+                let mut non_lifetime_count = 0;
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir(), &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } |
+                    GenericParamKind::Const { .. } => {
+                        non_lifetime_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
-                    next_early_index: index + type_count,
+                    next_early_index: index + non_lifetime_count,
                     abstract_type_parent: true,
                     track_lifetime_uses,
                     s: ROOT_SCOPE,
@@ -708,7 +705,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
 
                 let mut elision = None;
                 let mut lifetimes = FxHashMap::default();
-                let mut type_count = 0;
+                let mut non_lifetime_count = 0;
                 for param in &generics.params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {
@@ -725,12 +722,13 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                                 lifetimes.insert(name, reg);
                             }
                         }
-                        GenericParamKind::Type { .. } => {
-                            type_count += 1;
+                        GenericParamKind::Type { .. } |
+                        GenericParamKind::Const { .. } => {
+                            non_lifetime_count += 1;
                         }
                     }
                 }
-                let next_early_index = index + type_count;
+                let next_early_index = index + non_lifetime_count;
 
                 if let Some(elision_region) = elision {
                     let scope = Scope::Elision {
@@ -788,23 +786,20 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
                 let generics = &trait_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let mut type_count = 0;
-                let lifetimes = generics
-                    .params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir(), &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            type_count += 1;
-                            None
-                        }
-                    })
-                    .collect();
+                let mut non_lifetime_count = 0;
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir(), &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } |
+                    GenericParamKind::Const { .. } => {
+                        non_lifetime_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
-                    next_early_index: index + type_count,
+                    next_early_index: index + non_lifetime_count,
                     s: self.scope,
                     track_lifetime_uses: true,
                     abstract_type_parent: true,
@@ -842,24 +837,21 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
             Type(ref ty) => {
                 let generics = &impl_item.generics;
                 let mut index = self.next_early_index();
-                let mut next_early_index = index;
+                let mut non_lifetime_count = 0;
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics
-                    .params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir(), &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            next_early_index += 1;
-                            None
-                        }
-                    })
-                    .collect();
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir(), &mut index, param))
+                    }
+                    GenericParamKind::Const { .. } |
+                    GenericParamKind::Type { .. } => {
+                        non_lifetime_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
-                    next_early_index,
+                    next_early_index: index + non_lifetime_count,
                     s: self.scope,
                     track_lifetime_uses: true,
                     abstract_type_parent: true,
@@ -874,19 +866,19 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
                 let mut index = self.next_early_index();
                 let mut next_early_index = index;
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics
-                    .params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir(), &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            next_early_index += 1;
-                            None
-                        }
-                    })
-                    .collect();
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir(), &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        next_early_index += 1;
+                        None
+                    }
+                    GenericParamKind::Const { .. } => {
+                        next_early_index += 1;
+                        None
+                    }
+                }).collect();
 
                 let scope = Scope::Binder {
                     lifetimes,
@@ -950,6 +942,10 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
                         self.visit_ty(&ty);
                     }
                 }
+                GenericParamKind::Const { ref ty, .. } => {
+                    walk_list!(self, visit_param_bound, &param.bounds);
+                    self.visit_ty(&ty);
+                }
             }
         }
         for predicate in &generics.where_clause.predicates {
@@ -1395,6 +1391,10 @@ fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound]) {
                     Set1::Many => Set1::Many,
                 })
             }
+            GenericParamKind::Const { .. } => {
+                // Generic consts don't impose any constraints.
+                None
+            }
         })
         .collect()
 }
@@ -1703,25 +1703,22 @@ fn visit_early_late<F>(
             }
         }
 
-        let mut type_count = 0;
-        let lifetimes = generics
-            .params
-            .iter()
-            .filter_map(|param| match param.kind {
-                GenericParamKind::Lifetime { .. } => {
-                    if self.map.late_bound.contains(&param.id) {
-                        Some(Region::late(&self.tcx.hir(), param))
-                    } else {
-                        Some(Region::early(&self.tcx.hir(), &mut index, param))
-                    }
-                }
-                GenericParamKind::Type { .. } => {
-                    type_count += 1;
-                    None
+        let mut non_lifetime_count = 0;
+        let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                if self.map.late_bound.contains(&param.id) {
+                    Some(Region::late(&self.tcx.hir(), param))
+                } else {
+                    Some(Region::early(&self.tcx.hir(), &mut index, param))
                 }
-            })
-            .collect();
-        let next_early_index = index + type_count;
+            }
+            GenericParamKind::Type { .. } |
+            GenericParamKind::Const { .. } => {
+                non_lifetime_count += 1;
+                None
+            }
+        }).collect();
+        let next_early_index = index + non_lifetime_count;
 
         let scope = Scope::Binder {
             lifetimes,
@@ -2011,6 +2008,9 @@ fn visit_segment_args(&mut self, def: Def, depth: usize, generic_args: &'tcx hir
                     }
                     i += 1;
                 }
+                GenericArg::Const(ct) => {
+                    self.visit_anon_const(&ct.value);
+                }
             }
         }
 
@@ -2768,8 +2768,9 @@ fn insert_late_bound_lifetimes(
         match param.kind {
             hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
 
-            // Types are not late-bound.
-            hir::GenericParamKind::Type { .. } => continue,
+            // Neither types nor consts are late-bound.
+            hir::GenericParamKind::Type { .. }
+            | hir::GenericParamKind::Const { .. } => continue,
         }
 
         let lt_name = hir::LifetimeName::Param(param.name.modern());
index 28e01bd9793fd9813201801c2bf5b2714326d7f9..925cde5b5cc8b3d48057b3399ca707bacda789fe 100644 (file)
@@ -907,11 +907,13 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
                     for param in &generics.params {
                         match param.kind {
                             GenericParamKind::Lifetime { .. } => {}
-                            GenericParamKind::Type { .. } => {
-                                let mut err = cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS,
-                                                                  it.span,
-                                                                  "functions generic over \
-                                                                   types must be mangled");
+                            GenericParamKind::Type { .. } |
+                            GenericParamKind::Const { .. } => {
+                                let mut err = cx.struct_span_lint(
+                                    NO_MANGLE_GENERIC_ITEMS,
+                                    it.span,
+                                    "functions generic over types or consts must be mangled",
+                                );
                                 err.span_suggestion_short(
                                     no_mangle_attr.span,
                                     "remove this attribute",
@@ -1791,14 +1793,15 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
 
             for param in &generics.params {
                 let param_name = match param.kind {
-                    hir::GenericParamKind::Lifetime { .. } => { continue; },
+                    hir::GenericParamKind::Lifetime { .. } => continue,
                     hir::GenericParamKind::Type { .. } => {
                         match param.name {
-                            hir::ParamName::Fresh(_) => { continue; },
-                            hir::ParamName::Error => { continue; },
-                            hir::ParamName::Plain(name) => name.to_string()
+                            hir::ParamName::Fresh(_) => continue,
+                            hir::ParamName::Error => continue,
+                            hir::ParamName::Plain(name) => name.to_string(),
                         }
                     }
+                    hir::GenericParamKind::Const { .. } => continue,
                 };
                 let bound_spans = self.collect_outlives_bound_spans(
                     cx, def_id, &param_name, &param.bounds, infer_static
index 40d3ee9cc0b11266db0d27565fa03a6e288d5771..776adc077fc085a934c654edf6a4f4ed4b540c54 100644 (file)
@@ -1331,6 +1331,29 @@ fn encode_info_for_ty_param(&mut self,
         }
     }
 
+    fn encode_info_for_const_param(&mut self, def_id: DefId) -> Entry<'tcx> {
+        debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
+        let tcx = self.tcx;
+        Entry {
+            kind: EntryKind::Type,
+            visibility: self.lazy(&ty::Visibility::Public),
+            span: self.lazy(&tcx.def_span(def_id)),
+            attributes: LazySeq::empty(),
+            children: LazySeq::empty(),
+            stability: None,
+            deprecation: None,
+
+            ty: Some(self.encode_item_type(def_id)),
+            inherent_impls: LazySeq::empty(),
+            variances: LazySeq::empty(),
+            generics: None,
+            predicates: None,
+            predicates_defined_on: None,
+
+            mir: None,
+        }
+    }
+
     fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
         debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id);
         let tcx = self.tcx;
@@ -1684,6 +1707,11 @@ fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
                     let encode_info = IsolatedEncoder::encode_info_for_ty_param;
                     self.record(def_id, encode_info, (def_id, has_default));
                 }
+                hir::GenericParamKind::Const { .. } => {
+                    let def_id = self.tcx.hir().local_def_id(param.id);
+                    let encode_info = IsolatedEncoder::encode_info_for_const_param;
+                    self.record(def_id, encode_info, def_id);
+                }
             }
         }
     }
index a76aa7454cbe4c6e72eeb510415b842f51db5b29..e68702bfe3ae028ba0cec8ca948dd173c8741487 100644 (file)
@@ -1090,7 +1090,10 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             for param in &generics.params {
                 match param.kind {
                     hir::GenericParamKind::Lifetime { .. } => {}
-                    hir::GenericParamKind::Type { .. } => return,
+                    hir::GenericParamKind::Type { .. } |
+                    hir::GenericParamKind::Const { .. } => {
+                        return
+                    }
                 }
             }
 
index 23e9cd55cdce7f552fff4cfbb1cb05c07c18e61e..cde6eb22bb8aed7cd1e28555b9c9cae1b52230cb 100644 (file)
@@ -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();
                     }
@@ -1459,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;
@@ -1480,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;
                     }
                 }
index 05ca54df2984b8eab95210201ecceb274fa33d59..bc323e2cf8a989ef44321130dba68f20508d05c4 100644 (file)
@@ -840,8 +840,9 @@ fn nested_visit_map<'this>(
                         let bounds = impl_m.generics.params.iter().find_map(|param| {
                             match param.kind {
                                 GenericParamKind::Lifetime { .. } => None,
-                                GenericParamKind::Type { .. } => {
-                                    if param.hir_id == impl_hir_id {
+                                GenericParamKind::Type { .. } |
+                                GenericParamKind::Const { .. } => {
+                                    if param.hir_id == impl_node_id {
                                         Some(&param.bounds)
                                     } else {
                                         None