This commit improves the compile time of `rustc_platform_intrinsics` from 23s to
3.6s if compiling with `-O` and from 77s to 17s if compiling with `-O -g`. The
compiled rlib size also drops from 3.1M to 1.2M.
The wins here were gained by removing the destructors associated with `Type` by
removing the internal `Box` and `Vec` indirections. These destructors meant that
a lot of landing pads and extra code were generated to manage the runtime
representations. Instead everything can basically be statically computed and
shoved into rodata, so all we need is a giant string compare to lookup what's
what.
Closes#28273
danger of inference variables floating around without their inference
context.
The main insight here is that, when we are translating substitutions
between two impls, *we already know that the more specific impl holds*,
so we do not need to add its obligations to the parameter
environment. Instead, we can just thread through the inference context
we used to show select the more specific impl in the first place.
projection sensitive to "mode" (most importantly, trans vs middle).
This commit introduces several pieces of iteration infrastructure in the
specialization graph data structure, as well as various helpers for
finding the definition of a given item, given its kind and name.
In addition, associated type projection is now *mode-sensitive*, with
three possible modes:
- **Topmost**. This means that projection is only possible if there is a
non-`default` definition of the associated type directly on the
selected impl. This mode is a bit of a hack: it's used during early
coherence checking before we have built the specialization
graph (and therefore before we can walk up the specialization
parents to find other definitions). Eventually, this should be
replaced with a less "staged" construction of the specialization
graph.
- **AnyFinal**. Projection succeeds for any non-`default` associated
type definition, even if it is defined by a parent impl. Used
throughout typechecking.
- **Any**. Projection always succeeds. Used by trans.
The lasting distinction here is between `AnyFinal` and `Any` -- we wish
to treat `default` associated types opaquely for typechecking purposes.
In addition to the above, the commit includes a few other minor review fixes.
This commit leverages the specialization graph infrastructure to allow
specializing trait implementations to leave off methods for which their
parents have provided defaults.
It does not yet check that the `default` keyword is appropriately used
in such cases.
typestrong const integers
~~It would be great if someone could run crater on this PR, as this has a high danger of breaking valid code~~ Crater ran. Good to go.
----
So this PR does a few things:
1. ~~const eval array values when const evaluating an array expression~~
2. ~~const eval repeat value when const evaluating a repeat expression~~
3. ~~const eval all struct and tuple fields when evaluating a struct/tuple expression~~
4. remove the `ConstVal::Int` and `ConstVal::Uint` variants and replace them with a single enum (`ConstInt`) which has variants for all integral types
* `usize`/`isize` are also enums with variants for 32 and 64 bit. At creation and various usage steps there are assertions in place checking if the target bitwidth matches with the chosen enum variant
5. enum discriminants (`ty::Disr`) are now `ConstInt`
6. trans has its own `Disr` type now (newtype around `u64`)
This obviously can't be done without breaking changes (the ones that are noticable in stable)
We could probably write lints that find those situations and error on it for a cycle or two. But then again, those situations are rare and really bugs imo anyway:
```rust
let v10 = 10 as i8;
let v4 = 4 as isize;
assert_eq!(v10 << v4 as usize, 160 as i8);
```
stops compiling because 160 is not a valid i8
```rust
struct S<T, S> {
a: T,
b: u8,
c: S
}
let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };
```
stops compiling because `0xaa_aa_aa_aa` is not a valid i32
----
cc @eddyb @pnkfelix
related: https://github.com/rust-lang/rfcs/issues/1071
There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.
This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.
- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from https://github.com/rust-lang/rfcs/pull/1192#issuecomment-137864421. It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](https://github.com/rust-lang/rfcs/pull/1254#issuecomment-147815299), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.
cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777#30877rust-lang/rust#1192rust-lang/rfcs#1254
relevant to #28237 (tracking issue)
Zeroing on-drop seems to work fine. Still thinking about the best way to approach zeroing on-move.
(based on top of the other drop PR; only the last 2 commits are relevant)
A whole bunch of stuff gets folded into struct handling! Plus, removes
an ugly hack from trans and accidentally fixes a bug with constructing
ranges from references (see later commits with tests).
This will correctly add the thread_local attribute to the external static variable ```errno```:
```rust
extern {
#[thread_local]
static errno: c_int;
}
```
Before this commit, the thread_local attribute is ignored. Fixes#30795.
Thanks @alexcrichton for pointing out the solution.
Hopefully the author caught all the cases. For the mir_dynamic_drops_3 test case the ratio of
memsets to other instructions is 12%. On the other hand we actually do not double drop for at least
the test cases provided anymore in MIR.
The issue was that the const evaluator was returning an error because
the feature flag const_indexing wasn't turned on. The error was then
reported as a bug.
Fixes#29914
Needs a correct review because I'm not too confident with how this works.
All tests related to the C ABI are now passing.
References:
- dbe68fecd0/lib/CodeGen/TargetInfo.cpp (L479-L489)
- dbe68fecd0/lib/CodeGen/TargetInfo.cpp (L466-L477)
The `classifyArgumentType` function has two different paths depending on `RAA == CGCXXABI::RAA_DirectInMemory`, but I don't really know what's the corresponding option in Rust.
cc @brson @eddyb
The issue was that the const evaluator was returning an error because
the feature flag const_indexing wasn't turned on. The error was then
reported as a bug.
Fixes#29914
<sup>**context:** moving back to a layered approach to type checking.</sup>
It looks like they'd not ended up tightly coupled in the time one was owned by the other. Every instance outside of `FnCtxt.inh` was from an `InferCtxt` created and dropped in the same function body.
This conflicts slightly with #30652, but there too it looks like the `FulfillmentContext` is from an `InferCtxt` that is created and dropped within the same function body (across one call to a module-private function).
That said, I heard that the PR that originally moved `FulfillmentContext` into `InferCtxt` was big, which leaves me concerned that I'm missing something.
r? @nikomatsakis
This changes three ICEs to fatal errors.
I've grepped for `lang_item.*expect` and `\.expect.*lang` and didn't come up with any more. But, there could be more ICEs lurking.
I wasn't sure about a test because there already _is_ a cfail test for missing lang items, but it only checks one.
Relevant to (already closed) #31477#31480#31558.
cc @lilred