Rollup of 5 pull requests
Successful merges:
- #111741 (Use `ObligationCtxt` in custom type ops)
- #111840 (Expose more information in `get_body_with_borrowck_facts`)
- #111876 (Roll compiler_builtins to 0.1.92)
- #111912 (Use `Option::is_some_and` and `Result::is_ok_and` in the compiler )
- #111915 (libtest: Improve error when missing `-Zunstable-options`)
r? `@ghost`
`@rustbot` modify labels: rollup
Always require closure parameters to be `Sized`
The `rust-call` ABI isn't compatible with `#![feature(unsized_fn_params)]`, so trying to use that feature with closures leads to an ICE (#67981). This turns that ICE into a type-check error.
`@rustbot` label A-closures F-unsized_fn_params
fix(resolve): not defined `extern crate shadow_name`
Fixes https://github.com/rust-lang/rust/issues/109148
## Why does #109148 panic?
When resolving `use std::xx` it enters `visit_scopes` from `early_resolve_ident_in_lexical_scope`, and iters twice during the loop:
|iter| `scope` | `break_result` | result |
|-|-|-|-|
| 0 | `Module` pointed to root | binding pointed to `Undetermined`, so result is `None` | scope changed to `ExternPrelude` |
| 1 | `ExternPrelude` | binding pointed to `std` | - |
Then, the result of `maybe_resolve_path` is `Module(std)`, so `import.imported_module.set` is executed.
Finally, during the `finalize_import` of `use std::xx`, `resolve_path` returns `NonModule` because `Binding(Ident(std), Module(root)`'s binding points to `extern crate blah as std`, which causes the assertion to fail at `assert!(import.imported_module.get().is_none());`.
## Investigation
The question is why `#[a] extern crate blah as std` is not defined as a binding of `std::xxx`, which causes the iteration twice during `visit_scopes` when resolving `std::xxx`. Ideally, the value of `break_result.is_some()` should have been valid in the first iteration.
After debugging, I found that because `#[a] extern crate blah as std` had been dummied by `placeholder` during `collect_invocations`, so it had lost its attrs, span, etc..., so it will not be defined. However, `expand_invoc` added them back, then the next `build_reduced_graph`, `#[a] extern crate blah as std` would have been defined, so it makes the result of `resolved_path` unexpected, and the program panics.
## Try to solve
I think there has two-way to solve this issue:
- Expand invocations before the first `resolve_imports` during `fully_expand_fragment`. However, I do not think this is a good idea because it would mess up the current design.
- As my PR described: do not define to `extern crate blah as std` during the second `build_reduced_graph`, which is very easy and more reasonable.
r? `@petrochenkov`
The `rust-call` ABI isn't compatible with
`#![feature(unsized_fn_params)]`, so trying to use that feature with
closures leads to an ICE (#67981). This turns that ICE into a
type-check error.
Don't ICE if method receiver fails to unify with `arbitrary_self_types`
Consider:
```rust
struct Foo(u32);
impl Foo {
fn get<R: Deref<Target=Self>>(self: R) -> u32 {
self.0
}
}
fn main() {
let mut foo = Foo(1);
foo.get::<&Foo>();
}
```
The problem here is that with `arbitrary_self_types`, we're allowed to have a method receiver that mentions generics from the method itself (`fn get<R: Deref<Target=Self>>(self: R)`). Since we don't actually take into account the user-written turbofish generics when doing method lookup (nor do we check that method predicates hold), method probing will happily infer `R = Foo` during the probe. When we later confirm the method, we do use the turbofish'd subst and instead now have that `R = &Foo`. This doesn't unify with the self type we chose during the probe, causing an ICE.
Getting this to work correctly will be difficult. Specifically, we'll need to actually pass in the turbofish generics for the method being probed for and check that the self type unifies considering those generics. This seems like a lot of work, and I'm not actually familiar with the restrictions originally called out for `#![feature(arbitrary_self_types)]`, but I think we should probably instead just deny having receivers that mention (type/const) generics that come from the method itself.
But I mostly just want to turn this ICE into an error, so I'll leave that up for later PRs.
Fixes#111838
Check opaques for mismatch during writeback
Revive #111705.
I realized that we don't need to put any substs in the writeback results since all of the hidden types have already been remapped. See the comment in `compiler/rustc_middle/src/ty/typeck_results.rs`, which should make that clear for other explorers of the codebase.
Additionally, we need to do some diagnostic stashing because the diagnostics we produce during HIR typeck is very poor and we should prefer the diagnostic that comes from MIR, if we have one.
r? `@oli-obk`
Remove return type sized check hack from hir typeck
Remove a bunch of special-cased suggestions when someone returns `-> dyn Trait` that checks for type equality, etc.
This was a pretty complex piece of code that also relied on a hack in hir typeck (see changes to `compiler/rustc_hir_typeck/src/check.rs`), and I'm not convinced that it's necessary to maintain, when all we really need to tell the user is that they should return `-> impl Trait` or `-> Box<dyn Trait>`, depending on their specific use-case.
This is necessary because we may need to move the "return type is sized" check from hir typeck to wfcheck, which does not have access to typeck results. This is a prerequisite for that, and I'm fairly confident that the diagnostics "regressions" here are not a big deal.
Deal with unnormalized projections when structurally resolving types with new solver
1. Normalize types in `structurally_resolved_type` when the new solver is enabled
2. Normalize built-in autoderef targets in `Autoderef` when the new solver is enabled
3. Normalize-erasing-regions in `resolve_type` in writeback
This is motivated by the UI test provided, which currently fails with:
```
error[E0609]: no field `x` on type `<usize as SliceIndex<[Foo]>>::Output`
--> <source>:9:11
|
9 | xs[0].x = 1;
| ^
```
I'm pretty happy with the approach in (1.) and (2.) and think we'll inevitably need something like this in the long-term, but (3.) seems like a hack to me. It's a *lot* of work to add tons of new calls to every user of these typeck results though (mir build, late lints, etc). Happy to discuss further.
r? `@lcnr`
Give better error when collecting into `&[T]`
The detection of slice reference of `{integral}` in `rustc_on_unimplemented` is hacky, but a proper solution requires changing `FmtPrinter` to add a parameter to print integers as `{integral}` and I didn't want to change it just for `rustc_on_unimplemented`. I can do that if requested, though.
I'm open to better wording; this is the best I could come up with.
fix recursion depth handling after confirmation
fixes#111729
I think having to use `Obligation::with_depth` correctly everywhere is very hard because e.g. the nested obligations from `eq` currently do not have the correct obligation depth.
The new solver [completely removes `recursion_depth` from obligations](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/traits/solve/struct.Goal.html) and instead tracks the depth in the solver itself which is far easier to get right. Moving the old solver towards this shouldn't be that hard but is probably somewhat annoying.
r? `@matthewjasper`
Fix overflow in error emitter
Fix#109854Close#94171 (was already fixed before but missing test)
This bug happens when a multipart suggestion spans more than one line.
The fix is to update the `acc` variable, which didn't handle the case when the text to remove spans multiple lines but the text to add spans only one line.
Also, use `usize::try_from` instead of `as usize` to detect overflows earlier in the future, and point to the source of the overflow (the original issue points to a different place where this value is used, not where the overflow had happened).
And finally add an `if start != end` check to avoid doing any extra work in case of empty ranges.
Long explanation:
Given this test case:
```rust
fn generate_setter() {
String::with_capacity(
//~^ ERROR this function takes 1 argument but 3 arguments were supplied
generate_setter,
r#"
pub(crate) struct Person<T: Clone> {}
"#,
r#""#,
);
}
```
The compiler will try to convert that code into the following:
```rust
fn generate_setter() {
String::with_capacity(
//~^ ERROR this function takes 1 argument but 3 arguments were supplied
/* usize */,
);
}
```
So it creates a suggestion with 3 separate parts:
```
// Replace "generate_setter" with "/* usize */"
SubstitutionPart { span: fuzz_input.rs:4:5: 4:20 (#0), snippet: "/* usize */" }
// Remove second arg (multiline string)
SubstitutionPart { span: fuzz_input.rs:4:20: 7:3 (#0), snippet: "" }
// Remove third arg (r#""#)
SubstitutionPart { span: fuzz_input.rs:7:3: 8:11 (#0), snippet: "" }
```
Each of this parts gets a separate `SubstitutionHighlight` (this marks the relevant text green in a terminal, the values are 0-indexed so `start: 4` means column 5):
```
SubstitutionHighlight { start: 4, end: 15 }
SubstitutionHighlight { start: 15, end: 15 }
SubstitutionHighlight { start: 18446744073709551614, end: 18446744073709551614 }
```
The 2nd and 3rd suggestion are empty (start = end) because they only remove text, so there are no additions to highlight. But the 3rd span has overflowed because the compiler assumes that the 3rd suggestion is on the same line as the first suggestion. The 2nd span starts at column 20 and the highlight starts at column 16 (15+1), so that suggestion is good. But since the 3rd span starts at column 3, the result is `3 - 4`, or column -1, which turns into -2 with 0-indexed, and that's equivalent to `18446744073709551614 as isize`.
With this fix, the resulting `SubstitutionHighlight` are:
```
SubstitutionHighlight { start: 4, end: 15 }
SubstitutionHighlight { start: 15, end: 15 }
SubstitutionHighlight { start: 15, end: 15 }
```
As expected. I guess ideally we shouldn't emit empty highlights when removing text, but I am too scared to change that.
Add more tests for the offset_of macro
Implements what I [suggested in the tracking issue](https://github.com/rust-lang/rust/issues/106655#issuecomment-1535007205), plus some further improvements:
* ensuring that offset_of!(Self, ...) works iff inside an impl block
* ensuring that the output type is usize and doesn't coerce. this can be changed in the future, but if it is done, it should be a conscious decision
* improving the privacy checking test
* ensuring that generics don't let you escape the unsized check
r? `````@WaffleLapkin`````
Dont check `must_use` on nested `impl Future` from fn
Fixes (but does not close, per beta policy) #111484
Also fixes a `FIXME` left in the code about (presumably) false-positives on non-async `#[must_use] fn() -> impl Future` cases, though if that's not desirable to include in the beta backport then I can certainly revert it.
Beta nominating as it fixes a beta ICE.
Fix dependency tracking for debugger visualizers
This PR fixes dependency tracking for debugger visualizer files by changing the `debugger_visualizers` query to an `eval_always` query that scans the AST while it is still available. This way the set of visualizer files is already available when dep-info is emitted. Since the query is turned into an `eval_always` query, dependency tracking will now reliably detect changes to the visualizer script files themselves.
TODO:
- [x] perf.rlo
- [x] Needs a bit more documentation in some places
- [x] Needs regression test for the incr. comp. case
Fixes https://github.com/rust-lang/rust/issues/111226
Fixes https://github.com/rust-lang/rust/issues/111227
Fixes https://github.com/rust-lang/rust/issues/111295
r? `@wesleywiser`
cc `@gibbyfree`
Shorten even more panic temporary lifetimes
Followup to #104134. As pointed out by `@bjorn3` in https://github.com/rust-lang/rust/pull/104134#pullrequestreview-1425585948, there are other cases in the panic macros which would also benefit from dropping their non-Send temporaries as soon as possible, avoiding pointlessly holding them across an await point.
For the tests added in this PR, here are the failures you get today on master without the macro changes in this PR:
<details>
<summary>tests/ui/macros/panic-temporaries-2018.rs</summary>
```console
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries-2018.rs:52:18
|
LL | require_send(panic_display());
| ^^^^^^^^^^^^^^^ future returned by `panic_display` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries-2018.rs:35:31
|
LL | f(panic!("{}", NOT_SEND)).await;
| -------- ^^^^^- `NOT_SEND` is later dropped here
| | |
| | await occurs here, with `NOT_SEND` maybe used later
| has type `NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries-2018.rs:48:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries-2018.rs:52:18
|
LL | require_send(panic_display());
| ^^^^^^^^^^^^^^^ future returned by `panic_display` is not `Send`
|
= help: within `NotSend`, the trait `Sync` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries-2018.rs:35:31
|
LL | f(panic!("{}", NOT_SEND)).await;
| ---------------------- ^^^^^- the value is later dropped here
| | |
| | await occurs here, with the value maybe used later
| has type `&NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries-2018.rs:48:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries-2018.rs:53:18
|
LL | require_send(panic_str());
| ^^^^^^^^^^^ future returned by `panic_str` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries-2018.rs:40:36
|
LL | f(panic!((NOT_SEND, "...").1)).await;
| -------- ^^^^^- `NOT_SEND` is later dropped here
| | |
| | await occurs here, with `NOT_SEND` maybe used later
| has type `NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries-2018.rs:48:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries-2018.rs:54:18
|
LL | require_send(unreachable_display());
| ^^^^^^^^^^^^^^^^^^^^^ future returned by `unreachable_display` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries-2018.rs:45:31
|
LL | f(unreachable!(NOT_SEND)).await;
| -------- ^^^^^- `NOT_SEND` is later dropped here
| | |
| | await occurs here, with `NOT_SEND` maybe used later
| has type `NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries-2018.rs:48:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries-2018.rs:54:18
|
LL | require_send(unreachable_display());
| ^^^^^^^^^^^^^^^^^^^^^ future returned by `unreachable_display` is not `Send`
|
= help: within `NotSend`, the trait `Sync` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries-2018.rs:45:31
|
LL | f(unreachable!(NOT_SEND)).await;
| ---------------------- ^^^^^- the value is later dropped here
| | |
| | await occurs here, with the value maybe used later
| has type `&NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries-2018.rs:48:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: aborting due to 5 previous errors
```
</details>
<details>
<summary>tests/ui/macros/panic-temporaries.rs</summary>
```console
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries.rs:42:18
|
LL | require_send(panic_display());
| ^^^^^^^^^^^^^^^ future returned by `panic_display` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries.rs:35:31
|
LL | f(panic!("{}", NOT_SEND)).await;
| -------- ^^^^^- `NOT_SEND` is later dropped here
| | |
| | await occurs here, with `NOT_SEND` maybe used later
| has type `NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries.rs:38:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
--> tests/ui/macros/panic-temporaries.rs:42:18
|
LL | require_send(panic_display());
| ^^^^^^^^^^^^^^^ future returned by `panic_display` is not `Send`
|
= help: within `NotSend`, the trait `Sync` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> tests/ui/macros/panic-temporaries.rs:35:31
|
LL | f(panic!("{}", NOT_SEND)).await;
| ---------------------- ^^^^^- the value is later dropped here
| | |
| | await occurs here, with the value maybe used later
| has type `&NotSend` which is not `Send`
note: required by a bound in `require_send`
--> tests/ui/macros/panic-temporaries.rs:38:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: aborting due to 2 previous errors
```
</details>
r? bjorn3
do not allow inference in `predicate_must_hold` (alternative approach)
See the FCP description for more info, but tl;dr is that we should not return `EvaluatedToOkModuloRegions` if an obligation may hold only with some choice of inference vars being constrained.
Attempts to solve this in the approach laid out by lcnr here: https://github.com/rust-lang/rust/pull/109558#discussion_r1147318134, rather than by eagerly replacing infer vars with placeholders which is a bit too restrictive.
r? `@ghost`
fix(resolve): replace bindings to dummy for unresolved imports
close#109343
In #109343, `f` in `pub use f as g` points to:
|namespace| binding|
|-|-|
|type| `external crate f`|
|value| `None` |
|macro| `None` |
When resolve `value_ns` during `resolve_doc_links`, the value of the binding of single_import `pub use f as g` goes to `pub use inner::f`, and since it does not satisfy [!self.is_accessible_from(binding.vis, single_import.parent_scope.module)](https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/ident.rs#L971) and returns `Err(Undetermined)`, which eventually goes to `PathResult::Indeterminate => unreachable!`.
This PR replace all namespace binding to `dummy_binding` for indeterminate import, so, the bindings of `pub use f as g` had been changed to followings after finalize:
|namespace| binding|
|-|-|
|type| `dummy`|
|value| `dummy` |
|macro| `dummy` |
r?`@petrochenkov`
Do not recover when parsing stmt in cfg-eval.
`parse_stmt` does recovery on its own. When parsing the statement fails, we always get `Ok(None)` instead of an `Err` variant with the diagnostic that we can emit.
To avoid this behaviour, we need to opt-out of recovery for cfg_eval.
Fixes https://github.com/rust-lang/rust/issues/105228
* ensuring that offset_of!(Self, ...) works iff inside an impl block
* ensuring that the output type is usize and doesn't coerce. this can be
changed in the future, but if it is done, it should be a conscious descision
* improving the privacy checking test
* ensuring that generics don't let you escape the unsized check