Commit Graph

248 Commits

Author SHA1 Message Date
Niko Matsakis
d4e4e374e7 apply minimum bounds when checking closure signature
Required for test expect-fn-supply-fn.rs to pass; otherwise we have
unconstrained inference variables that get inferred to `'empty`.
2018-10-27 09:06:03 -04:00
kennytm
46f504543d
Rollup merge of #55258 - Aaron1011:fix/rustdoc-blanket, r=GuillaumeGomez
Fix Rustdoc ICE when checking blanket impls

Fixes #55001, #54744

Previously, SelectionContext would unconditionally cache the selection
result for an obligation. This worked fine for most users of
SelectionContext, but it caused an issue when used by Rustdoc's blanket
impl finder.

The issue occured when SelectionContext chose a ParamCandidate which
contained inference variables. Since inference variables can change
between calls to select(), it's not safe to cache the selection result -
the chosen candidate might not be applicable for future results, leading
to an ICE when we try to run confirmation.

This commit prevents SelectionContext from caching any ParamCandidate
that contains inference variables. This should always be completely
safe, as trait selection should never depend on a particular result
being cached.

I've also added some extra debug!() statements, which I found helpful in
tracking down this bug.
2018-10-26 18:24:59 +08:00
Aaron Hill
4f2624cac9
Fix Rustdoc ICE when checking blanket impls
Fixes #55001, #54744

Previously, SelectionContext would unconditionally cache the selection
result for an obligation. This worked fine for most users of
SelectionContext, but it caused an issue when used by Rustdoc's blanket
impl finder.

The issue occured when SelectionContext chose a ParamCandidate which
contained inference variables. Since inference variables can change
between calls to select(), it's not safe to cache the selection result -
the chosen candidate might not be applicable for future results, leading
to an ICE when we try to run confirmation.

This commit prevents SelectionContext from caching any ParamCandidate
that contains inference variables. This should always be completely
safe, as trait selection should never depend on a particular result
being cached.

I've also added some extra debug!() statements, which I found helpful in
tracking down this bug.
2018-10-22 19:40:43 -04:00
Fabian Drinck
2f41c0d194 Rename InferTy::CanonicalTy to BoundTy and add DebruijnIndex to variant type 2018-10-20 19:16:23 +02:00
Oliver Scherer
ab3f37ec43 Free some memory instead of just dropping elements 2018-10-19 14:34:44 +02:00
Oliver Scherer
3c9258e604 Prefer Default::default over FxHash*::default in struct constructors 2018-10-19 14:34:44 +02:00
Oliver Scherer
ee81739dc1 Deprecate the FxHashMap() and FxHashSet() constructor function hack 2018-10-19 14:34:44 +02:00
bors
5ea8eb55cd Auto merge of #55067 - ljedrz:generic_iterator_related_improvements, r=petrochenkov
A few iterator-related improvements

- typeck: don't collect into a vector when unnecessary
- create only one vector when winnowing candidates
- change a cloning map to `into_iter`
2018-10-16 07:04:10 +00:00
ljedrz
354a965ede create only one vector when winnowing candidates 2018-10-14 17:20:45 +02:00
Oliver Scherer
78aaa3e546 Check the invariant for principal inside the method 2018-10-13 11:32:49 +02:00
Niko Matsakis
068a6a256c remove occurences of skolemization 2018-10-04 11:02:40 -04:00
Niko Matsakis
21aaaac29b remove all occurences of skolemize 2018-10-04 11:02:40 -04:00
Niko Matsakis
0887456401 extend NLL universe code to have >1 placeholder within one universe 2018-10-04 11:02:40 -04:00
Niko Matsakis
4cd4eae435 rename skolemized to placeholder 2018-10-04 11:02:40 -04:00
Niko Matsakis
a96510d066 select.rs: rustfmt 2018-10-04 11:02:39 -04:00
Pietro Albini
2503db8e61
Rollup merge of #54789 - scalexm:unnormalized, r=nikomatsakis
Introduce `TyKind::UnnormalizedProjection`

Introduce a new variant used for lazy normalization in chalk integration. Mostly `bug!` everywhere.

r? @nikomatsakis
2018-10-04 12:20:16 +02:00
scalexm
608adfc3f0 Introduce TyKind::UnnormalizedProjection 2018-10-03 17:06:28 +02:00
Ariel Ben-Yehuda
1069c0e38f add a special case for literal 'static: 'a where-clauses
This makes evaluation more consistent with fulfillment.
2018-10-01 22:44:45 +03:00
Ariel Ben-Yehuda
53a4b39909 handle outlives predicates in trait evaluation
Fixes #54302.
2018-10-01 22:44:45 +03:00
bors
fc403ad987 Auto merge of #53255 - orium:fix-bug-overflow-send, r=arielb1
Add a per-tree error cache to the obligation forest

This implements part of what @nikomatsakis mentioned in  https://github.com/rust-lang/rust/pull/30533#issuecomment-170705871:

> 1. If you find that a new obligation is a duplicate of one already in the tree, the proper processing is:
>      * if that other location is your parent, you should abort with a cycle error (or accept it, if coinductive)
>      * if that other location is not an ancestor, you can safely ignore the new obligation

In particular it implements the "if that other location is your parent accept it, if coinductive" part.  This fixes #40827.

I have to say that I'm not 100% confident that this is rock solid.  This is my first pull request 🎉, and I didn't know anything about the trait resolver before this.  In particular I'm not totally sure that comparing predicates is enough (for instance, do we need to compare `param_env` as well?).  Also, I'm not sure what @nikomatsakis mentions [here](https://github.com/rust-lang/rust/issues/30977#issue-127091096), but it might be something that affects this PR:

> In particular, I am wary of getting things wrong around inference variables! We can always add things to the set in their current state, and if unifications occur then the obligation is just kind of out-of-date, but I want to be sure we don't accidentally fail to notice that something is our ancestor. I decided this was subtle enough to merit its own PR.

Anyway, go ahead and review 🙂.

Ref #30977.

# Performance

We are now copying vectors around, so I decided to do some benchmarking.  A simple benchmark shows that this does not seem to affect performance in a measurable way:

I ran `cargo clean && cargo build` 20 times on actix-web (84b27db) and these are the results:

```text
rustc master:

            Mean        Std.Dev.    Min         Median      Max
real        66.637      2.996       57.220      67.714      69.314
user        307.293     14.741      258.093     312.209     320.702
sys         12.524      0.653       10.499      12.726      13.193

rustc fix-bug-overflow-send:

            Mean        Std.Dev.    Min         Median      Max
real        66.297      4.310       53.532      67.516      70.348
user        306.812     22.371      236.917     314.748     326.229
sys         12.757      0.952       9.671       13.125      13.544
```

I will do a more comprehensive benchmark (compiling rustc stage1) and post the results.

r? @nikomatsakis, @nnethercote

PS: It is better to review this commit-by-commit.
2018-09-30 19:41:07 +00:00
Diogo Sousa
d2ff5d696c Typos and style fixes. 2018-09-30 20:01:28 +01:00
Zack M. Davis
5b22d9b2ca don't elide lifetimes in paths in librustc/
This seemed like a good way to kick the tires on the
elided-lifetimes-in-paths lint (#52069)—seems to work! This was also
pretty tedious—it sure would be nice if `cargo fix` worked on this
codebase (#53896)!
2018-09-29 21:48:29 -07:00
Eduard-Mihai Burtescu
7020326bea rustc: keep a Span for each predicate in ty::GenericPredicates. 2018-09-28 17:19:35 +03:00
bors
e783d2be40 Auto merge of #54199 - nikomatsakis:predicate_may_hold-failure, r=eddyb
overlook overflows in rustdoc trait solving

Context:

The new rustdoc "auto trait" feature walks across impls and tries to run trait solving on them with a lot of unconstrained variables. This is prone to overflows. These overflows used to cause an ICE because of a caching bug (fixed in this PR). But even once that is fixed, it means that rustdoc causes an overflow rather than generating docs.

This PR therefore adds a new helper that propagates the overflow error out. This requires rustdoc to then decide what to do when it encounters such an overflow: technically, an overflow represents neither "yes" nor "no", but rather a failure to make a decision. I've decided to opt on the side of treating this as "yes, implemented", since rustdoc already takes an optimistic view. This may prove to include too many items, but I *suspect* not.

We could probably reduce the rate of overflows by unifying more of the parameters from the impl -- right now we only seem to consider the self type. Moreover, in the future, as we transition to Chalk, overflow errors are expected to just "go away" (in some cases, though, queries might return an ambiguous result).

Fixes #52873

cc @QuietMisdreavus -- this is the stuff we were talking about earlier
cc @GuillaumeGomez -- this supersedes #53687
2018-09-26 12:39:20 +00:00
Pietro Albini
167a045e2e
Rollup merge of #54370 - nnethercote:better-domain_size, r=nikomatsakis
Improve handling of type bounds in `bit_set.rs`.

Currently, `BitSet` doesn't actually know its own domain size; it just
knows how many words it contains. We can make it better.
2018-09-22 09:56:32 +02:00
kennytm
2d0262e44e
Rollup merge of #54295 - ljedrz:cleanups_rustc_traits, r=nikomatsakis
A few cleanups and minor improvements to rustc/traits

It's a little bigger than usual, so bear with me ^^:

- introduce `TyCtxt::all_impls` and use it to avoid inefficiently allocating push loops
- modify `ArgKind::from_expected_ty` to take an `Option<Span>` argument to make it more versatile
- replace `ArgKind::Arg("_".to_owned(), "_".to_owned())` with `ArgKind::empty`
- move early `return`s earlier where possible
- if all branches of a `match` end with the same expression, move it after it
- change a hacky `match` expression to an `if else` chain
- move the `push` out from a push loop closure to reduce the number of allocations
- correct the vector size for `pretty_predicates` (under `specialize`)
- take advantage of the fact that `if else` is an expression
- prefer `cloned()` to `map(|&x| x)` and `map(|x| *x)`
- prefer `vec![x; y.len()]` to `y.map(|_| x).collect()`
- use `unwrap_or_else` instead of `match` where applicable
- use `if let` instead of `match` when only one branch matters
- prefer `to_owned` to `to_string` for string literals
- remove explicit `return`s
- remove superfluous braces
- whitespace fixes
- several other minor improvements
2018-09-20 21:36:27 +08:00
Nicholas Nethercote
99f05e800e Improve handling of type bounds in bit_set.rs.
Currently, `BitSet` doesn't actually know its own domain size; it just
knows how many words it contains. To improve things, this commit makes
the following changes.

- It changes `BitSet` and `SparseBitSet` to store their own domain size,
  and do more precise bounds and same-size checks with it. It also
  changes the signature of `BitSet::to_string()` (and puts it within
  `impl ToString`) now that the domain size need not be passed in from
  outside.

- It uses `derive(RustcDecodable, RustcEncodable)` for `BitSet`. This
  required adding code to handle `PhantomData` in `libserialize`.

- As a result, it removes the domain size from `HybridBitSet`, making a
  lot of that code nicer.

- Both set_up_to() and clear_above() were overly general, working with
  arbitrary sizes when they are only needed for the domain size. The
  commit removes the former, degeneralizes the latter, and removes the
  (overly general) tests.

- Changes `GrowableBitSet::grow()` to `ensure()`, fixing a bug where a
  (1-based) domain size was confused with a (0-based) element index.

- Changes `BitMatrix` to store its row count, and do more precise bounds
  checks with it.

- Changes `ty_params` in `select.rs` from a `BitSet` to a
  `GrowableBitSet` because it repeatedly failed the new, more precise
  bounds checks. (Changing the type was simpler than computing an
  accurate domain size.)

- Various other minor improvements.
2018-09-20 08:52:41 +10:00
ljedrz
a8ec8e5cb7 A few cleanups and minor improvements to rustc/traits 2018-09-18 08:48:39 +02:00
Nicholas Nethercote
266e2d3d69 Merge indexed_set.rs into bitvec.rs, and rename it bit_set.rs.
Currently we have two files implementing bitsets (and 2D bit matrices).
This commit combines them into one, taking the best features from each.

This involves renaming a lot of things. The high level changes are as
follows.
- bitvec.rs              --> bit_set.rs
- indexed_set.rs         --> (removed)
- BitArray + IdxSet      --> BitSet (merged, see below)
- BitVector              --> GrowableBitSet
- {,Sparse,Hybrid}IdxSet --> {,Sparse,Hybrid}BitSet
- BitMatrix              --> BitMatrix
- SparseBitMatrix        --> SparseBitMatrix

The changes within the bitset types themselves are as follows.

```
OLD             OLD             NEW
BitArray<C>     IdxSet<T>       BitSet<T>
--------        ------          ------
grow            -               grow
new             -               (remove)
new_empty       new_empty       new_empty
new_filled      new_filled      new_filled
-               to_hybrid       to_hybrid
clear           clear           clear
set_up_to       set_up_to       set_up_to
clear_above     -               clear_above
count           -               count
contains(T)     contains(&T)    contains(T)
contains_all    -               superset
is_empty        -               is_empty
insert(T)       add(&T)         insert(T)
insert_all      -               insert_all()
remove(T)       remove(&T)      remove(T)
words           words           words
words_mut       words_mut       words_mut
-               overwrite       overwrite
merge           union           union
-               subtract        subtract
-               intersect       intersect
iter            iter            iter
```

In general, when choosing names I went with:
- names that are more obvious (e.g. `BitSet` over `IdxSet`).
- names that are more like the Rust libraries (e.g. `T` over `C`,
  `insert` over `add`);
- names that are more set-like (e.g. `union` over `merge`, `superset`
  over `contains_all`, `domain_size` over `num_bits`).

Also, using `T` for index arguments seems more sensible than `&T` --
even though the latter is standard in Rust collection types -- because
indices are always copyable. It also results in fewer `&` and `*`
sigils in practice.
2018-09-18 07:08:09 +10:00
Niko Matsakis
f58f2c8efa don't cache overflow results globally 2018-09-13 13:40:33 -04:00
ms2300
6c14360c32 Changing TyAnon -> TyOpaque and relevant functions 2018-09-05 13:01:16 -06:00
Matthias Krüger
ede1f7d2a5 use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into() 2018-08-23 10:14:52 +02:00
varkor
8a5dccde2a Remove Ty prefix from Ty{Bool|Char|Int|Uint|Float|Str} 2018-08-22 16:08:49 +01:00
varkor
04fa5d3adb Remove Ty prefix from Ty{Foreign|Param} 2018-08-22 16:07:55 +01:00
varkor
6f637da50c Remove Ty prefix from Ty{Adt|Array|Slice|RawPtr|Ref|FnDef|FnPtr|Dynamic|Closure|Generator|GeneratorWitness|Never|Tuple|Projection|Anon|Infer|Error} 2018-08-22 16:07:44 +01:00
bors
81cfaad030 Auto merge of #53212 - sunjay:nll-raw-cast, r=nikomatsakis
NLL - Prevent where clauses from extending the lifetime of bindings

Fixes https://github.com/rust-lang/rust/issues/53123

r? @nikomatsakis
2018-08-15 06:54:18 +00:00
ljedrz
b187c4268c Consider changing assert! to debug_assert! when it calls visit_with 2018-08-10 08:40:30 +02:00
Sunjay Varma
644765197a Preferring BuiltInCandidate { has_nested: false } in all cases 2018-08-09 15:05:24 -06:00
ljedrz
44d32d4413 Avoid unnecessary pattern matching against Option and Result 2018-08-07 10:24:27 +02:00
Mark Rousskov
9bc4fbb10a Split out growth functionality into BitVector type 2018-08-01 06:50:40 -06:00
Niko Matsakis
7bbbed9046 drive-by nits and debug
Co-authored-by: Tyler Mandry <tmandry@gmail.com>
2018-07-02 10:38:35 -04:00
Alex Kitchens
fdc2275609 Update broken rustc-guide links
Recently, there has been some rearrangement of the content in the Rustc
Guide, and this commit changes the urls the match the updated guide.
2018-06-24 22:00:39 -05:00
Matthew Jasper
ba35e80534 Reenable trivial bounds
Removes extra global bounds at the winnowing stage rather than when
normalizing the param_env. This avoids breaking inference when there is
a global bound.
2018-06-08 17:00:03 +01:00
kennytm
5b67b13d1e
Rollup merge of #50932 - nnethercote:seen-Predicates, r=eddyb
Optimize seen Predicate filtering.

This speeds up a few rustc-perf benchmark runs, most notably ones
involving 'coercions', the best by 2%.
2018-05-23 00:26:15 +08:00
Eduard-Mihai Burtescu
196b2e0d82 rustc: don't call Kind::from directly, use .into() instead. 2018-05-21 12:13:19 +03:00
Eduard-Mihai Burtescu
e3df729c25 rustc: make mk_substs_trait take &[Kind] instead of &[Ty]. 2018-05-21 12:13:17 +03:00
Nicholas Nethercote
2ff632484c Optimize seen Predicate filtering.
This speeds up a few rustc-perf benchmark runs, most notably ones
involving 'coercions', the best by 2%.
2018-05-21 18:43:25 +10:00
Matthew Jasper
d0ec8ea1cc Implement RFC 2056 - trivial constraints 2018-05-15 11:37:33 +01:00
bors
0a223d139c Auto merge of #50395 - Zoxc:small-tys, r=michaelwoerister
Optimize layout of TypeVariants

This makes references to `Slice` use thin pointers by storing the slice length in the slice itself. `GeneratorInterior` is replaced by storing the movability of generators in `TyGenerator` and the interior witness is stored in `GeneratorSubsts` (which is just a wrapper around `&'tcx Substs`, like `ClosureSubsts`). Finally the fields of `TypeAndMut` is stored inline in `TyRef`. These changes combine to reduce `TypeVariants` from 48 bytes to 24 bytes on x86_64.

r? @michaelwoerister
2018-05-10 14:14:35 +00:00
John Kåre Alsaker
c9d9c249ec Insert fields from TypeAndMut into TyRef to allow layout optimization 2018-05-08 16:21:58 +02:00