typeck: Make sure casts from other types to fat pointers are illegal
Fixes ICEs where non-fat pointers and scalars are cast to fat pointers,
Fixes#21397Fixes#22955Fixes#23237Fixes#24100
The new functionality being tested here is that a drop impl bounded by
`UserDefined` does not cause dropck to inject its conservative
constraints on region inference.
Closes#17841.
The majority of the work should be done, e.g. trait and inherent impls, different forms of UFCS syntax, defaults, and cross-crate usage. It's probably enough to replace the constants in `f32`, `i8`, and so on, or close to good enough.
There is still some significant functionality missing from this commit:
- ~~Associated consts can't be used in match patterns at all. This is simply because I haven't updated the relevant bits in the parser or `resolve`, but it's *probably* not hard to get working.~~
- Since you can't select an impl for trait-associated consts until partway through type-checking, there are some problems with code that assumes that you can check constants earlier. Associated consts that are not in inherent impls cause ICEs if you try to use them in array sizes or match ranges. For similar reasons, `check_static_recursion` doesn't check them properly, so the stack goes ka-blooey if you use an associated constant that's recursively defined. That's a bit trickier to solve; I'm not entirely sure what the best approach is yet.
- Dealing with consts associated with type parameters will raise some new issues (e.g. if you have a `T: Int` type parameter and want to use `<T>::ZERO`). See rust-lang/rfcs#865.
- ~~Unused associated consts don't seem to trigger the `dead_code` lint when they should. Probably easy to fix.~~
Also, this is the first time I've been spelunking in rustc to such a large extent, so I've probably done some silly things in a couple of places.
An actual typeck error is the cause of many failed compilations but an
unrelated bug is being reported instead. It is triggered because a typeck
error is presumably not yet identified during compiler execution, which
would normally bypass an invariant in the presence of other errors. In
this particular situation, we delay the reporting of the bug until
abort_if_errors().
Closes#23827, closes#24356, closes#23041, closes#22897, closes#23966,
closes#24013, and closes#23729
**There is at least one situation where this bug may still be genuinely
triggered (#23437).**
As part of the audit for #22820 the following duplicate feature
gate tests were removed:
* `box_patterns`
* `simd_ffi`
These tests for `box_patterns` and `simd_ffi` were added in #23578,
however there were existing tests in #20723 and #21233 respectively.
r? @nrc
As part of the audit for #22820 the following feature gate tests have been
added:
* `negate_unsigned`
* `on_unimplemented`
* `optin_builtin_traits`
* `plugin`
* `rustc_attrs`
* `rustc_diagnostic_macros`
* `slice_patterns`
In addition some feature gate error message typos fixed.
Rather than storing the relations between free-regions in a global
table, introduce a `FreeRegionMap` data structure. regionck computes the
`FreeRegionMap` for each fn and stores the result into the tcx so that
borrowck can use it (this could perhaps be refactored to have borrowck
recompute the map, but it's a bid tedious to recompute due to the
interaction of closures and free fns). The main reason to do this is
because of #22779 -- using a global table was incorrect because when
validating impl method signatures, we want to use the free region
relationships from the *trait*, not the impl.
Fixes#22779.
As part of the audit for #22820 the following duplicate feature
gate tests were removed:
* `box_patterns`
* `simd_ffi`
These tests for `box_patterns` and `simd_ffi` were added in #23578,
however there were existing tests in #20723 and #21233 respectively.
As part of the audit for #22820 the following feature gate tests have
been added:
* `negate_unsigned`
* `on_unimplemented`
* `optin_builtin_traits`
* `plugin`
* `rustc_attrs`
* `slice_patterns`
This PR uses the inline error suggestions introduced in #24242 to modify a few existing `help` messages. The new errors look like this:
foobar.rs:5:12: 5:25 error: expected a path on the left-hand side of `+`,
not `&'static Copy` [E0178]
foobar.rs:5 let x: &'static Copy + 'static;
^~~~~~~~~~~~~
foobar.rs:5:12: 5:35 help: try adding parentheses (per RFC 438):
foobar.rs: let x: &'static (Copy + 'static);
foobar.rs:2:13: 2:23 error: cast to unsized type: `&_` as `core::marker::Copy`
foobar.rs:2 let x = &1 as Copy;
^~~~~~~~~~
foobar.rs:2:19: 2:23 help: try casting to a reference instead:
foobar.rs: let x = &1 as &Copy;
foobar.rs:7:24: 7:25 error: expected expression, found `;`
foobar.rs:7 let x = box (1 + 1);
^
foobar.rs:7:13: 7:16 help: try using `box()` instead:
foobar.rs: let x = box() (1 + 1);
This also modifies compiletest to give the ability to directly test suggestions given by error messages.
Check for duplicate loop labels in function bodies.
See also: http://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833
The change, which we are putting in as future-proofing in preparation for future potential additions to the language (namely labeling arbitrary blocks and using those labels in borrow expressions), means that code like this will start emitting warnings:
```rust
fn main() {
{ 'a: loop { break; } }
{ 'a: loop { break; } }
}
```
To make the above code compile without warnings, write this instead:
```rust
fn main() {
{ 'a: loop { break; } }
{ 'b: loop { break; } }
}
```
Since this change is only introducing a new warnings, this change is non-breaking.
Fix#21633