diff options
| author | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2017-11-16 21:10:49 +0900 |
|---|---|---|
| committer | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2017-11-24 13:00:55 +0900 |
| commit | d602c2efffafeda612f6192db1a44e113186db3e (patch) | |
| tree | 19be08aeb2ce0c22d3a505a2b4d873862c6130a9 | |
| parent | bbd7932a66b56da9a1c7d8cc30dc931922b356c0 (diff) | |
| download | rust-d602c2efffafeda612f6192db1a44e113186db3e.tar.gz rust-d602c2efffafeda612f6192db1a44e113186db3e.zip | |
Visit const expressions in check match
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 98ed8d99fda..bae3cf4db01 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -26,6 +26,7 @@ use rustc::lint; use rustc_errors::DiagnosticBuilder; use rustc::hir::def::*; +use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use rustc::hir::{self, Pat, PatKind}; @@ -48,14 +49,38 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { let def_id = self.tcx.hir.local_def_id(id); - MatchVisitor { - tcx: self.tcx, - tables: self.tcx.body_tables(b), - region_scope_tree: &self.tcx.region_scope_tree(def_id), - param_env: self.tcx.param_env(def_id), - identity_substs: Substs::identity_for_item(self.tcx, def_id), - }.visit_body(self.tcx.hir.body(b)); + check_body(self.tcx, def_id, b); } + + fn visit_item(&mut self, item: &'tcx hir::Item) { + intravisit::walk_item(self, item); + match item.node { + hir::ItemStatic(.., body_id) | hir::ItemConst(.., body_id) => { + let def_id = self.tcx.hir.local_def_id(item.id); + check_body(self.tcx, def_id, body_id); + } + _ => (), + } + } + + fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { + intravisit::walk_impl_item(self, ii); + if let hir::ImplItemKind::Const(_, body_id) = ii.node { + let def_id = self.tcx.hir.local_def_id(ii.id); + check_body(self.tcx, def_id, body_id); + } + } + + fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { + intravisit::walk_trait_item(self, ti); + if let hir::TraitItemKind::Const(_, Some(body_id)) = ti.node { + let def_id = self.tcx.hir.local_def_id(ti.id); + check_body(self.tcx, def_id, body_id); + } + } + + // Enum variants and types (e.g. `[T; { .. }]`) may have bodies too, + // but they are const-evaluated during typeck. } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { @@ -63,6 +88,20 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.sess.abort_if_errors(); } +pub(crate) fn check_body<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + body_id: hir::BodyId, +) { + MatchVisitor { + tcx, + tables: tcx.body_tables(body_id), + region_scope_tree: &tcx.region_scope_tree(def_id), + param_env: tcx.param_env(def_id), + identity_substs: Substs::identity_for_item(tcx, def_id), + }.visit_body(tcx.hir.body(body_id)); +} + fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> { struct_span_err!(sess, sp, E0004, "{}", &error_message) } |
