Repository: rust
Issue: `default_free_fn` feature does not have the same diagnostics as using `Default::default` in recursing situations
Labels: A-diagnostics,T-compiler

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: [Rust playground link](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=3d6b6403d9ba304664c2defc11bc43ba) <!-- Please provide a link to play.rust-lang.org -->

```rust
#![feature(default_free_fn)]

use std::default::default;

struct Foo {
    a: i32,
    b: String,
}

impl Default for Foo {
    fn default() -> Self {
        Self { a: 1, ..default() }
    }
}

fn main() {
    let foo = Foo::default();
}

```

The current output is:

```
   Compiling playground v0.0.1 (/playground)
warning: unused variable: `foo`
  --> src/main.rs:17:9
   |
17 |     let foo = Foo::default();
   |         ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: fields `a` and `b` are never read
 --> src/main.rs:6:5
  |
5 | struct Foo {
  |        --- fields in this struct
6 |     a: i32,
  |     ^
7 |     b: String,
  |     ^
  |
  = note: `#[warn(dead_code)]` on by default

warning: `playground` (bin "playground") generated 2 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.86s
     Running `target/debug/playground`

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
timeout: the monitored command dumped core
/playground/tools/entrypoint.sh: line 11:     9 Aborted                 timeout --signal=KILL ${timeout} "$@"
```

<!-- The following is not always necessary. -->
Ideally the output should look like: ([Using `Default::default()`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b0e3199a9ecfac128da4ca6b59e059e3))

```
   Compiling playground v0.0.1 (/playground)
warning: unused variable: `foo`
  --> src/main.rs:16:9
   |
16 |     let foo = Foo::default();
   |         ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: function cannot return without recursing
  --> src/main.rs:7:5
   |
7  |     fn default() -> Self {
   |     ^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
10 |             ..Default::default()
   |               ------------------ recursive call site
   |
   = note: `#[warn(unconditional_recursion)]` on by default
   = help: a `loop` may express intention better if this is on purpose

warning: fields `a` and `b` are never read
 --> src/main.rs:2:5
  |
1 | struct Foo {
  |        --- fields in this struct
2 |     a: i32,
  |     ^
3 |     b: String,
  |     ^
  |
  = note: `#[warn(dead_code)]` on by default

warning: `playground` (bin "playground") generated 3 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.86s
     Running `target/debug/playground`

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
timeout: the monitored command dumped core
/playground/tools/entrypoint.sh: line 11:     8 Aborted                 timeout --signal=KILL ${timeout} "$@"
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

Using `default()` should also warn the user about unconditional_recursion.

<!--
If dramatically different output is caused by small changes, consider also
adding them here.

If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->