1
Fork 0
Commit graph

60 commits

Author SHA1 Message Date
Oli Scherer
956db072a8 Don't fall back to crate-level opaque type definitions.
That would just hide bugs, as it works accidentally if the opaque type
is defined at the crate level.
2022-01-12 14:06:11 +00:00
Nicholas Nethercote
f09b1facd0 Eliminate ObligationCauseData.
This makes `Obligation` two words bigger, but avoids allocating a lot of
the time.

I previously tried this in #73983 and it didn't help much, but local
timings look more promising now.
2021-12-20 09:29:20 +11:00
LegionMammal978
375524014f Remove in_band_lifetimes from rustc_infer
This crate actually had a typo `'ctx` in one of its functions:
```diff
-pub fn same_type_modulo_infer(a: Ty<'tcx>, b: Ty<'ctx>) -> bool {
+pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
```
2021-12-13 17:53:27 -05:00
Matthias Krüger
1f2a26e999
Rollup merge of #90023 - b-naber:postpone_const_eval_infer_vars, r=nikomatsakis
Postpone the evaluation of constant expressions that depend on inference variables

Previously `delay_span_bug` calls were triggered once an inference variable was included in the substs of a constant that was to be evaluated. Some of these would merely have resulted in trait candidates being rejected, hence no real error was ever encountered, but the triggering of the `delay_span_bug` then caused an ICE in later stages of the compiler due to no error ever occurring.
We now postpone the evaluation of these constants, so any trait obligation fulfillment will simply stall on this constant and the existing type inference machinery of the compiler handles any type errors if present.

Fixes https://github.com/rust-lang/rust/issues/89320
Fixes https://github.com/rust-lang/rust/issues/89146
Fixes https://github.com/rust-lang/rust/issues/87964
Fixes https://github.com/rust-lang/rust/issues/87470
Fixes https://github.com/rust-lang/rust/issues/83288
Fixes https://github.com/rust-lang/rust/issues/83249
Fixes https://github.com/rust-lang/rust/issues/90654

I want to thank `@BoxyUwU` for cooperating on this and for providing some help.

r? `@lcnr` maybe?
2021-12-05 00:37:58 +01:00
Alan Egerton
bfc434b6d0
Reduce boilerplate around infallible folders 2021-12-02 16:14:16 +00:00
LeSeulArtichaut
30bf20a692
Unwrap the results of type folders
Co-authored-by: Alan Egerton <eggyal@gmail.com>
2021-11-26 07:38:25 +00:00
LeSeulArtichaut
6dc3dae46f
Adapt TypeFolder implementors to return a Result
Co-authored-by: Alan Egerton <eggyal@gmail.com>
2021-11-26 07:25:16 +00:00
Jacob Pratt
7b103e7dd2
Use derive_default_enum in the compiler 2021-11-22 20:17:53 -05:00
Matthew Jasper
3ea84e879a Remove unused field of RegionVariableOrigin 2021-11-11 23:15:47 +00:00
Matthew Jasper
9734c03524 Remove some fields from ObligationCauseCode 2021-11-07 13:20:02 +00:00
bors
9d39f6ab7d Auto merge of #89970 - jackh726:gats_diagnostics, r=nikomatsakis
Implementation of GATs outlives lint

See #87479 for background. Closes #87479

The basic premise of this lint/error is to require the user to write where clauses on a GAT when those bounds can be implied or proven from any function on the trait returning that GAT.

## Intuitive Explanation (Attempt) ##
Let's take this trait definition as an example:
```rust
trait Iterable {
    type Item<'x>;
    fn iter<'a>(&'a self) -> Self::Item<'a>;
}
```
Let's focus on the `iter` function. The first thing to realize is that we know that `Self: 'a` because of `&'a self`. If an impl wants `Self::Item` to contain any data with references, then those references must be derived from `&'a self`. Thus, they must live only as long as `'a`. Furthermore, because of the `Self: 'a` implied bound, they must live only as long as `Self`. Since it's `'a` is used in place of `'x`, it is reasonable to assume that any value of `Self::Item<'x>`, and thus `'x`, will only be able to live as long as `Self`. Therefore, we require this bound on `Item` in the trait.

As another example:
```rust
trait Deserializer<T> {
    type Out<'x>;
    fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>;
}
```
The intuition is similar here, except rather than a `Self: 'a` implied bound, we have a `T: 'a` implied bound. Thus, the data on `Self::Out<'a>` is derived from `&'a T`, and thus it is reasonable to expect that the lifetime `'x` will always be less than `T`.

## Implementation Algorithm ##
* Given a GAT `<P0 as Trait<P1..Pi>>::G<Pi...Pn>` declared as `trait T<A1..Ai> for A0 { type G<Ai...An>; }` used in return type of one associated function `F`
* Given env `E` (including implied bounds) for `F`
* For each lifetime parameter `'a` in `P0...Pn`:
    * For each other type parameter `Pi != 'a` in `P0...Pn`: // FIXME: this include of lifetime parameters too
        * If `E => (P: 'a)`:
            * Require where clause `Ai: 'a`

## Follow-up questions ##
* What should we do when we don't pass params exactly?
For this example:
```rust
trait Des {
    type Out<'x, D>;
    fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>;
}
```
Should we be requiring a `D: 'x` clause? We pass `Wrap<T>` as `D` and `'z` as `'x`, and should be able to prove that `Wrap<T>: 'z`.

r? `@nikomatsakis`
2021-11-06 04:15:22 +00:00
b-naber
dae2407368 resolve variables before erasing lifetimes 2021-11-05 18:40:26 +01:00
b-naber
7530c43b79 postpone evaluation of constants whose substs depend on inference vars or regions 2021-11-05 18:40:26 +01:00
Oli Scherer
4413f8c709 Member constraints already covered all of E0482 already, so that error never occurred anymore 2021-10-18 15:50:56 +00:00
jackh726
82148cdc66 Change outlives clause checking algorithm 2021-10-16 19:04:39 -04:00
Oli Scherer
9b5aa063d8 More tracing instrumentation 2021-09-28 12:28:22 +00:00
bors
900cf5e890 Auto merge of #88804 - Mark-Simulacrum:never-algo-v2, r=nikomatsakis,jackh726
Revise never type fallback algorithm

This is a rebase of https://github.com/rust-lang/rust/pull/84573, but dropping the stabilization of never type (and the accompanying large test diff).

Each commit builds & has tests updated alongside it, and could be reviewed in a more or less standalone fashion. But it may make more sense to review the PR as a whole, I'm not sure. It should be noted that tests being updated isn't really a good indicator of final behavior -- never_type_fallback is not enabled by default in this PR, so we can't really see the full effects of the commits here.

This combines the work by Niko, which is [documented in this gist](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660), with some additional rules largely derived to target specific known patterns that regress with the algorithm solely derived by Niko. We build these from an intuition that:

* In general, fallback to `()` is *sound* in all cases
* But, in general, we *prefer* fallback to `!` as it accepts more code, particularly that written to intentionally use `!` (e.g., Result's with a Infallible/! variant).

When evaluating Niko's proposed algorithm, we find that there are certain cases where fallback to `!` leads to compilation failures in real-world code, and fallback to `()` fixes those errors. In order to allow for stabilization, we need to fix a good portion of these patterns.

The final rule set this PR proposes is that, by default, we fallback from `?T` to `!`, with the following exceptions:

1. `?T: Foo` and `Bar::Baz = ?T` and `(): Foo`, then fallback to `()`
2. Per [Niko's algorithm](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660#proposal-fallback-chooses-between--and--based-on-the-coercion-graph), the "live" `?T` also fallback to `()`.

The first rule is necessary to address a fairly common pattern which boils down to something like the snippet below. Without rule 1, we do not see the closure's return type as needing a () fallback, which leads to compilation failure.

```rust
#![feature(never_type_fallback)]

trait Bar { }
impl Bar for () {  }
impl Bar for u32 {  }

fn foo<R: Bar>(_: impl Fn() -> R) {}

fn main() {
    foo(|| panic!());
}
```

r? `@jackh726`
2021-09-23 22:45:22 +00:00
Oli Scherer
dfb11a8a26 Add helper function to InferCtxt that generates inference vars for unresolved associated types 2021-09-20 13:57:56 +00:00
Niko Matsakis
bc2ece2a8d stop categorizing inference variables as diverging when created
Instead, we now rely on the code that looks for a NeverToAny adjustment.
2021-09-17 12:47:48 -04:00
Niko Matsakis
2ee89144e2 introduce new fallback algorithm
We now fallback type variables using the following rules:

* Construct a coercion graph `A -> B` where `A` and `B` are unresolved
  type variables or the `!` type.
* Let D be those variables that are reachable from `!`.
* Let N be those variables that are reachable from a variable not in
D.
* All variables in (D \ N) fallback to `!`.
* All variables in (D & N) fallback to `()`.
2021-09-17 12:47:48 -04:00
jackh726
af9de99f12 Detect stricter constraints on gats where clauses in impls vs trait 2021-09-07 18:30:58 -04:00
lcnr
bc0156bace shrink ty::PredicateKind again 2021-08-26 11:00:30 +02:00
lcnr
caa975c89e use ty::Unevaluated instead of def substs pair 2021-08-26 11:00:30 +02:00
lcnr
bfaf13af4e make unevaluated const substs optional 2021-08-26 11:00:30 +02:00
bors
91f9806208 Auto merge of #88166 - BoxyUwU:const-equate-canon, r=lcnr
canonicalize consts before calling try_unify_abstract_consts query

Fixes #88022
Fixes #86953
Fixes #77708
Fixes #82034
Fixes #85031

these ICEs were all caused by calling the `try_unify_abstract_consts` query with inference vars in substs

r? `@lcnr`
2021-08-22 18:00:22 +00:00
Niko Matsakis
60cc00f540 move fallback_if_possible and friends to fallback.rs
Along the way, simplify and document the logic more clearly.
2021-08-20 17:27:50 -04:00
Niko Matsakis
020655b90d move the sub-unify check and extend the documentation a bit
I didn't like the sub-unify code executing when a predicate was
ENQUEUED, that felt fragile. I would have preferred to move the
sub-unify code so that it only occurred during generalization, but
that impacted diagnostics, so having it also occur when we process
subtype predicates felt pretty reasonable. (I guess we only need one
or the other, but I kind of prefer both, since the generalizer
ultimately feels like the *right* place to guarantee the properties we
want.)
2021-08-20 17:27:50 -04:00
Niko Matsakis
947c0de028 introduce a Coerce predicate 2021-08-19 17:28:24 -04:00
Niko Matsakis
7e0ae7d89b introduce a Diverging enum instead of a bool 2021-08-19 17:28:24 -04:00
Ellen
c2b61fbafe move code to InferCtxt method 2021-08-19 21:04:09 +01:00
Matthew Jasper
d563a63788 Report nicer errors for HRTB NLL errors from queries 2021-08-15 09:11:01 +02:00
Matthew Jasper
5e6027c6bf Track causes for universes created during borrowck 2021-08-15 09:10:46 +02:00
Matthew Jasper
842f0590db Show bound lifetimes when comparing types in diagnostics 2021-08-15 08:44:35 +02:00
Oli Scherer
238d974fc6 Document with_opaque_type_inference's use cases. 2021-08-06 10:49:35 +00:00
Oli Scherer
1b9ad13941 Use existing type alias instead of manually writing it 2021-08-06 10:44:16 +00:00
Oli Scherer
b2c1919a3d Store the DefId of the currently typechecked item in InferCtxt
This allows opaque type inference to check for defining uses without having to pass down that def id via function arguments to every method that could possibly cause an opaque type to be compared with a concrete type
2021-08-06 10:39:23 +00:00
Oli Scherer
d99805982b Move opaque type cache into InferCtxt 2021-08-06 10:12:31 +00:00
Esteban Küber
e5d42af6ba Point at unmet explicit lifetime obligation bound 2021-07-31 07:56:01 -07:00
Aaron Hill
3291218f47
Improve caching during trait evaluation
Previously, we would 'forget' that we had `'static` regions in some
place during trait evaluation. This lead to us producing
`EvaluatedToOkModuloRegions` when we could have produced
`EvaluatedToOk`, causing us to perform unnecessary work.

This PR preserves `'static` regions when we canonicalize a predicate for
`evaluate_obligation`, and when we 'freshen' a predicate during trait
evaluation. Thie ensures that evaluating a predicate containing
`'static` regions can produce `EvaluatedToOk` (assuming that we
don't end up introducing any region dependencies during evaluation).

Building off of this improved caching, we use
`predicate_must_hold_considering_regions` during fulfillment of
projection predicates to see if we can skip performing additional work.
We already do this for trait predicates, but doing this for projection
predicates lead to mixed performance results without the above caching
improvements.
2021-07-21 17:54:05 -05:00
lcnr
513c56a611 remove unused variant 2021-05-06 14:59:53 +02:00
Jack Huey
62a49c3bb8 Add tcx lifetime to Binder 2021-03-31 10:13:57 -04:00
Joshua Nelson
441dc3640a Remove (lots of) dead code
Found with https://github.com/est31/warnalyzer.

Dubious changes:
- Is anyone else using rustc_apfloat? I feel weird completely deleting
  x87 support.
- Maybe some of the dead code in rustc_data_structures, in case someone
  wants to use it in the future?
- Don't change rustc_serialize

  I plan to scrap most of the json module in the near future (see
  https://github.com/rust-lang/compiler-team/issues/418) and fixing the
  tests needed more work than I expected.

TODO: check if any of the comments on the deleted code should be kept.
2021-03-27 22:16:33 -04:00
lcnr
7c9b5b4ce0 update const_eval_resolve 2021-03-20 17:22:24 +01:00
Harald van Dijk
95e096d623
Change x64 size checks to not apply to x32.
Rust contains various size checks conditional on target_arch = "x86_64",
but these checks were never intended to apply to
x86_64-unknown-linux-gnux32. Add target_pointer_width = "64" to the
conditions.
2021-03-06 16:02:48 +00:00
Hirochika Matsumoto
f8e0e78d75 Rename NLL* to Nll* accordingly to C-CASE 2021-01-28 16:18:25 +09:00
LingMan
a56bffb4f9 Use Option::map_or instead of .map(..).unwrap_or(..) 2021-01-14 19:23:59 +01:00
Matthias Krüger
6e852cc4ce remove redundant clones (clippy::redundant_clone) 2020-12-24 12:59:22 +01:00
Jack Huey
328fcee4af Make BoundRegion have a kind of BoungRegionKind 2020-12-18 15:27:28 -05:00
bors
e0ef0fc392 Auto merge of #78779 - LeSeulArtichaut:ty-visitor-return, r=oli-obk
Introduce `TypeVisitor::BreakTy`

Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`

~~Blocked on FCP in rust-lang/compiler-team#383.~~
2020-11-17 12:24:34 +00:00
Bastian Kauschke
2bf93bd852 compiler: fold by value 2020-11-16 22:34:57 +01:00