Commit graph

727 commits

Author SHA1 Message Date
Zack M. Davis
5cc488d250 deduplicate projection error (E0271) messages
The `ErrorId` variant takes a u16 so that `DiagnosticMessageId` can retain
its `Copy` status (the present author's first choice having been the "EXXX"
code as a string).

The duplicated "type mismatch resolving `{}`" literal is unfortunate, but
the `struct_span_err!` macro (which we want to mark that error code as
used) is fussy about taking a literal, and the one-time-diagnostics set
needs an owned string.

This is concerning #33941 and probably #45805!
2017-11-12 19:34:27 -08:00
Cengiz Can
da52563bf5 Improve SubSupConflict case with one named, one anonymous lifetime parameter #42701 2017-11-12 18:56:45 +03:00
bors
b087dedf3f Auto merge of #45870 - mikeyhew:arbitrary_self_types, r=arielb1
Implement arbitrary_self_types

r? @arielb1
cc @nikomatsakis

Partial implementation of #44874.  Supports trait and struct methods with arbitrary self types, as long as the type derefs (transitively) to `Self`. Doesn't support raw-pointer `self` yet.

Methods with non-standard self types (i.e. anything other than `&self, &mut self, and Box<Self>`) are not object safe, because dynamic dispatch hasn't been implemented for them yet.

I believe this is also a (partial) fix for #27941.
2017-11-12 07:31:08 +00:00
bors
c1aacdcb30 Auto merge of #45864 - nikomatsakis:issue-30046-infer-fn-once-in-closures, r=eddyb
adjust closure kind based on the guarantor's upvar note

Fixes #30046.

r? @eddyb
2017-11-12 05:08:09 +00:00
Guillaume Gomez
5d07d73ffb Rollup merge of #45877 - mikhail-m1:mir-borrowck-act-on-moved, r=arielb1
restore move out dataflow, add report of move out errors

fix https://github.com/rust-lang/rust/issues/45363
r? @arielb1
2017-11-11 13:38:07 +01:00
bors
bd7ce71aab Auto merge of #45807 - tommyip:format_err, r=estebank
Make positional argument error in format! clearer

r? @estebank

Fixes #44954
2017-11-11 07:33:31 +00:00
bors
a35a3abcda Auto merge of #45050 - petrochenkov:ambind, r=nikomatsakis
resolve: Use same rules for disambiguating fresh bindings in `match` and `let`

Resolve `Unit` as a unit struct pattern in
```rust
struct Unit;

let Unit = x;
```
consistently with
```rust
match x {
    Unit => {}
}
```
It was previously an error.
(The change also applies to unit variants and constants.)

Fixes https://users.rust-lang.org/t/e0530-cannot-shadow-unit-structs-what-in-the-earthly-what/13054
(This particular change doesn't depend on a fix for the issue mentioned in https://users.rust-lang.org/t/e0530-cannot-shadow-unit-structs-what-in-the-earthly-what/13054/4)

cc @rust-lang/lang
r? @nikomatsakis
2017-11-10 19:10:12 +00:00
bors
968b6206cb Auto merge of #45785 - arielb1:unsafe-fixes, r=eddyb
fixes to MIR effectck

r? @eddyb

beta-nominating because regression (MIR effectck is new)
2017-11-10 11:37:32 +00:00
kennytm
253d18e3f9 Rollup merge of #45887 - xfix:assert-eq-trailling-comma, r=dtolnay
Allow a trailling comma in assert_eq/ne macro

From Rust beginners IRC:

&lt;???> It sure does annoy me that assert_eq!() does not accept a trailing comma after the last argument.
&lt;???> ???: File an issue against https://github.com/rust-lang/rust and CC @rust-lang/libs

Figured that might as well submit it. Will become insta-stable after merging (danger zone).

cc @rust-lang/libs
2017-11-10 17:07:10 +08:00
kennytm
de083eb165 Rollup merge of #45856 - estebank:issue-45829, r=nikomatsakis
Fix help for duplicated names: `extern crate (...) as (...)`

On the case of duplicated names caused by an `extern crate` statement
with a rename, don't include the inline suggestion, instead using a span
label with only the text to avoid incorrect rust code output.

Fix #45829.
2017-11-10 17:07:05 +08:00
Michael Hewson
ddc21d567e Don't emit the feature error if it's an invalid self type 2017-11-09 11:03:27 -05:00
Mikhail Modin
3acb4e9e4a add reinit test 2017-11-09 17:46:35 +03:00
Michael Hewson
c046fda312 update test/ui/static-lifetime.stderr with new error message 2017-11-09 09:21:54 -05:00
Konrad Borowski
6a92c0fdbd Allow a trailing comma in assert_eq/ne macro 2017-11-09 14:14:49 +01:00
Michael Hewson
7f8b003fbb update ui test to new error message 2017-11-08 16:12:34 -05:00
bors
02004ef783 Auto merge of #45452 - estebank:colon-typo, r=nikomatsakis
Detect `=` -> `:` typo in let bindings

When encountering a let binding type error, attempt to parse as
initializer instead. If successful, it is likely just a typo:

```rust
fn main() {
    let x: Vec::with_capacity(10);
}
```

```
error: expected type, found `10`
 --> file.rs:3:31
  |
3 |     let x: Vec::with_capacity(10, 20);
  |         --                    ^^
  |         ||
  |         |help: did you mean assign here?: `=`
  |         while parsing the type for `x`
```

Fix #43703.
2017-11-08 20:00:41 +00:00
Esteban Küber
d0339c7e44 Fix help for duplicated names: extern crate (...) as (...)
On the case of duplicated names caused by an `extern crate` statement
with a rename, don't include the inline suggestion, instead using a span
label with only the text to avoid incorrect rust code output.
2017-11-08 10:36:14 -08:00
bors
4bb96f6519 Auto merge of #45575 - michaelwoerister:tweak-inline-trans-items, r=nikomatsakis
Only instantiate inline- and const-fns if they are referenced (again).

It seems that we have regressed on not translating `#[inline]` functions unless they are actually used. This should bring back this optimization. I also added a regression test this time so it doesn't happen again accidentally.

Fixes #40392.

r? @alexcrichton

UPDATE & PSA
---------------------
This patch **makes translation very lazy** -- in general this is a good thing (we don't want the compiler to do unnecessary work) but it has two consequences:
1. Some error messages are only generated when an item is actually translated. Consequently, this patch will lead to more cases where the compiler will only start emitting errors when the erroneous function is actually used. This has always been true to some extend (e.g. when passing generic values to an intrinsic) but since this is something user-facing it's worth mentioning.
2. When writing tests, one has to make sure that the functions in question are actually generated. In other words, it must not be dead code. This can usually  be achieved by either
    1. making sure the function is exported from the resulting binary or
    2. by making sure the function is called from something that is exported (or `main()`).

Note that it depends on the crate type what functions are exported:
   1. For rlibs and dylibs everything that is reachable from the outside is exported.
   2. For executables, cdylibs, and staticlibs, items are only exported if they are additionally `#[no_mangle]` or have an `#[export_name]`.

The commits in this PR contain many examples of how tests can be updated to comply to the new requirements.
2017-11-08 12:23:34 +00:00
Niko Matsakis
629efae761 look for the note on the guarantor, not the root cmt
This was causing upvar inference to fail for all cases where the move
was from a projection, not the root variable.
2017-11-08 05:29:03 -05:00
bors
49bee9d09a Auto merge of #45735 - tirr-c:issue-45730, r=arielb1
Forbid casting to/from a pointer of unknown kind

Fixes #45730.

Before, it ICE'd when `pointer_kind` encountered `TyInfer`.
2017-11-08 07:12:15 +00:00
kennytm
d8238e4314
Rollup merge of #45751 - estebank:issue-44684, r=nikomatsakis
Handle anon lifetime arg being returned with named lifetime return type

When there's a lifetime mismatch between an argument with an anonymous
lifetime being returned in a method with a return type that has a named
lifetime, show specialized lifetime error pointing at argument with a
hint to give it an explicit lifetime matching the return type.

```
error[E0621]: explicit lifetime required in the type of `other`
  --> file2.rs:21:21
   |
17 |     fn bar(&self, other: Foo) -> Foo<'a> {
   |                   ----- consider changing the type of `other` to `Foo<'a>`
...
21 |                     other
   |                     ^^^^^ lifetime `'a` required
```

Follow up to #44124 and #42669. Fix #44684.
2017-11-07 22:40:15 +08:00
Michael Woerister
6c1529b34f Update invalid inline arg test. 2017-11-07 08:54:38 +01:00
Esteban Küber
805333b2b5 review comments 2017-11-06 21:02:31 -08:00
bors
785643a5eb Auto merge of #45668 - nikomatsakis:nll-free-region, r=arielb1
extend NLL with preliminary support for free regions on functions

This PR extends https://github.com/rust-lang/rust/pull/45538 with support for free regions. This is pretty preliminary and will no doubt want to change in various ways, particularly as we add support for closures, but it's enough to get the basic idea in place:

- We now create specific regions to represent each named lifetime declared on the function.
- Region values can contain references to these regions (represented for now as a `BTreeSet<RegionIndex>`).
- If we wind up trying to infer that `'a: 'b` must hold, but no such relationship was declared, we report an error.

It also does a number of drive-by refactorings.

r? @arielb1

cc @spastorino
2017-11-06 23:30:57 +00:00
Ariel Ben-Yehuda
12aedc833c collect unused unsafe code
FIXME: de-uglify
2017-11-06 23:41:18 +02:00
Wonwoo Choi
99ada043b6 Forbid casting to/from a pointer of unknown kind 2017-11-07 01:45:57 +09:00
Tommy Ip
13a416298c Update tests for new format! error message 2017-11-06 16:28:30 +00:00
bors
74be072068 Auto merge of #45737 - oli-obk:json, r=petrochenkov
Pretty print json in ui tests

I found the json output in one line to not be useful for reviewing

r? @petrochenkov
2017-11-06 12:18:12 +00:00
Oliver Schneider
6d6fb2ef97
Adjust json errors to byte changes 2017-11-06 10:35:50 +01:00
Esteban Küber
de959afab5 Handle anon lifetime arg being returned with named lifetime return type
When there's a lifetime mismatch between an argument with an anonymous
lifetime being returned in a method with a return type that has a named
lifetime, show specialized lifetime error pointing at argument with a
hint to give it an explicit lifetime matching the return type.

```
error[E0621]: explicit lifetime required in the type of `other`
  --> file2.rs:21:21
   |
17 |     fn bar(&self, other: Foo) -> Foo<'a> {
   |                   ----- consider changing the type of `other` to `Foo<'a>`
...
21 |                     other
   |                     ^^^^^ lifetime `'a` required
```

Follow up to #44124 and #42669.
2017-11-05 09:55:07 -08:00
bors
666687a68c Auto merge of #45072 - nikomatsakis:issue-38714, r=arielb1
new rules for merging expected and supplied types in closure signatures

As uncovered in #38714, we currently have some pretty bogus code for combining the "expected signature" of a closure with the "supplied signature". To set the scene, consider a case like this:

```rust
fn foo<F>(f: F)
where
  F: for<'a> FnOnce(&'a u32) -> &'a u32
  // ^ *expected* signature comes from this where-clause
{
    ...
}

fn main() {
    foo(|x: &u32| -> &u32 { .. }
     // ^^^^^^^^^^^^^^^^^ supplied signature
     // comes from here
}
```

In this case, the supplied signature (a) includes all the parts and (b) is the same as the expected signature, modulo the names used for the regions. But often people supply only *some* parts of the signature. For example, one might write `foo(|x| ..)`, leaving *everything* to be inferred, or perhaps `foo(|x: &u32| ...)`, which leaves the return type to be inferred.

In the current code, we use the expected type to supply the types that are not given, but otherwise use the type the user gave, except for one case: if the user writes `fn foo(|x: _| ..)` (i.e., an underscore at the outermost level), then we will take the expected type (rather than instantiating a fresh type variable). This can result in nonsensical situations, particularly with bound regions that link the types of parameters to one another or to the return type. Consider `foo(|x: &u32| ...)` -- if we *literally* splice the expected return type of `&'a u32` together with what the user gave, we wind up with a signature like `for<'a> fn(&u32) -> &'a u32`. This is not even permitted as a type, because bound regions like `'a` must appear also in the arguments somewhere, which is why #38714 leads to an ICE.

This PR institutes some new rules. These are not meant to be the *final* set of rules, but they are a kind of "lower bar" for what kind of code we accept (i.e., we can extend these rules in the future to be smarter in some cases, but -- as we will see -- these rules do accept some things that we then would not be able to back off from).

These rules are derived from a few premises:

- First and foremost, anonymous regions in closure annotation are mostly requests for the code to "figure out the right lifetime" and shouldn't be read too closely. So for example when people write a closure signature like `|x: &u32|`, they are really intended for us to "figure out" the right region for `x`.
    - In contrast, the current code treats this supplied type as being more definitive. In particular, writing `|x: &u32|` would always result in the region of `x` being bound in the closure type. In other words, the signature would be something like `for<'a> fn(&'a u32)` -- this is derived from the fact that `fn(&u32)` expands to a type where the region is bound in the fn type.
    - This PR takes a different approach. The "binding level" for reference types appearing in closure signatures can be informed in some cases by the expected signature. So, for example, if the expected signature is something like `(&'f u32)`, where the region of the first argument appears free, then for `|x: &u32|`, the new code would infer `x` to also have the free region `'f`.
        - This inference has some limits. We don't do this for bindings that appear within the selected types themselves. So e.g. `|x: fn(&u32)|`, when combined with an expected type of `fn(fn(&'f u32))`, would still result in a closure that expects `for<'a> fn(&'a u32)`. Such an annotation will ultimately result in an error, as it happens, since `foo` is supplying a `fn(&'f u32)` to the closure, but the closure signature demands a `for<'a> fn(&'a u32)`. But still we choose to trust it and have the user change it.
        - I wanted to preserve the rough intuition that one can copy-and-paste a type out of the fn signature and into the fn body without dramatically changing its meaning. Interestingly, if one has `|x: &u32|`, then regardless of whether the region of `x` is bound or free in the closure signature, it is also free in the region body, and that is also true when one writes `let x: &u32`, so that intuition holds here. But the same would not be true for `fn(&u32)`, hence the different behavior.
- Second, we must take either **all** the references to bound regions from the expected type or **none**. The current code, as we saw, will happily take a bound region in the return type but drop the other place where it is used, in the parameters. Since bound regions are all about linking multiple things together, I think it's important not to do that. (That said, we could conceivably be a bit less strict here, since the subtyping rules will get our back, but we definitely don't want any bound regions that appear only in the return type.)
- Finally, we cannot take the bound region names from the supplied types and "intermix" them with the names from the expected types.
    - We *could* potentially do some alpha renaming, but I didn't do that.
- Ultimately, if the types the user supplied do not match expectations in some way that we cannot recover from, we fallback to deriving the closure signature solely from those expected types.
    - For example, if the expected type is `u32` but the user wrote `i32`.
    - Or, more subtle, if the user wrote e.g. `&'x u32` for some named lifetime `'x`, but the expected type includes a bound lifetime (`for<'a> (&'a u32)`). In that case, preferring the type that the user explicitly wrote would hide an appearance of a bound name from the expected type, and we try to never do that.

The detailed rules that I came up with are found in the code, but for ease of reading I've also [excerpted them into a gist](https://gist.github.com/nikomatsakis/e69252a2b57e6d97d044c2f254c177f1). I am not convinced they are correct and would welcome feedback for alternative approaches.

(As an aside, the way I think I would ultimately *prefer* to think about this is that the conversion from HIR types to internal types could be parameterized by an "expected type" that it uses to guide itself. However, since that would be a pain, I opted *in the code* to first instantiate the supplied types as `Ty<'tcx>` and then "merge" those types with the `Ty<'tcx>` from the expected signature.)

I think we should probably FCP this before landing.

cc @rust-lang/lang
r? @arielb1
2017-11-05 16:49:08 +00:00
bors
94ede93467 Auto merge of #44042 - LukasKalbertodt:ascii-methods-on-instrinsics, r=alexcrichton
Copy all `AsciiExt` methods to the primitive types directly in order to deprecate it later

**EDIT:** [this PR is ready now](https://github.com/rust-lang/rust/pull/44042#issuecomment-333883548). I edited this post to reflect the current status of discussion, which is (apart from code review) pretty much settled.

---

This is my current progress in order to prepare stabilization of #39658. As discussed there (and in #39659), the idea is to deprecated `AsciiExt` and copy all methods to the type directly. Apparently there isn't really a reason to have those methods in an extension trait¹.

~~This is **work in progress**: copy&pasting code while slightly modifying the documentation isn't the most exciting thing to do. Therefore I wanted to already open this WIP PR after doing basically 1/4 of the job (copying methods to `&[u8]`, `char` and `&str` is still missing) to get some feedback before I continue. Some questions possibly worth discussing:~~

1. ~~Does everyone agree that deprecating `AsciiExt` is a good idea? Does everyone agree with the goal of this PR?~~ => apparently yes
2. ~~Are my changes OK so far? Did I do something wrong?~~
3. ~~The issue of the unstable-attribute is currently set to 0. I would wait until you say "Ok" to the whole thing, then create a tracking issue and then insert the correct issue id. Is that ok?~~
4. ~~I tweaked `eq_ignore_ascii_case()`: it now takes the argument `other: u8` instead of `other: &u8`. The latter was enforced by the trait. Since we're not bound to a trait anymore, we can drop the reference, ok?~~ => I reverted this, because the interface has to match the `AsciiExt` interface exactly.

¹ ~~Could it be that we can't write `impl [u8] {}`? This might be the reason for `AsciiExt`. If that is the case: is there a good reason we can't write such an impl block? What can we do instead?~~ => we couldn't at the time this PR was opened, but Simon made it possible.

/cc @SimonSapin @zackw
2017-11-05 11:42:59 +00:00
bors
12e6b53744 Auto merge of #45711 - tirr-c:unicode-span, r=estebank
Display spans correctly when there are zero-width or wide characters

Hopefully...
* fixes #45211
* fixes #8706

---

Before:
```
error: invalid width `7` for integer literal
  --> unicode_2.rs:12:25
   |
12 |     let _ = ("a̐éö̲", 0u7);
   |                         ^^^
   |
   = help: valid widths are 8, 16, 32, 64 and 128

error: invalid width `42` for integer literal
  --> unicode_2.rs:13:20
   |
13 |     let _ = ("아あ", 1i42);
   |                    ^^^^
   |
   = help: valid widths are 8, 16, 32, 64 and 128

error: aborting due to 2 previous errors
```

After:
```
error: invalid width `7` for integer literal
  --> unicode_2.rs:12:25
   |
12 |     let _ = ("a̐éö̲", 0u7);
   |                     ^^^
   |
   = help: valid widths are 8, 16, 32, 64 and 128

error: invalid width `42` for integer literal
  --> unicode_2.rs:13:20
   |
13 |     let _ = ("아あ", 1i42);
   |                      ^^^^
   |
   = help: valid widths are 8, 16, 32, 64 and 128

error: aborting due to 2 previous errors
```

Spans might display incorrectly on the browser.

r? @estebank
2017-11-04 23:09:19 +00:00
kennytm
ea572657da Rollup merge of #45639 - LaurentMazare:master, r=petrochenkov
Add a nicer error message for missing  in for loop, fixes #40782.

As suggested by @estebank in issue #40782, this works in the same way as #42578: if the in keyword is missing, we continue parsing the expression and if this works correctly an adapted error message is produced. Otherwise we return the old error.

A specific test case has also been added.
This is my first PR on rust-lang/rust so any feedback is very welcome.
2017-11-04 13:49:28 +08:00
Esteban Küber
9dc7abe06d Detect = -> : typo in let bindings
When encountering a let binding type error, attempt to parse as
initializer instead. If successful, it is likely just a typo:

```rust
fn main() {
    let x: Vec::with_capacity(10);
}
```

```
error: expected type, found `10`
 --> file.rs:3:31
  |
3 |     let x: Vec::with_capacity(10, 20);
  |         --                    ^^
  |         ||
  |         |help: did you mean assign here?: `=`
  |         while parsing the type for `x`
```
2017-11-03 17:39:16 -07:00
Vadim Petrochenkov
765076faab Give better help for identifier patterns failing exhaustiveness check 2017-11-04 03:09:47 +03:00
Vadim Petrochenkov
3386757923 Move some tests to UI 2017-11-04 03:09:47 +03:00
Lukas Kalbertodt
da57580736 Remove unused AsciiExt imports and fix tests related to ascii methods
Many AsciiExt imports have become useless thanks to the inherent ascii
methods added in the last commits. These were removed. In some places, I
fully specified the ascii method being called to enforce usage of the
AsciiExt trait. Note that some imports are not removed but tagged with
a `#[cfg(stage0)]` attribute. This is necessary, because certain ascii
methods are not yet available in stage0. All those imports will be
removed later.

Additionally, failing tests were fixed. The test suite should exit
successfully now.
2017-11-03 21:27:40 +01:00
bors
59d484575a Auto merge of #45569 - zackmdavis:unexported_pub_lint, r=petrochenkov
`unreachable-pub` lint (as authorized by RFC 2126)

To whom it may concern:

RFC 2126 commissions the creation of a lint for `pub` items that are not visible from crate root (#45521). We understand (but seek confirmation from more knowledgable compiler elders) that this can be implemented by linting HIR items that are _not_ ~~`cx.access_levels.is_exported`~~ `cx.access_levels.is_reachable` but have a `vis` (-ibility) field of `hir::Visibility::Public`.

The lint, tentatively called ~~`unexported-pub`~~ `unreachable-pub` (with the understanding that much could be written on the merits of various names, as it is said of the colors of bicycle-sheds), suggests `crate` as a replacement for `pub` if the `crate_visibility_modifier` feature is enabled (see #45388), and `pub(crate)` otherwise. We also use help messaging to suggest the other potential fix of exporting the item; feedback is desired as to whether this may be confusing or could be worded better.

As a preview of what respecting the proposed lint would look like (and to generate confirmatory evidence that this implementation doesn't issue false positives), ~~we take its suggestions for `libcore`~~ (save one, which is deferred to another pull request because it brings up an unrelated technical matter). I remain your obedient servant.

![unexported_pub](https://user-images.githubusercontent.com/1076988/32089794-fbd02420-baa0-11e7-87e5-3ec01f18924a.png)

r? @petrochenkov
2017-11-03 16:28:24 +00:00
Oliver Schneider
d1d9cfc722
Don't add a new -Z flag, reuse -Zunstable-options 2017-11-03 16:22:19 +01:00
Oliver Schneider
c7cb2cf8b5
Pretty print json in ui tests 2017-11-03 13:38:26 +01:00
Zack M. Davis
085ec6d528 unreachable-pub lint for pub items not reachable from crate root
This is with deepest thanks to Vadim Petrochenkov for thorough review, and
resolves #45521.
2017-11-02 20:50:17 -07:00
bors
9f3b09116b Auto merge of #45484 - oli-obk:lint_names, r=nikomatsakis
Report lint names in json diagnostics

This allows tools like `rustfix` to have whitelists for what to automatically apply and what not.
2017-11-03 00:42:11 +00:00
Niko Matsakis
e8a96c97f4 fallback to provided signature in the event of a type error
This prevents regressions on some annoying cases.
2017-11-02 18:38:24 -04:00
Wonwoo Choi
272c2faa1d Display spans correctly when there are non-half-width characters 2017-11-03 03:15:39 +09:00
bors
e340996ff5 Auto merge of #45409 - tamird:suggest-match-default-bindings, r=nikomatsakis
typeck: suggest use of match_default_bindings feature

Fixes #45383.
Updates #42640.

r? @nikomatsakis
cc @tschottdorf

This needs a UI test, but thought I'd get some early feedback.
2017-11-02 16:28:16 +00:00
Niko Matsakis
7b4282e02b emit less info when we warn
Actually, I meant to make this use `delay_span_bug`
2017-11-02 10:34:25 -04:00
Niko Matsakis
fdcd2256f0 trace span info for constraints and report errors 2017-11-02 10:34:25 -04:00
Oliver Schneider
88fb4c4fda
Report lint names in json diagnostics 2017-11-02 10:19:41 +01:00
bors
a7d98c7837 Auto merge of #45630 - joshleeb:iss35241, r=estebank
Improve display of error E0308

Ref. Forgetting to call a variant constructor causes a confusing error message #35241.

This PR modifies [`note_type_err`](b7041bfab3/src/librustc/infer/error_reporting/mod.rs (L669-L674)) to display a `help` message when a `TyFnPtr` or `TyFnDef` are found and the return type, of the function or function pointer, is the same as the type that is expected.

The output of compiling

```rust
struct Foo(u32);

fn test() -> Foo { Foo }

fn main() {}
```

is now

```bash
$ rustc src/test/ui/issue-35241.rs
error[E0308]: mismatched types
  --> src/test/ui/issue-35241.rs:13:20
   |
13 | fn test() -> Foo { Foo }
   |              ---   ^^^ expected struct `Foo`, found fn item
   |              |
   |              expected `Foo` because of return type
   |
   = help: did you mean `Foo { /* fields */ }`?
   = note: expected type `Foo`
              found type `fn(u32) -> Foo {Foo::{{constructor}}}`

error: aborting due to previous error
```
2017-11-02 08:30:03 +00:00