Provide hint when cast needs a dereference
For a given code:
``` rust
vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
```
display:
``` nocode
error: casting `&f64` as `i16` is invalid
--> file3.rs:2:35
|
2 | vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
| - ^^^
| |
| did you mean `*s`?
```
instead of:
``` nocode
error: casting `&f64` as `i16` is invalid
--> <anon>:2:30
|
2 | vec![0.0].iter().map(|s| s as i16).collect();
| ^^^^^^^^
|
= help: cast through a raw pointer first
```
Fixes#37338.
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop.
- ~~I have also changed the loop scoping in MIR-building so that the test
of a while loop is not considered to be part of that loop. This makes
the rules consistent with #37360. The new loop scopes in typeck also
follow this rule. That means that `loop { while (break) {} }` now
terminates instead of looping forever. This is technically a breaking
change.~~
- ~~On that note, expressions like `while break {}` and `if break {}` no
longer parse because `{}` is interpreted as an expression argument to
`break`. But no code except compiler test cases should do that anyway
because it makes no sense.~~
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
Clean up `ast::Attribute`, `ast::CrateConfig`, and string interning
This PR
- removes `ast::Attribute_` (changing `Attribute` from `Spanned<Attribute_>` to a struct),
- moves a `MetaItem`'s name from the `MetaItemKind` variants to a field of `MetaItem`,
- avoids needlessly wrapping `ast::MetaItem` with `P`,
- moves string interning into `syntax::symbol` (`ast::Name` is a reexport of `symbol::Symbol` for now),
- replaces `InternedString` with `Symbol` in the AST, HIR, and various other places, and
- refactors `ast::CrateConfig` from a `Vec` to a `HashSet`.
r? @eddyb
Add tests for incremental reuse scenarios
These are microbenchmarks checking that we achieve the expected reuse in the scenarios covered by incremental beta.
r? @michaelwoerister
For a given code:
```rust
vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
```
display:
```nocode
error: casting `&f64` as `i16` is invalid
--> foo.rs:2:35
|
2 | vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
| - ^^^ cannot cast `&f64` as `i16`
| |
| did you mean `*s`?
```
instead of:
```nocode
error: casting `&f64` as `i16` is invalid
--> <anon>:2:30
|
2 | vec![0.0].iter().map(|s| s as i16).collect();
| ^^^^^^^^
|
= help: cast through a raw pointer first
```
Show a better error when using --test with #[proc_macro_derive]
Fixes https://github.com/rust-lang/rust/issues/37480
Currently using `--test` with a crate that contains a `#[proc_macro_derive]` attribute causes an error. This PR doesn't attempt to fix the issue itself, or determine what tesing of a proc_macro_derive crate should be - just to provide a better error message.
ICH: Handle MacroDef HIR instances.
As of recently, `hir::MacroDef` instances are exported in crate metadata, which means we also store their ICH when doing incremental compilation. Even though exported macro definitions should not (yet) interact with incremental compilation, the ICH is also used for the general purpose crate hash, where macros should be included.
This PR implements ICH computation for `MacroDef`. In theory, the ICH of these MacroDefs is less stable than that of other HIR items, since I opted to just call the compiler-generated `Hash::hash()` for `Token::Interpolated` variants. `Token::Interpolated` contains AST data structures and it would have been a lot of effort to expand ICH computation to the AST too. Since quasi-quoting is rarely used *and* it would only make a difference if incremental compilation was extended to macros, the simpler implementation seemed like a good idea.
This fixes the problem reported in https://github.com/rust-lang/rust/issues/37756. The test still fails because of broken codegen-unit support though.
r? @nikomatsakis
Improvements to the #[should_panic] feature
Add more error checking for the `#[should_panic]` attribute, and print the expected panic string when it does not match.
Fixes https://github.com/rust-lang/rust/issues/29000
Eg:
```running 3 tests
test test2 ... ok
test test1 ... FAILED
: Panic did not include expected string 'foo'
test test3 ... FAILED
failures:
---- test1 stdout ----
thread 'test1' panicked at 'bar', test.rs:7
note: Run with `RUST_BACKTRACE=1` for a backtrace.
---- test3 stdout ----
thread 'test3' panicked at 'bar', test.rs:18
```
Separate impl items from the parent impl
This change separates impl item bodies out of the impl itself. This gives incremental more resolution. In so doing, it refactors how the visitors work, and cleans up a bit of the collect/check logic (mostly by moving things out of collect that didn't really belong there, because they were just checking conditions).
However, this is not as effective as I expected, for a kind of frustrating reason. In particular, when invoking `foo.bar()` you still wind up with dependencies on private items. The problem is that the method resolution code scans that list for methods with the name `bar` -- and this winds up touching *all* the methods, even private ones.
I can imagine two obvious ways to fix this:
- separating fn bodies from fn sigs (#35078, currently being pursued by @flodiebold)
- a more aggressive model of incremental that @michaelwoerister has been advocating, in which we hash the intermediate results (e.g., the outputs of collect) so that we can see that the intermediate result hasn't changed, even if a particular impl item has changed.
So all in all I'm not quite sure whether to land this or not. =) It still seems like it has to be a win in some cases, but not with the test cases we have just now. I can try to gin up some test cases, but I'm not sure if they will be totally realistic. On the other hand, some of the early refactorings to the visitor trait seem worthwhile to me regardless.
cc #36349 -- well, this is basically a fix for that issue, I guess
r? @michaelwoerister
NB: Based atop of @eddyb's PR https://github.com/rust-lang/rust/pull/37402; don't land until that lands.
Improved error reporting when target sysroot is missing.
Attempts to resolve#37131.
This is my first pull request on rust, so I would greatly appreciate any feedback you have on this.
Thanks!
Before, when we created an AssociatedItem for impl item X, we would read
the impl item itself. Now we instead load up the impl I that contains X
and read the data from the `ImplItemRef` for X; actually, we do it for
all impl items in I pre-emptively.
This kills the last source of edges between a method X and a call to a
method Y defined in the same impl.
Fixes#37121
add test for #37765
Adds a test for #37765, a path parsing fix which removes the need for a parenthesis workaround.
Closes#37765.
cc #37290 @withoutboats
r? @petrochenkov
Add semicolon to "perhaps add a `use` for one of them" help
Similar to pull request #37430, this makes the message more copy-paste
friendly and aligns it with other messages like:
help: you can import it into scope: use foo::Bar;
r? @eddyb
coherence: skip impls with an erroneous trait ref
Impls with a erroneous trait ref are already ignored in the first part
of coherence, so ignore them in the second part too. This avoids
cascading coherence errors when 1 impl of a trait has an error.
r? @nikomatsakis
Support `use`ing externally defined macros behind `#![feature(use_extern_macros)]`
With `#![feature(use_extern_macros)]`,
- A name collision between macros from different upstream crates is much less of an issue since we can `use` the macros in different submodules or rename with `as`.
- We can reexport macros with `pub use`, so `#![feature(macro_reexport)]` is no longer needed.
- These reexports are allowed in any module, so crates can expose a macro-modular interface.
If a macro invocation can resolve to both a `use` import and a `macro_rules!` or `#[macro_use]`, it is an ambiguity error.
r? @nrc