The "hint" mechanism is essentially used as a workaround to compute
types for expressions which have not yet been type-checked. This
commit clarifies that usage, and limits the effects to the places
where it is currently necessary.
Fixes#26210.
Transition to the new object lifetime defaults, replacing the old defaults completely.
r? @pnkfelix
This is a [breaking-change] as specified by [RFC 1156][1156] (though all cases that would break should have been receiving warnings starting in Rust 1.2). Types like `&'a Box<Trait>` (or `&'a Rc<Trait>`, etc) will change from being interpreted as `&'a Box<Trait+'a>` to `&'a Box<Trait+'static>`. To restore the old behavior, write the `+'a` explicitly. For example, the function:
```rust
trait Trait { }
fn foo(x: &Box<Trait>) { ... }
```
would be rewritten as:
```rust
trait Trait { }
fn foo(x: &'a Box<Trait+'a>) { ... }
```
if one wanted to preserve the current typing.
[1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md
This PR modernizes some names in the type checker. The only remaining snake_case name in ty.rs is `ctxt` which should be resolved by @eddyb's pending refactor. We can bike shed over the names, it would just be nice to bring the type checker inline with modern Rust.
r? @eddyb
cc @nikomatsakis
In a followup to PR #26849, improve one more location for I/O where
we can use `Vec::resize` to ensure better performance when zeroing
buffers.
Use the `vec![elt; n]` macro everywhere we can in the tree. It replaces
`repeat(elt).take(n).collect()` which is more verbose, requires type
hints, and right now produces worse code. `vec![]` is preferable for vector
initialization.
The `vec![]` replacement touches upon one I/O path too, Stdin::read
for windows, and that should be a small improvement.
r? @alexcrichton
The common pattern `iter::repeat(elt).take(n).collect::<Vec<_>>()` is
exactly equivalent to `vec![elt; n]`, do this replacement in the whole
tree.
(Actually, vec![] is smart enough to only call clone n - 1 times, while
the former solution would call clone n times, and this fact is
virtually irrelevant in practice.)
Fixes#23302.
Note that there's an odd situation regarding the following, most likely due to some inadequacy in `const_eval`:
```rust
enum Y {
A = 1usize,
B,
}
```
In this case, `Y::B as usize` might be considered a constant expression in some cases, but not others. (See #23513, for a related problem where there is only one variant, with no discriminant, and it doesn't behave nicely as a constant expression either.)
Most of the complexity in this PR is basically future-proofing, to ensure that when `Y::B as usize` is fully made to be a constant expression, it can't be used to set `Y::A`, and thus indirectly itself.
`MethodCallee` now has no information about the method, other than its `DefId`.
The previous bits of information can be recovered as follows:
```rust
let method_item = tcx.impl_or_trait_item(callee.def_id);
let container = method_item.container();
```
The method is inherent if `container` is a `ty::ImplContainer`:
* the `impl` the method comes from is `container.id()`
The method is a trait method if `container` is a `ty::TraitContainer:
* the `trait` the method is part of is `container.id()`
* a `ty::TraitRef` can be constructed by putting together:
* `container.id()` as the `trait` ID
* `callee.substs.clone().method_to_trait()` as the `trait` substs (including `Self`)
* the above `trait_ref` is a valid `T: Trait<A, B, C>` predicate
* selecting `trait_ref` could result in one of the following:
* `traits::VtableImpl(data)`: static dispatch to `data.impl_def_id`
* `traits::VtableObject(data)`: dynamic dispatch, with the vtable index:
`traits::get_vtable_index_of_object_method(tcx, data, callee.def_id)`
* other variants of `traits::Vtable`: various other `impl` sources
bound that is likely to change. In that case, it will change to 'static,
so then scan down the graph to see whether there are any hard
constraints that would prevent 'static from being a valid value
here. Report a warning.
region-bound is expected to change in Rust 1.3, but don't use it for
anything in this commit. Note that this is not a "significant" part of
the type (it's not part of the formal model) so we have to normalize
this away or trans starts to get confused because two equal types wind
up with distinct LLVM types.
This patch implements the next chunk of flattening out the type checking context. In a series of patches I moved around the necessary state and logic in order to delete the `Typer` and `ClosureTyper` traits. My next goal is to clean the interfaces and start to move the normalization code behind them.
r? @nrc I hope my PR is coherent, doing this too late at night ;)