Auto merge of #10382 - samueltardieu:issue-10381, r=llogiq

Box::default(): do not omit the type of the removed trait object

Within a larger expression, when the type of `Box::new(T::default())` is `Box<dyn Trait>`, the concrete type `T` cannot be omitted in the proposed replacement `Box::<T>::default()`.

Fixes #10381

changelog: [`box_default`]: in case of a trait object do not omit the concrete type name
This commit is contained in:
bors 2023-02-20 13:14:23 +00:00
commit 574c8aeeb5
4 changed files with 48 additions and 5 deletions

View File

@ -117,7 +117,8 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
) => {
if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) &&
let Some(sig) = expr_sig(cx, path) &&
let Some(input) = sig.input(index)
let Some(input) = sig.input(index) &&
!cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait()
{
input.no_bound_vars().is_some()
} else {

View File

@ -33,6 +33,7 @@ fn main() {
let _vec4: Box<_> = Box::<Vec<bool>>::default();
let _more = ret_ty_fn();
call_ty_fn(Box::default());
issue_10381();
}
fn ret_ty_fn() -> Box<bool> {
@ -65,3 +66,20 @@ fn issue_10089() {
let _ = Box::<WeirdPathed>::default();
};
}
fn issue_10381() {
#[derive(Default)]
pub struct Foo {}
pub trait Bar {}
impl Bar for Foo {}
fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
if i % 2 == 0 {
Some(Box::<Foo>::default())
} else {
None
}
}
assert!(maybe_get_bar(2).is_some());
}

View File

@ -33,6 +33,7 @@ fn main() {
let _vec4: Box<_> = Box::new(Vec::from([false; 0]));
let _more = ret_ty_fn();
call_ty_fn(Box::new(u8::default()));
issue_10381();
}
fn ret_ty_fn() -> Box<bool> {
@ -65,3 +66,20 @@ fn issue_10089() {
let _ = Box::new(WeirdPathed::default());
};
}
fn issue_10381() {
#[derive(Default)]
pub struct Foo {}
pub trait Bar {}
impl Bar for Foo {}
fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
if i % 2 == 0 {
Some(Box::new(Foo::default()))
} else {
None
}
}
assert!(maybe_get_bar(2).is_some());
}

View File

@ -73,22 +73,28 @@ LL | call_ty_fn(Box::new(u8::default()));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:39:5
--> $DIR/box_default.rs:40:5
|
LL | Box::new(bool::default())
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:56:28
--> $DIR/box_default.rs:57:28
|
LL | let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:65:17
--> $DIR/box_default.rs:66:17
|
LL | let _ = Box::new(WeirdPathed::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()`
error: aborting due to 15 previous errors
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:78:18
|
LL | Some(Box::new(Foo::default()))
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()`
error: aborting due to 16 previous errors