Skip to content

Commit d602c2e

Browse files
committed
Visit const expressions in check match
1 parent bbd7932 commit d602c2e

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

src/librustc_const_eval/check_match.rs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc::lint;
2626
use rustc_errors::DiagnosticBuilder;
2727

2828
use rustc::hir::def::*;
29+
use rustc::hir::def_id::DefId;
2930
use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
3031
use rustc::hir::{self, Pat, PatKind};
3132

@@ -48,21 +49,59 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
4849

4950
let def_id = self.tcx.hir.local_def_id(id);
5051

51-
MatchVisitor {
52-
tcx: self.tcx,
53-
tables: self.tcx.body_tables(b),
54-
region_scope_tree: &self.tcx.region_scope_tree(def_id),
55-
param_env: self.tcx.param_env(def_id),
56-
identity_substs: Substs::identity_for_item(self.tcx, def_id),
57-
}.visit_body(self.tcx.hir.body(b));
52+
check_body(self.tcx, def_id, b);
5853
}
54+
55+
fn visit_item(&mut self, item: &'tcx hir::Item) {
56+
intravisit::walk_item(self, item);
57+
match item.node {
58+
hir::ItemStatic(.., body_id) | hir::ItemConst(.., body_id) => {
59+
let def_id = self.tcx.hir.local_def_id(item.id);
60+
check_body(self.tcx, def_id, body_id);
61+
}
62+
_ => (),
63+
}
64+
}
65+
66+
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
67+
intravisit::walk_impl_item(self, ii);
68+
if let hir::ImplItemKind::Const(_, body_id) = ii.node {
69+
let def_id = self.tcx.hir.local_def_id(ii.id);
70+
check_body(self.tcx, def_id, body_id);
71+
}
72+
}
73+
74+
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
75+
intravisit::walk_trait_item(self, ti);
76+
if let hir::TraitItemKind::Const(_, Some(body_id)) = ti.node {
77+
let def_id = self.tcx.hir.local_def_id(ti.id);
78+
check_body(self.tcx, def_id, body_id);
79+
}
80+
}
81+
82+
// Enum variants and types (e.g. `[T; { .. }]`) may have bodies too,
83+
// but they are const-evaluated during typeck.
5984
}
6085

6186
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
6287
tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx: tcx }.as_deep_visitor());
6388
tcx.sess.abort_if_errors();
6489
}
6590

91+
pub(crate) fn check_body<'a, 'tcx>(
92+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
93+
def_id: DefId,
94+
body_id: hir::BodyId,
95+
) {
96+
MatchVisitor {
97+
tcx,
98+
tables: tcx.body_tables(body_id),
99+
region_scope_tree: &tcx.region_scope_tree(def_id),
100+
param_env: tcx.param_env(def_id),
101+
identity_substs: Substs::identity_for_item(tcx, def_id),
102+
}.visit_body(tcx.hir.body(body_id));
103+
}
104+
66105
fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> {
67106
struct_span_err!(sess, sp, E0004, "{}", &error_message)
68107
}

0 commit comments

Comments
 (0)