Commit Graph

47 Commits

Author SHA1 Message Date
Camille GILLOT
e2d41f4c97 Make nested RPITIT inherit the parent opaque's generics. 2022-12-04 14:38:20 +00:00
Vadim Petrochenkov
6cd4dd3091 rustc_hir: Relax lifetime requirements on Visitor::visit_path 2022-12-01 17:04:02 +03:00
bors
454784afba Auto merge of #104048 - cjgillot:split-lifetime, r=compiler-errors
Separate lifetime ident from lifetime resolution in HIR

Drive-by: change how suggested generic args are computed.
Fixes https://github.com/rust-lang/rust/issues/103815

I recommend reviewing commit-by-commit.
2022-11-27 14:30:19 +00:00
Santiago Pastorino
974e2837bb
Introduce PredicateKind::Clause 2022-11-25 00:04:54 -03:00
Camille GILLOT
1c737d6997 Use kw::Empty for elided lifetimes in path. 2022-11-24 17:48:59 +00:00
Camille GILLOT
fb7d25e978 Separate lifetime ident from resolution in HIR. 2022-11-23 19:33:06 +00:00
bors
7fe6f36224 Auto merge of #103491 - cjgillot:self-rpit, r=oli-obk
Support using `Self` or projections inside an RPIT/async fn

I reuse the same idea as https://github.com/rust-lang/rust/pull/103449 to use variances to encode whether a lifetime parameter is captured by impl-trait.

The current implementation of async and RPIT replace all lifetimes from the parent generics by `'static`.  This PR changes the scheme
```rust
impl<'a> Foo<'a> {
    fn foo<'b, T>() -> impl Into<Self> + 'b { ... }
}

opaque Foo::<'_a>::foo::<'_b, T>::opaque<'b>: Into<Foo<'_a>> + 'b;
impl<'a> Foo<'a> {
    // OLD
    fn foo<'b, T>() -> Foo::<'static>::foo::<'static, T>::opaque::<'b> { ... }
                             ^^^^^^^ the `Self` becomes `Foo<'static>`

    // NEW
    fn foo<'b, T>() -> Foo::<'a>::foo::<'b, T>::opaque::<'b> { ... }
                             ^^ the `Self` stays `Foo<'a>`
}
```

There is the same issue with projections. In the example, substitute `Self` by `<T as Trait<'b>>::Assoc` in the sugared version, and `Foo<'_a>` by `<T as Trait<'_b>>::Assoc` in the desugared one.

This allows to support `Self` in impl-trait, since we do not replace lifetimes by `'static` any more.  The same trick allows to use projections like `T::Assoc` where `Self` is allowed.  The feature is gated behind a `impl_trait_projections` feature gate.

The implementation relies on 2 tweaking rules for opaques in 2 places:
- we only relate substs that correspond to captured lifetimes during TypeRelation;
- we only list captured lifetimes in choice region computation.

For simplicity, I encoded the "capturedness" of lifetimes as a variance, `Bivariant` vs `Invariant` for unused vs captured lifetimes. The `variances_of` query used to ICE for opaques.

Impl-trait that do not reference `Self` or projections will have their variances as:
- `o` (invariant) for each parent type or const;
- `*` (bivariant) for each parent lifetime --> will not participate in borrowck;
- `o` (invariant) for each own lifetime.

Impl-trait that does reference `Self` and/or projections will have some parent lifetimes marked as `o` (as the example above), and participate in type relation and borrowck.  In the example above, `variances_of(opaque) = ['_a: o, '_b: *, T: o, 'b: o]`.

r? types
cc `@compiler-errors` , as you asked about the issue with `Self` and projections.
2022-11-21 12:17:03 +00:00
Camille GILLOT
607d0c2a14 Store a LocalDefId in hir::AnonConst. 2022-11-13 14:06:11 +00:00
Camille GILLOT
18482f7b23 Store a LocalDefId in hir::GenericParam. 2022-11-13 14:05:30 +00:00
Camille GILLOT
290f0781b4 Store LocalDefId in hir::Closure. 2022-11-13 14:04:02 +00:00
Camille GILLOT
c5949c8bee Create bidirectional bounds between original and duplicated parameters. 2022-11-13 09:01:29 +00:00
Camille GILLOT
49a5aa4f0c Verify predicates on RPIT and async opaques. 2022-11-12 10:03:28 +00:00
Camille GILLOT
6c95805a34 Clean-up formatting. 2022-11-11 10:32:49 +00:00
Camille GILLOT
3075f03513 Resolve lifetimes using the regular logic for RPIT. 2022-11-11 10:12:28 +00:00
Camille GILLOT
44c10e4cb0 Resolve lifetimes independently for each item-like. 2022-11-11 10:11:50 +00:00
Manish Goregaokar
f162e3a1b1
Rollup merge of #100508 - BoxyUwU:make_less_things_late_bound, r=nikomatsakis
avoid making substs of type aliases late bound when used as fn args

fixes #47511
fixes #85533
(although I did not know theses issues existed when i was working on this 🙃)

currently `Alias<...>` is treated the same as `Struct<...>` when deciding if generics should be late bound or early bound but this is not correct as `Alias` might normalize to a projection which does not constrain the generics.

I think this needs more tests before merging
more explanation of PR [here](https://hackmd.io/v44a-QVjTIqqhK9uretyQg?view)

Hackmd inline for future readers:
---

This assumes reader is familiar with the concept of early/late bound lifetimes. There's a section on rustc-dev-guide if not (although i think some details are a bit out of date)

## problem & background

Not all lifetimes on a fn can be late bound:
```rust
fn foo<'a>() -> &'a ();
impl<'a> Fn<()> for FooFnDef {
    type Output = &'a (); // uh oh unconstrained lifetime
}
```
so we make make them early bound
```rust
fn foo<'a>() -> &'a ();
impl<'a> Fn<()> for FooFnDef<'a> {// wow look at all that lifetimey
     type Output = &'a ();
}
```
(Closures have the same constraint however it is not enforced leading to soundness bugs, [#84385](https://github.com/rust-lang/rust/pull/84385) implements this "downgrading late bound to early bound" for closures)

lifetimes on fn items are only late bound when they are "constrained" by the fn args:
```rust
fn foo<'a>(_: &'a ()) -> &'a ();
//               late bound, not present on `FooFnItem`
//               vv
impl<'a> Trait<(&'a (),)> for FooFnItem {
    type Output = &'a ();
}

// projections do not constrain inputs
fn bar<'a, T: Trait>(_: <T as Trait<'a>>::Assoc) -> &'a (); //  early bound
                                                            //  vv
impl<'a, T: Trait> Fn<(<T as Trait<'a>>::Assoc,)> for BarFnItem<'a, T> {
    type Output = &'a ();
}
```

current logic for determining if inputs "constrain" a lifetime works off of HIR so does not normalize aliases. It also assumes that any path with no self type constrains all its substs (i.e. `Foo<'a, u32>` has no self type but `T::Assoc` does). This falls apart for top level type aliases (see linked issues):

```rust
type Alias<'a, T> = <T as Trait<'a>>::Assoc;
//                      wow look its a path with no self type uwu
//                      i bet that constrains `'a` so it should be latebound
//                      vvvvvvvvvvv
fn foo<'a, T: Trait>(_: Alias<'a, T>) -> &'a ();
//                     `Alias` normalized to make things clearer
//                     vvvvvvvvvvvvvvvvvvvvvvv
impl<'a, T: Trait> Fn<(<T as Trait<'a>>::Assoc,)> for FooFnDef<T> {
    type Output = &'a ();
    // oh no `'a` isnt constrained wah wah waaaah *trumbone noises*
    // i think, idk what musical instrument that is
}
```

## solution

The PR solves this by having the hir visitor that checks for lifetimes in constraining uses check if the path is a `DefKind::Alias`. If it is we ""normalize"" it by calling `type_of` and walking the returned type. This is a bit hacky as it requires a mapping between the substs on the path in hir, and the generics of the `type Alias<...>` which is on the ty layer.

Alternative solutions may involve calculating the "late boundness" of lifetimes after/during astconv rather than relying on hir at all. We already have code to determine whether a lifetime SHOULD be late bound or not as this is currently how the error for `fn foo<'a, T: Trait>(_: Alias<'a, T>) -> &'a ();` gets emitted.

It is probably not possible to do this right now, late boundness is used by `generics_of` and `gather_explicit_predicates_of` as we currently do not put late bound lifetimes in `Generics`. Although this seems sus to me as the long term goal is to make all generics late bound which would result in `generics_of(function)` being empty? [#103448](https://github.com/rust-lang/rust/pull/103448) places all lifetimes in `Generics` regardless of late boundness so that may be a good step towards making this possible.
2022-11-08 21:03:51 -05:00
Boxy
49be827dca comment 2022-11-08 21:59:58 +00:00
yukang
1f21b96dce add 'ty_error_with_guaranteed' and 'const_error_with_guaranteed' 2022-11-08 11:17:46 +08:00
Boxy
c0889a6005 fixyfixfix 2022-11-06 13:39:18 +00:00
Matthias Krüger
d10187f040
Rollup merge of #103780 - compiler-errors:bound-closure-lifetimes, r=jackh726
Fix late-bound lifetime closure ICEs in HIR typeck and MIR borrowck

During HIR typeck, we need to teach astconv to treat late-bound regions within a closure body as free, fixing escaping bound vars ICEs in both of the issues below.

However, this then gets us to MIR borrowck, which itself needs to be taught how to instantiate free region vids for late-bound regions that come from items that _aren't_ the typeck root (for now, just closures).

Fixes #103771
Fixes #103736
2022-11-04 12:18:01 +01:00
Zhixing Zhang
744fa610eb fix(generic_const_exprs): Fix predicate inheritance for children of opaque types 2022-11-01 15:41:16 -07:00
Michael Goulet
9f28de513a Free late-bound lifetimes in closures as well 2022-10-31 01:47:19 +00:00
Guillaume Gomez
692a22e735
Rollup merge of #103618 - nnethercote:rename-OwnerId-fields, r=compiler-errors
Rename some `OwnerId` fields.

`@spastorino` noticed some silly expressions like `item_id.def_id.def_id`.

This commit renames several `def_id: OwnerId` fields as `owner_id`, so those expressions become `item_id.owner_id.def_id`.

`item_id.owner_id.local_def_id` would be even clearer, but the use of `def_id` for values of type `LocalDefId` is *very* widespread, so I left that alone.

r? `@compiler-errors`
2022-10-29 14:18:03 +02:00
Nicholas Nethercote
c8c25ce5a1 Rename some OwnerId fields.
spastorino noticed some silly expressions like `item_id.def_id.def_id`.

This commit renames several `def_id: OwnerId` fields as `owner_id`, so
those expressions become `item_id.owner_id.def_id`.

`item_id.owner_id.local_def_id` would be even clearer, but the use of
`def_id` for values of type `LocalDefId` is *very* widespread, so I left
that alone.
2022-10-29 20:28:38 +11:00
Matthias Krüger
790a716420
Rollup merge of #103383 - compiler-errors:tait-scope, r=oli-obk
Note scope of TAIT more accurately

This maybe explains why the person was confused in #101897, since we say "same module" but really should've said "same impl".

r? ``@oli-obk``
2022-10-29 08:57:35 +02:00
Boxy
b3425587a6 tidy + move logic to fn 2022-10-27 22:29:16 +01:00
Boxy
ca5a6e43dd use proper spans 2022-10-27 22:18:26 +01:00
Boxy
c00ff9c4d0 DoIt 2022-10-27 21:48:47 +01:00
Oli Scherer
b6824ba52a Make param index generation a bit more robust 2022-10-24 12:27:05 +00:00
Michael Goulet
4accf838f6 Note scope of TAIT more accurately 2022-10-22 03:09:49 +00:00
lcnr
660ca48041 change ConstEvaluatable to use ty::Const 2022-10-18 16:09:04 +02:00
bors
60bd3f9677 Auto merge of #102700 - oli-obk:0xDEAD_TAIT, r=compiler-errors
Check hidden types in dead code

fixes #99490

r? `@compiler-errors`

best reviewed commit by commit
2022-10-13 22:39:05 +00:00
bors
0938e1680d Auto merge of #101679 - compiler-errors:rpitit-default-body, r=nikomatsakis
Support default-body trait functions with return-position `impl Trait` in traits

Introduce a new `Trait` candidate kind for the `ImplTraitInTrait` projection candidate, which just projects an RPITIT down to its opaque type form.

This is a hack until we lower RPITITs to regular associated types, after which we will need to rework how these default bodies are type-checked, so comments are left in a few places for us to clean up later.

Fixes #101665
2022-10-12 21:03:47 +00:00
Camille GILLOT
a474ec50b7 Move lifetime resolution module to rustc_hir_analysis. 2022-10-10 17:40:52 +00:00
Yuki Okushi
24424d0acb
Rollup merge of #102829 - compiler-errors:rename-impl-item-kind, r=TaKO8Ki
rename `ImplItemKind::TyAlias` to `ImplItemKind::Type`

The naming of this variant seems inconsistent given that this is not really a "type alias", and the associated type variant for `TraitItemKind` is just called `Type`.
2022-10-10 00:09:42 +09:00
Michael Goulet
70f3c79c50 ImplItemKind::TyAlias => ImplItemKind::Type 2022-10-09 07:09:57 +00:00
Oli Scherer
f85d3a7e33 Check hidden types in dead code 2022-10-07 19:43:46 +00:00
Oli Scherer
5d15beb591 Unconditionally encode hidden types in typeck results 2022-10-07 19:36:32 +00:00
Takayuki Maeda
fa767868df fix a ICE #102768 2022-10-07 21:10:08 +09:00
Michael Goulet
21047f1a1c Support default-body trait functions with RPITIT 2022-10-05 02:45:01 +00:00
Maybe Waffle
a8f7e244b7 Refactor rustc lint API 2022-10-01 10:03:06 +00:00
bors
65445a571c Auto merge of #102471 - Dylan-DPC:rollup-ij3okjt, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #102336 (Fix associated type bindings with anon const in GAT position)
 - #102342 (Add negation methods for signed non-zero integers.)
 - #102385 (Don't export `__heap_base` and `__data_end` on wasm32-wasi.)
 - #102435 (Improve example of Iterator::reduce)
 - #102436 (rustdoc: clean up "normalize.css 8" input override CSS)
 - #102452 (fix minor ungrammatical sentence)
 - #102455 (Use let-chaining in `WhileTrue::check_expr`.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
2022-09-29 13:27:28 +00:00
Oli Scherer
6367e69929 Split collect.rs 2022-09-29 09:31:46 +00:00
Michael Goulet
92561f43f1 Support bindings with anon consts in generics 2022-09-27 17:42:15 +00:00
Michael Goulet
05267b5a50 Make type_of work correctly for const arg bindings 2022-09-27 17:42:14 +00:00
Michael Goulet
cca48285b8 Format type_of 2022-09-27 17:42:13 +00:00
lcnr
1fc86a63f4 rustc_typeck to rustc_hir_analysis 2022-09-27 10:37:23 +02:00