about summary refs log tree commit diff
path: root/src/test/ui
AgeCommit message (Collapse)AuthorLines
2022-01-20Rollup merge of #93061 - estebank:macr-suggestion, r=cjgillotMatthias Krüger-23/+68
Only suggest adding `!` to expressions that can be macro invocation
2022-01-20Rollup merge of #91032 - eholk:generator-drop-tracking, r=nikomatsakisMatthias Krüger-80/+413
Introduce drop range tracking to generator interior analysis This PR addresses cases such as this one from #57478: ```rust struct Foo; impl !Send for Foo {} let _: impl Send = || { let guard = Foo; drop(guard); yield; }; ``` Previously, the `generator_interior` pass would unnecessarily include the type `Foo` in the generator because it was not aware of the behavior of `drop`. We fix this issue by introducing a drop range analysis that finds portions of the code where a value is guaranteed to be dropped. If a value is dropped at all suspend points, then it is no longer included in the generator type. Note that we are using "dropped" in a generic sense to include any case in which a value has been moved. That is, we do not only look at calls to the `drop` function. There are several phases to the drop tracking algorithm, and we'll go into more detail below. 1. Use `ExprUseVisitor` to find values that are consumed and borrowed. 2. `DropRangeVisitor` uses consume and borrow information to gather drop and reinitialization events, as well as build a control flow graph. 3. We then propagate drop and reinitialization information through the CFG until we reach a fix point (see `DropRanges::propagate_to_fixpoint`). 4. When recording a type (see `InteriorVisitor::record`), we check the computed drop ranges to see if that value is definitely dropped at the suspend point. If so, we skip including it in the type. ## 1. Use `ExprUseVisitor` to find values that are consumed and borrowed. We use `ExprUseVisitor` to identify the places where values are consumed. We track both the `hir_id` of the value, and the `hir_id` of the expression that consumes it. For example, in the expression `[Foo]`, the `Foo` is consumed by the array expression, so after the array expression we can consider the `Foo` temporary to be dropped. In this process, we also collect values that are borrowed. The reason is that the MIR transform for generators conservatively assumes anything borrowed is live across a suspend point (see `rustc_mir_transform::generator::locals_live_across_suspend_points`). We match this behavior here as well. ## 2. Gather drop events, reinitialization events, and control flow graph After finding the values of interest, we perform a post-order traversal over the HIR tree to find the points where these values are dropped or reinitialized. We use the post-order index of each event because this is how the existing generator interior analysis refers to the position of suspend points and the scopes of variables. During this traversal, we also record branching and merging information to handle control flow constructs such as `if`, `match`, and `loop`. This is necessary because values may be dropped along some control flow paths but not others. ## 3. Iterate to fixed point The previous pass found the interesting events and locations, but now we need to find the actual ranges where things are dropped. Upon entry, we have a list of nodes ordered by their position in the post-order traversal. Each node has a set of successors. For each node we additionally keep a bitfield with one bit per potentially consumed value. The bit is set if we the value is dropped along all paths entering this node. To compute the drop information, we first reverse the successor edges to find each node's predecessors. Then we iterate through each node, and for each node we set its dropped value bitfield to the intersection of all incoming dropped value bitfields. If any bitfield for any node changes, we re-run the propagation loop again. ## 4. Ignore dropped values across suspend points At this point we have a data structure where we can ask whether a value is guaranteed to be dropped at any post order index for the HIR tree. We use this information in `InteriorVisitor` to check whether a value in question is dropped at a particular suspend point. If it is, we do not include that value's type in the generator type. Note that we had to augment the region scope tree to include all yields in scope, rather than just the last one as we did before. r? `@nikomatsakis`
2022-01-19Rollup merge of #92316 - petrochenkov:extmangle, r=wesleywiserMatthias Krüger-0/+39
mangling_v0: Skip extern blocks during mangling There's no need to include the dummy `Nt` into the symbol name, items in extern blocks belong to their parent modules for all purposes except for inheriting the ABI and attributes. Follow up to https://github.com/rust-lang/rust/pull/92032 (There's also a drive-by fix to the `rust-demangler` tool's tests, which don't run on CI, I initially attempted using them for testing this PR.)
2022-01-19Only suggest adding `!` to expressions that can be macro invocationEsteban Kuber-23/+68
2022-01-19Rollup merge of #92783 - FabianWolff:issue-92726, r=nikomatsakisMatthias Krüger-0/+33
Annotate dead code lint with notes about ignored derived impls Fixes #92726. CC `@pmetzger,` is this what you had in mind? r? `@nikomatsakis`
2022-01-19Rollup merge of #88642 - c410-f3r:let_chains_2, r=matthewjasperMatthias Krüger-304/+463
Formally implement let chains ## Let chains My longest and hardest contribution since #64010. Thanks to `@Centril` for creating the RFC and special thanks to `@matthewjasper` for helping me since the beginning of this journey. In fact, `@matthewjasper` did much of the complicated MIR stuff so it's true to say that this feature wouldn't be possible without him. Thanks again `@matthewjasper!` With the changes proposed in this PR, it will be possible to chain let expressions along side local variable declarations or ordinary conditional expressions. In other words, do much of what the `if_chain` crate already does. ## Other considerations * `if let guard` and `let ... else` features need special care and should be handled in a following PR. * Irrefutable patterns are allowed within a let chain context * ~~Three Clippy lints were already converted to start dogfooding and help detect possible corner cases~~ cc #53667
2022-01-18Formally implement let chainsCaio-304/+463
2022-01-18Respond to code review commentsEric Holk-4/+69
2022-01-18Safely handle partial dropsEric Holk-2/+83
We previously weren't tracking partial re-inits while being too aggressive around partial drops. With this change, we simply ignore partial drops, which is the safer, more conservative choice.
2022-01-18Update async-fn-nonsend.rsEric Holk-5/+43
The previous commit made the non_sync_with_method_call case pass due to the await being unreachable. Unfortunately, this isn't actually the behavior the test was verifying. This change lifts the panic into a helper function so that the generator analysis still thinks the await is reachable, and therefore we preserve the same testing behavior.
2022-01-18Handle uninhabited return typesEric Holk-29/+3
This changes drop range analysis to handle uninhabited return types such as `!`. Since these calls to these functions do not return, we model them as ending in an infinite loop.
2022-01-18Handle empty loops betterEric Holk-4/+12
2022-01-18Handle reinits in match guardsEric Holk-0/+25
2022-01-18Update stderr filesEric Holk-5/+5
2022-01-18Address code review commentsEric Holk-0/+21
1. Add test case for partial drops 2. Simplify code in `propagate_to_fixpoint` and remove most clones 3. Clean up PostOrderIndex creation
2022-01-18Update async-fn-nonsend.stderrEric Holk-29/+6
2022-01-18Handle more cases with conditionally initialized/dropped valuesEric Holk-2/+42
2022-01-18Basic loop supportEric Holk-1/+1
2022-01-18Support reinitialization of variablesEric Holk-22/+81
2022-01-18Support conditional dropsEric Holk-0/+22
This adds support for branching and merging control flow and uses this to correctly handle the case where a value is dropped in one branch of an if expression but not another. There are other cases we need to handle, which will come in follow up patches. Issue #57478
2022-01-18Attribute drop to parent expression of the consume pointEric Holk-8/+40
This is needed to handle cases like `[a, b.await, c]`. `ExprUseVisitor` considers `a` to be consumed when it is passed to the array, but the array is not quite live yet at that point. This means we were missing the `a` value across the await point. Attributing drops to the parent expression means we do not consider the value consumed until the consuming expression has finished. Issue #57478
2022-01-18Make generator and async-await tests passEric Holk-3/+2
The main change needed to make this work is to do a pessimistic over- approximation for AssignOps. The existing ScopeTree analysis in region.rs works by doing both left to right and right to left order and then choosing the most conservative ordering. This behavior is needed because AssignOp's evaluation order depends on whether it is a primitive type or an overloaded operator, which runs as a method call. This change mimics the same behavior as region.rs in generator_interior.rs. Issue #57478
2022-01-18Track drops across multiple yieldsEric Holk-0/+40
2022-01-18Track drop points in generator_interiorEric Holk-69/+7
This change adds the basic infrastructure for tracking drop ranges in generator interior analysis, which allows us to exclude dropped types from the generator type. Not yet complete, but many of the async/await and generator tests pass. The main missing piece is tracking branching control flow (e.g. around an `if` expression). The patch does include support, however, for multiple yields in th e same block. Issue #57478
2022-01-18Add test case for #57478Eric Holk-0/+14
2022-01-18Rollup merge of #92780 - b-naber:postpone-const-eval-coherence, r=lcnrMatthias Krüger-4/+40
Directly use ConstValue for single literals in blocks Addresses the minimal repro in https://github.com/rust-lang/rust/issues/92186, but doesn't fix the underlying problem (which would be solved by solving the anon subst problem afaict). I do, however, think that it makes sense in general to treat single literals in anon blocks as const values directly, especially in light of the problem that the issue refers to (anon const evaluation being postponed until infer variables in substs can be resolved, which was introduced by https://github.com/rust-lang/rust/pull/90023), i.e. while we do get warnings for those unnecessary braces, we should try to avoid errors caused by those braces if possible.
2022-01-18Rollup merge of #92425 - calebzulawski:simd-cast, r=workingjubileeMatthias Krüger-0/+69
Improve SIMD casts * Allows `simd_cast` intrinsic to take `usize` and `isize` * Adds `simd_as` intrinsic, which is the same as `simd_cast` except for saturating float-to-int conversions (matching the behavior of `as`). cc `@workingjubilee`
2022-01-18Rollup merge of #91150 - dtolnay:qpath, r=davidtwcoMatthias Krüger-1/+13
Let qpath contain NtTy: `<$:ty as $:ty>::…` Example: ```rust macro_rules! m { (<$type:ty as $trait:ty>::$name:ident) => { <$type as $trait>::$name }; } fn main() { let _: m!(<str as ToOwned>::Owned); } ``` Previous behavior: ```console error: expected identifier, found `ToOwned` --> src/main.rs:3:19 | 3 | <$type as $trait>::$name | ^^^^^^ expected identifier ... 8 | let _: m!(<str as ToOwned>::Owned); | --------------------------- | | | this macro call doesn't expand to a type | in this macro invocation ``` The <code>expected identifier, found \`ToOwned\`</code> error is particularly silly. I think it should be fine to accept this code as long as $trait is of the form `TyKind::Path(None, path)`; if it is any other kind of `NtTy`, we'll keep the same behavior as before.
2022-01-18Rollup merge of #90782 - ricobbe:binutils-dlltool, r=michaelwoeristerMatthias Krüger-60/+10
Implement raw-dylib support for windows-gnu Add support for `#[link(kind = "raw-dylib")]` on windows-gnu targets. Work around binutils's linker's inability to read import libraries produced by LLVM by calling out to the binutils `dlltool` utility to create an import library from a temporary .DEF file; this approach is effectively a slightly refined version of `@mati865's` earlier attempt at this strategy in PR #88801. (In particular, this attempt at this strategy adds support for `#[link_ordinal(...)]` as well.) In support of #58713.
2022-01-18Auto merge of #87648 - JulianKnodt:const_eq_constrain, r=oli-obkbors-30/+138
allow eq constraints on associated constants Updates #70256 (cc `@varkor,` `@Centril)`
2022-01-18Rollup merge of #92997 - woppopo:test92114, r=Mark-SimulacrumMatthias Krüger-3/+23
Add `~const` bound test for negative impls Resolves #92114 which has been fixed in #92892.
2022-01-18Rollup merge of #92701 - ehuss:even-more-attr-validation, r=matthewjasperMatthias Krüger-161/+327
Add some more attribute validation This adds some more validation for the position of attributes: * `link` is only valid on an `extern` block * `windows_subsystem` and `no_builtins` are only valid at the crate level
2022-01-18Rollup merge of #92640 - compiler-errors:array-deref-on-newtype, r=lcnrMatthias Krüger-0/+44
Fix ICEs related to `Deref<Target=[T; N]>` on newtypes 1. Stash a const infer's type into the canonical var during canonicalization, so we can recreate the fresh const infer with that same type. For example, given `[T; _]` we know `_` is a `usize`. If we go from infer => canonical => infer, we shouldn't forget that variable is a usize. Fixes #92626 Fixes #83704 2. Don't stash the autoderef'd slice type that we get from method lookup, but instead recreate it during method confirmation. We need to do this because the type we receive back after picking the method references a type variable that does not exist after probing is done. Fixes #92637 ... A better solution for the second issue would be to actually _properly_ implement `Deref` for `[T; N]` instead of fixing this autoderef hack to stop leaking inference variables. But I actually looked into this, and there are many complications with const impls.
2022-01-17Update with final commentskadmin-24/+5
2022-01-17Add term to ExistentialProjectionkadmin-8/+118
Also prevent ICE when adding a const in associated const equality.
2022-01-17Update term for use in more placeskadmin-1/+1
Replace use of `ty()` on term and use it in more places. This will allow more flexibility in the future, but slightly worried it allows items which are consts which only accept types.
2022-01-17Rollup merge of #92164 - WaffleLapkin:rustc_must_implement_one_of_attr, ↵Matthias Krüger-0/+256
r=Aaron1011 Implement `#[rustc_must_implement_one_of]` attribute This PR adds a new attribute — `#[rustc_must_implement_one_of]` that allows changing the "minimal complete definition" of a trait. It's similar to GHC's minimal `{-# MINIMAL #-}` pragma, though `#[rustc_must_implement_one_of]` is weaker atm. Such attribute was long wanted. It can be, for example, used in `Read` trait to make transitions to recently added `read_buf` easier: ```rust #[rustc_must_implement_one_of(read, read_buf)] pub trait Read { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { let mut buf = ReadBuf::new(buf); self.read_buf(&mut buf)?; Ok(buf.filled_len()) } fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> { default_read_buf(|b| self.read(b), buf) } } impl Read for Ty0 {} //^ This will fail to compile even though all `Read` methods have default implementations // Both of these will compile just fine impl Read for Ty1 { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { /* ... */ } } impl Read for Ty2 { fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> { /* ... */ } } ``` For now, this is implemented as an internal attribute to start experimenting on the design of this feature. In the future we may want to extend it: - Allow arbitrary requirements like `a | (b & c)` - Allow multiple requirements like - ```rust #[rustc_must_implement_one_of(a, b)] #[rustc_must_implement_one_of(c, d)] ``` - Make it appear in rustdoc documentation - Change the syntax? - Etc Eventually, we should make an RFC and make this (or rather similar) attribute public. --- I'm fairly new to compiler development and not at all sure if the implementation makes sense, but at least it passes tests :)
2022-01-17Use Term in ProjectionPredicatekadmin-38/+41
ProjectionPredicate should be able to handle both associated types and consts so this adds the first step of that. It mainly just pipes types all the way down, not entirely sure how to handle consts, but hopefully that'll come with time.
2022-01-17add eq constraints on associated constantskadmin-0/+14
2022-01-17add and update testsb-naber-4/+40
2022-01-17Auto merge of #92816 - tmiasko:rm-llvm-asm, r=Amanieubors-1535/+106
Remove deprecated LLVM-style inline assembly The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it is time to remove `llvm_asm!` to avoid continued maintenance cost. Closes #70173. Closes #92794. Closes #87612. Closes #82065. cc `@rust-lang/wg-inline-asm` r? `@Amanieu`
2022-01-17Add `~const` bound test for negative implswoppopo-3/+23
2022-01-17Auto merge of #92996 - matthiaskrgr:rollup-50wpzva, r=matthiaskrgrbors-54/+116
Rollup of 10 pull requests Successful merges: - #92795 (Link sidebar "location" heading to top of page) - #92799 (Remove some unnecessary uses of `FieldDef::ident`) - #92808 (Fix `try wrapping expression in variant` suggestion with struct field shorthand) - #92819 (rustdoc: remove hand-rolled isatty) - #92876 (Fix suggesting turbofish with lifetime arguments) - #92921 (Rename Printer constructor from mk_printer() to Printer::new()) - #92937 (rustdoc: Add missing dot separator) - #92953 (Copy an example to PartialOrd as well) - #92977 (Docs: recommend VecDeque instead of Vec::remove(0)) - #92981 (fix const_ptr_offset_from tracking issue) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2022-01-17Rollup merge of #92876 - compiler-errors:fix-turbofish-lifetime-suggestion, ↵Matthias Krüger-44/+85
r=nagisa Fix suggesting turbofish with lifetime arguments Now we suggest turbofish correctly given exprs like `foo<'_>`. Also fix suggestion when we have `let x = foo<bar, baz>;` which was broken.
2022-01-17Rollup merge of #92808 - ↵Matthias Krüger-10/+31
compiler-errors:wrap-struct-shorthand-field-in-variant, r=davidtwco Fix `try wrapping expression in variant` suggestion with struct field shorthand Fixes a broken suggestion: [playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=83fe2dbfe1485f8cfca1aef2a6582e77) before: ``` error[E0308]: mismatched types --> src/main.rs:7:19 | 7 | let x = Foo { bar }; | ^^^ expected enum `Option`, found integer | = note: expected enum `Option<i32>` found type `{integer}` help: try wrapping the expression in `Some` | 7 | let x = Foo { Some(bar) }; | +++++ + ``` after: ``` error[E0308]: mismatched types --> src/main.rs:7:19 | 7 | let x = Foo { bar }; | ^^^ expected enum `Option`, found integer | = note: expected enum `Option<i32>` found type `{integer}` help: try wrapping the expression in `Some` | 7 | let x = Foo { bar: Some(bar) }; | ~~~~~~~~~~~~~~ ``` r? ``@m-ou-se`` since you touched the code last in #91080
2022-01-17Auto merge of #92473 - petrochenkov:ltrattr2, r=Aaron1011bors-24/+12
expand: Pick `cfg`s and `cfg_attrs` one by one, like other attributes This is a rebase of https://github.com/rust-lang/rust/pull/83354, but without any language-changing parts ~(except for https://github.com/rust-lang/rust/pull/84110)~, i.e. the attribute expansion order is the same. This is a pre-requisite for any other changes making cfg attributes closer to regular macro attributes - Possibly changing their expansion order (https://github.com/rust-lang/rust/issues/83331) - Keeping macro backtraces for cfg attributes, or otherwise making them visible after expansion without keeping them in place literally (https://github.com/rust-lang/rust/pull/84110). Two exceptions to the "one by one" behavior are: - cfgs eagerly expanded by `derive` and `cfg_eval`, they are still expanded in a batch, that's by design. - cfgs at the crate root, they are currently expanded not during the main expansion pass, but before that, during `#![feature]` collection. I'll try to disentangle that logic later in a separate PR. r? `@Aaron1011`
2022-01-16Rollup merge of #92746 - estebank:question-mark-in-type, r=davidtwcoMatthias Krüger-34/+68
Parse `Ty?` as `Option<Ty>` and provide structured suggestion Swift has specific syntax that desugars to `Option<T>` similar to our `?` operator, which means that people might try to use it in Rust. Parse it and gracefully recover.
2022-01-16Rollup merge of #92710 - jackh726:issue-92280, r=nikomatsakisMatthias Krüger-0/+73
Include Projections when elaborating TypeOutlives Fixes #92280 In `Elaborator`, we elaborate that `Foo<<Bar as Baz>::Assoc>: 'a` -> `<Bar as Baz>::Assoc: 'a`. This is the same rule that would be applied to any other `Param`. If there are escaping vars, we continue to do nothing. r? `@nikomatsakis`
2022-01-16Rollup merge of #92487 - dtolnay:traitalias, r=matthewjasperMatthias Krüger-1/+1
Fix unclosed boxes in pretty printing of TraitAlias This was causing trait aliases to not even render at all in stringified / pretty printed output. ```rust macro_rules! repro { ($item:item) => { stringify!($item) }; } fn main() { println!("{:?}", repro!(pub trait Trait<T> = Sized where T: 'a;)); } ``` Before:&ensp;`""` After:&ensp;`"pub trait Trait<T> = Sized where T: 'a;"` The fix is copied from how `head`/`end` for `ItemKind::Use`, `ItemKind::ExternCrate`, and `ItemKind::Mod` are all done in the pretty printer: https://github.com/rust-lang/rust/blob/dd3ac41495e85a9b7b5cb3186379d02ce17e51fe/compiler/rustc_ast_pretty/src/pprust/state.rs#L1178-L1184
2022-01-15Add nll revision for issue-92096 test that passesJack Huey-7/+9