Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 47904d2

Browse files
committedNov 11, 2019
Auto merge of #66170 - ecstatic-morse:hir-const-check, r=Centril,oli-obk
Add a HIR pass to check consts for `if`, `loop`, etc. Resolves #66125. This PR adds a HIR pass to check for high-level control flow constructs that are forbidden in a const-context. The MIR const-checker is unable to provide good spans for these since they are lowered to control flow primitives (e.g., `Goto` and `SwitchInt`), and these often don't map back to the underlying statement as a whole. This PR is intended only to improve diagnostics once `if` and `match` become commonplace in constants (behind a feature flag). The MIR const-checker will continue to operate unchanged, and will catch anything this check might miss. In this implementation, the HIR const-checking pass is run much earlier than the MIR one, so it will supersede any errors from the latter. I will need some mentoring if we wish to change this, since I'm not familiar with the diagnostics system. Moving this pass into the same phase as the MIR const-checker could also help keep backwards compatibility for items like `const _: () = loop { break; };`, which are currently (erroneously?) accepted by the MIR const-checker (see #62272). r? @Centril cc @eddyb (since they filed #62272)
2 parents e2fa952 + 5e81914 commit 47904d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+773
-353
lines changed
 

‎src/librustc/hir/map/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,33 @@ impl<'hir> Entry<'hir> {
7979
}
8080
}
8181

82+
fn fn_sig(&self) -> Option<&'hir FnSig> {
83+
match &self.node {
84+
Node::Item(item) => {
85+
match &item.kind {
86+
ItemKind::Fn(sig, _, _) => Some(sig),
87+
_ => None,
88+
}
89+
}
90+
91+
Node::TraitItem(item) => {
92+
match &item.kind {
93+
TraitItemKind::Method(sig, _) => Some(sig),
94+
_ => None
95+
}
96+
}
97+
98+
Node::ImplItem(item) => {
99+
match &item.kind {
100+
ImplItemKind::Method(sig, _) => Some(sig),
101+
_ => None,
102+
}
103+
}
104+
105+
_ => None,
106+
}
107+
}
108+
82109
fn associated_body(self) -> Option<BodyId> {
83110
match self.node {
84111
Node::Item(item) => {
@@ -450,6 +477,14 @@ impl<'hir> Map<'hir> {
450477
}
451478
}
452479

480+
pub fn fn_sig_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnSig> {
481+
if let Some(entry) = self.find_entry(hir_id) {
482+
entry.fn_sig()
483+
} else {
484+
bug!("no entry for hir_id `{}`", hir_id)
485+
}
486+
}
487+
453488
/// Returns the `HirId` that corresponds to the definition of
454489
/// which this is the body of, i.e., a `fn`, `const` or `static`
455490
/// item (possibly associated), a closure, or a `hir::AnonConst`.

‎src/librustc/query/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,11 @@ rustc_queries! {
329329
desc { |tcx| "checking for unstable API usage in {}", key.describe_as_module(tcx) }
330330
}
331331

332+
/// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
333+
query check_mod_const_bodies(key: DefId) -> () {
334+
desc { |tcx| "checking consts in {}", key.describe_as_module(tcx) }
335+
}
336+
332337
/// Checks the loops in the module.
333338
query check_mod_loops(key: DefId) -> () {
334339
desc { |tcx| "checking loops in {}", key.describe_as_module(tcx) }

0 commit comments

Comments
 (0)
Please sign in to comment.