Diagnostics such as the following
```
mismatched types: expected `core::result::Result<uint,()>`, found `core::option::Option<<generic #1>>`
<anon>:6 let a: Result<uint, ()> = None;
^~~~
mismatched types: expected `&mut <generic #2>`, found `uint`
<anon>:7 f(42u);
^~~
```
tend to be fairly unappealing to new users. While specific type var IDs are valuable in
diagnostics that deal with more than one such variable, in practice many messages
only mention one. In those cases, leaving out the specific number makes the messages
slightly less terrifying.
In addition, type variables have been changed to use the type hole syntax `_` in diagnostics.
With a variable ID, they're printed as `_#id` (e.g. `_#1`). In cases where the ID is left out,
it's simply `_`. Integer and float variables have an additional suffix after the number, e.g.
`_#1i` or `_#3f`.
This adds a `Substs` field to `ty_unboxed_closure` and plumbs basic
handling of it throughout the compiler. trans now correctly
monomorphizes captured free variables and llvm function defs. This
fixes uses of unboxed closures which reference a free type or region
parameter from their environment in either their signature or free
variables. Closes#16791
Spring cleaning is here! In the Fall! This commit removes quite a large amount
of deprecated functionality from the standard libraries. I tried to ensure that
only old deprecated functionality was removed.
This is removing lots and lots of deprecated features, so this is a breaking
change. Please consult the deprecation messages of the deleted code to see how
to migrate code forward if it still needs migration.
[breaking-change]
- Unify the representations of `cat_upvar` and `cat_copied_upvar`
- In `link_reborrowed_region`, account for the ability of upvars to
change their mutability due to later processing. A map of recursive
region links we may want to establish in the future is maintained,
with the links being established when the kind of the borrow is
adjusted.
- When categorizing upvars, add an explicit deref that represents the
closure environment pointer for closures that do not take the
environment by value. The region for the implicit pointer is an
anonymous free region type introduced for this purpose. This
creates the necessary constraint to prevent unsound reborrows from
the environment.
- Add a note to categorizations to make it easier to tell when extra
dereferences have been inserted by an upvar without having to
perform deep pattern matching.
- Adjust borrowck to deal with the changes. Where `cat_upvar` and
`cat_copied_upvar` were previously treated differently, they are
now both treated roughly like local variables within the closure
body, as the explicit derefs now ensure proper behavior. However,
error diagnostics had to be changed to explicitly look through the
extra dereferences to avoid producing confusing messages about
references not present in the source code.
Closes issue #17403. Remaining work:
- The error diagnostics that result from failed region inference are
pretty inscrutible and should be improved.
Code like the following is now rejected:
let mut x = 0u;
let f = || &mut x;
let y = f();
let z = f(); // multiple mutable references to the same location
This also breaks code that uses a similar construction even if it does
not go on to violate aliasability semantics. Such code will need to
be reworked in some way, such as by using a capture-by-value closure
type.
[breaking-change]
Modify ast::ExprMatch to include a new value of type ast::MatchSource,
making it easy to tell whether the match was written literally or
produced via desugaring. This allows us to customize error messages
appropriately.
over inherent methods accessible via more autoderefs.
This simplifies the trait matching algorithm. It breaks code like:
impl Foo {
fn foo(self) {
// before this change, this will be called
}
}
impl<'a,'b,'c> Trait for &'a &'b &'c Foo {
fn foo(self) {
// after this change, this will be called
}
}
fn main() {
let x = &(&(&Foo));
x.foo();
}
To explicitly indicate that you wish to call the inherent method, perform
explicit dereferences. For example:
fn main() {
let x = &(&(&Foo));
(***x).foo();
}
Part of #17282.
[breaking-change]
Change to resolve and update compiler and libs for uses.
[breaking-change]
Enum variants are now in both the value and type namespaces. This means that
if you have a variant with the same name as a type in scope in a module, you
will get a name clash and thus an error. The solution is to either rename the
type or the variant.
The implementation essentially desugars during type collection and AST
type conversion time into the parameter scheme we have now. Only fully
qualified names--e.g. `<T as Foo>::Bar`--are supported.
[breaking-change]
1. The internal layout for traits has changed from (vtable, data) to (data, vtable). If you were relying on this in unsafe transmutes, you might get some very weird and apparently unrelated errors. You should not be doing this! Prefer not to do this at all, but if you must, you should use raw::TraitObject rather than hardcoding rustc's internal representation into your code.
2. The minimal type of reference-to-vec-literals (e.g., `&[1, 2, 3]`) is now a fixed size vec (e.g., `&[int, ..3]`) where it used to be an unsized vec (e.g., `&[int]`). If you want the unszied type, you must explicitly give the type (e.g., `let x: &[_] = &[1, 2, 3]`). Note in particular where multiple blocks must have the same type (e.g., if and else clauses, vec elements), the compiler will not coerce to the unsized type without a hint. E.g., `[&[1], &[1, 2]]` used to be a valid expression of type '[&[int]]'. It no longer type checks since the first element now has type `&[int, ..1]` and the second has type &[int, ..2]` which are incompatible.
3. The type of blocks (including functions) must be coercible to the expected type (used to be a subtype). Mostly this makes things more flexible and not less (in particular, in the case of coercing function bodies to the return type). However, in some rare cases, this is less flexible. TBH, I'm not exactly sure of the exact effects. I think the change causes us to resolve inferred type variables slightly earlier which might make us slightly more restrictive. Possibly it only affects blocks with unreachable code. E.g., `if ... { fail!(); "Hello" }` used to type check, it no longer does. The fix is to add a semicolon after the string.
methods.
This paves the way to associated items by introducing an extra level of
abstraction ("impl-or-trait item") between traits/implementations and
methods. This new abstraction is encoded in the metadata and used
throughout the compiler where appropriate.
There are no functional changes; this is purely a refactoring.
This leaves the `Share` trait at `std::kinds` via a `#[deprecated]` `pub use`
statement, but the `NoShare` struct is no longer part of `std::kinds::marker`
due to #12660 (the build cannot bootstrap otherwise).
All code referencing the `Share` trait should now reference the `Sync` trait,
and all code referencing the `NoShare` type should now reference the `NoSync`
type. The functionality and meaning of this trait have not changed, only the
naming.
Closes#16281
[breaking-change]
except where trait objects are involved.
Part of issue #15349, though I'm leaving it open for trait objects.
Cross borrowing for trait objects remains because it is needed until we
have DST.
This will break code like:
fn foo(x: &int) { ... }
let a = box 3i;
foo(a);
Change this code to:
fn foo(x: &int) { ... }
let a = box 3i;
foo(&*a);
[breaking-change]
This makes two changes to region inference: (1) it allows region
inference to relate early-bound regions; and (2) it allows regions to be
related before variance runs. The former is needed because there is no
relation between the two regions before region substitution happens,
while the latter is needed because type collection has to run before
variance. We assume that, before variance is inferred, that lifetimes
are invariant. This is a conservative overapproximation.
This relates to #13885. This does not remove `~self` from the language
yet, however.
[breaking-change]
This basically meant changing the interface so that no borrowed `&Vec`
is exposed, by hiding `fn get_vec` and `fn get_mut_vec` and revising
`fn all_vecs`.
Instead, clients should use one of the other methods; `get_slice`,
`pop`, `truncate`, `replace`, `push_all`, or `is_empty_in`, which
should work for any case currently used in rustc.
This change registers new snapshots, allowing `*T` to be removed from the language. This is a large breaking change, and it is recommended that if compiler errors are seen that any FFI calls are audited to determine whether they should be actually taking `*mut T`.
This breaks a fair amount of code. The typical patterns are:
* `for _ in range(0, 10)`: change to `for _ in range(0u, 10)`;
* `println!("{}", 3)`: change to `println!("{}", 3i)`;
* `[1, 2, 3].len()`: change to `[1i, 2, 3].len()`.
RFC #30. Closes#6023.
[breaking-change]
This is just a cleanup of the code. Doesn't really change anything deep about the way we operate. This is a prelude to implementing a good solution for one-way matching for #5527.
r? @pnkfelix (we were just crawling about this code, after all)