Skip to content

Commit

Permalink
Auto merge of #46882 - oli-obk:miri3, r=eddyb
Browse files Browse the repository at this point in the history
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)
* can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this.
* can convert integers to `&'static T` in constants (useful for embedded)

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)
fixes #45044 (pattern matching repeat expressions)
fixes #47971 (ICE on const fn + references)
fixes #48081 (ICE on cyclic assoc const error)
fixes #48746 (nonhelpful error message with unions)

r? @eddyb

even though 1k loc are added in tests, this PR reduces the loc in this repository by 700
  • Loading branch information
bors committed Mar 8, 2018
2 parents cdcca78 + 52dec0e commit c90f682
Show file tree
Hide file tree
Showing 251 changed files with 6,638 additions and 7,166 deletions.
21 changes: 3 additions & 18 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/doc/rustc-ux-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ for details on how to format and write long error codes.
[librustc](https://github.com/rust-lang/rust/blob/master/src/librustc/diagnostics.rs),
[libsyntax](https://github.com/rust-lang/rust/blob/master/src/libsyntax/diagnostics.rs),
[librustc_borrowck](https://github.com/rust-lang/rust/blob/master/src/librustc_borrowck/diagnostics.rs),
[librustc_const_eval](https://github.com/rust-lang/rust/blob/master/src/librustc_const_eval/diagnostics.rs),
[librustc_metadata](https://github.com/rust-lang/rust/blob/master/src/librustc_metadata/diagnostics.rs),
[librustc_mir](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/diagnostics.rs),
[librustc_passes](https://github.com/rust-lang/rust/blob/master/src/librustc_passes/diagnostics.rs),
Expand Down
19 changes: 0 additions & 19 deletions src/doc/unstable-book/src/language-features/const-indexing.md

This file was deleted.

4 changes: 3 additions & 1 deletion src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ impl<T: Ord> Ord for Reverse<T> {
/// }
/// }
/// ```
#[cfg_attr(not(stage0), lang = "ord")]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Ord: Eq + PartialOrd<Self> {
/// This method returns an `Ordering` between `self` and `other`.
Expand Down Expand Up @@ -596,7 +597,8 @@ impl PartialOrd for Ordering {
/// assert_eq!(x < y, true);
/// assert_eq!(x.lt(&y), true);
/// ```
#[lang = "ord"]
#[cfg_attr(stage0, lang = "ord")]
#[cfg_attr(not(stage0), lang = "partial_ord")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@
//! user of the `DepNode` API of having to know how to compute the expected
//! fingerprint for a given set of node parameters.

use mir::interpret::{GlobalId};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
use hir::map::DefPathHash;
use hir::{HirId, ItemLocalId};

use ich::Fingerprint;
use ich::{Fingerprint, StableHashingContext};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
use ty::subst::Substs;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ich::StableHashingContext;
use std::fmt;
use std::hash::Hash;
use syntax_pos::symbol::InternedString;
Expand Down Expand Up @@ -518,7 +518,7 @@ define_dep_nodes!( <'tcx>
[] TypeckTables(DefId),
[] UsedTraitImports(DefId),
[] HasTypeckTables(DefId),
[] ConstEval { param_env: ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)> },
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
[] CheckMatch(DefId),
[] SymbolName(DefId),
[] InstanceSymbolName { instance: Instance<'tcx> },
Expand Down Expand Up @@ -661,7 +661,7 @@ trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
where T: HashStable<StableHashingContext<'gcx>> + fmt::Debug
where T: HashStable<StableHashingContext<'a>> + fmt::Debug
{
default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

Expand Down
13 changes: 0 additions & 13 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,6 @@
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {
E0020: r##"
This error indicates that an attempt was made to divide by zero (or take the
remainder of a zero divisor) in a static or constant expression. Erroneous
code example:
```compile_fail
#[deny(const_err)]
const X: i32 = 42 / 0;
// error: attempt to divide by zero in a constant expression
```
"##,

E0038: r##"
Trait objects like `Box<Trait>` can only be constructed when certain
requirements are satisfied by the trait in question.
Expand Down
1 change: 0 additions & 1 deletion src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ impl serialize::UseSpecializedDecodable for DefId {}
pub struct LocalDefId(DefIndex);

impl LocalDefId {

#[inline]
pub fn from_def_id(def_id: DefId) -> LocalDefId {
assert!(def_id.is_local());
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ struct HirItemLike<T> {
hash_bodies: bool,
}

impl<'hir, T> HashStable<StableHashingContext<'hir>> for HirItemLike<T>
impl<'a, 'hir, T> HashStable<StableHashingContext<'hir>> for HirItemLike<T>
where T: HashStable<StableHashingContext<'hir>>
{
fn hash_stable<W: StableHasherResult>(&self,
Expand Down
64 changes: 32 additions & 32 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ pub fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
/// a reference to the TyCtxt) and it holds a few caches for speeding up various
/// things (e.g. each DefId/DefPath is only hashed once).
#[derive(Clone)]
pub struct StableHashingContext<'gcx> {
sess: &'gcx Session,
definitions: &'gcx Definitions,
cstore: &'gcx dyn CrateStore,
body_resolver: BodyResolver<'gcx>,
pub struct StableHashingContext<'a> {
sess: &'a Session,
definitions: &'a Definitions,
cstore: &'a dyn CrateStore,
body_resolver: BodyResolver<'a>,
hash_spans: bool,
hash_bodies: bool,
node_id_hashing_mode: NodeIdHashingMode,

// Very often, we are hashing something that does not need the
// CachingCodemapView, so we initialize it lazily.
raw_codemap: &'gcx CodeMap,
caching_codemap: Option<CachingCodemapView<'gcx>>,
raw_codemap: &'a CodeMap,
caching_codemap: Option<CachingCodemapView<'a>>,
}

#[derive(PartialEq, Eq, Clone, Copy)]
Expand All @@ -81,14 +81,14 @@ impl<'gcx> BodyResolver<'gcx> {
}
}

impl<'gcx> StableHashingContext<'gcx> {
impl<'a> StableHashingContext<'a> {
// The `krate` here is only used for mapping BodyIds to Bodies.
// Don't use it for anything else or you'll run the risk of
// leaking data out of the tracking system.
pub fn new(sess: &'gcx Session,
krate: &'gcx hir::Crate,
definitions: &'gcx Definitions,
cstore: &'gcx dyn CrateStore)
pub fn new(sess: &'a Session,
krate: &'a hir::Crate,
definitions: &'a Definitions,
cstore: &'a dyn CrateStore)
-> Self {
let hash_spans_initial = !sess.opts.debugging_opts.incremental_ignore_spans;

Expand All @@ -106,7 +106,7 @@ impl<'gcx> StableHashingContext<'gcx> {
}

#[inline]
pub fn sess(&self) -> &'gcx Session {
pub fn sess(&self) -> &'a Session {
self.sess
}

Expand Down Expand Up @@ -165,7 +165,7 @@ impl<'gcx> StableHashingContext<'gcx> {
}

#[inline]
pub fn codemap(&mut self) -> &mut CachingCodemapView<'gcx> {
pub fn codemap(&mut self) -> &mut CachingCodemapView<'a> {
match self.caching_codemap {
Some(ref mut cm) => {
cm
Expand Down Expand Up @@ -193,38 +193,38 @@ impl<'gcx> StableHashingContext<'gcx> {
}

impl<'a, 'gcx, 'lcx> StableHashingContextProvider for TyCtxt<'a, 'gcx, 'lcx> {
type ContextType = StableHashingContext<'gcx>;
type ContextType = StableHashingContext<'a>;
fn create_stable_hashing_context(&self) -> Self::ContextType {
(*self).create_stable_hashing_context()
}
}


impl<'gcx> StableHashingContextProvider for StableHashingContext<'gcx> {
type ContextType = StableHashingContext<'gcx>;
impl<'a> StableHashingContextProvider for StableHashingContext<'a> {
type ContextType = StableHashingContext<'a>;
fn create_stable_hashing_context(&self) -> Self::ContextType {
self.clone()
}
}

impl<'gcx> ::dep_graph::DepGraphSafe for StableHashingContext<'gcx> {
impl<'a> ::dep_graph::DepGraphSafe for StableHashingContext<'a> {
}


impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::BodyId {
impl<'a> HashStable<StableHashingContext<'a>> for hir::BodyId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
if hcx.hash_bodies() {
hcx.body_resolver.body(*self).hash_stable(hcx, hasher);
}
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::HirId {
impl<'a> HashStable<StableHashingContext<'a>> for hir::HirId {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
match hcx.node_id_hashing_mode {
NodeIdHashingMode::Ignore => {
Expand All @@ -243,21 +243,21 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::HirId {
}
}

impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::HirId {
impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::HirId {
type KeyType = (DefPathHash, hir::ItemLocalId);

#[inline]
fn to_stable_hash_key(&self,
hcx: &StableHashingContext<'gcx>)
hcx: &StableHashingContext<'a>)
-> (DefPathHash, hir::ItemLocalId) {
let def_path_hash = hcx.local_def_path_hash(self.owner);
(def_path_hash, self.local_id)
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::NodeId {
impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
match hcx.node_id_hashing_mode {
NodeIdHashingMode::Ignore => {
Expand All @@ -270,18 +270,18 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::NodeId {
}
}

impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for ast::NodeId {
impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::NodeId {
type KeyType = (DefPathHash, hir::ItemLocalId);

#[inline]
fn to_stable_hash_key(&self,
hcx: &StableHashingContext<'gcx>)
hcx: &StableHashingContext<'a>)
-> (DefPathHash, hir::ItemLocalId) {
hcx.definitions.node_to_hir_id(*self).to_stable_hash_key(hcx)
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
impl<'a> HashStable<StableHashingContext<'a>> for Span {

// Hash a span in a stable way. We can't directly hash the span's BytePos
// fields (that would be similar to hashing pointers, since those are just
Expand All @@ -293,7 +293,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
// Also, hashing filenames is expensive so we avoid doing it twice when the
// span starts and ends in the same file, which is almost always the case.
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
const TAG_VALID_SPAN: u8 = 0;
const TAG_INVALID_SPAN: u8 = 1;
Expand Down Expand Up @@ -373,8 +373,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
}
}

pub fn hash_stable_trait_impls<'gcx, W, R>(
hcx: &mut StableHashingContext<'gcx>,
pub fn hash_stable_trait_impls<'a, 'gcx, W, R>(
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>,
blanket_impls: &Vec<DefId>,
non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
Expand Down
Loading

0 comments on commit c90f682

Please sign in to comment.