mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Merge #8987
8987: Fix lowering of FnOnce() without return type r=flodiebold a=flodiebold This should result in an implicit `-> ()`, not leaving out the binding. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
33fdd512e3
3 changed files with 43 additions and 16 deletions
|
@ -205,7 +205,7 @@ fn lower_generic_args_from_fn_path(
|
||||||
) -> Option<GenericArgs> {
|
) -> Option<GenericArgs> {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
let mut bindings = Vec::new();
|
let mut bindings = Vec::new();
|
||||||
if let Some(params) = params {
|
let params = params?;
|
||||||
let mut param_types = Vec::new();
|
let mut param_types = Vec::new();
|
||||||
for param in params.params() {
|
for param in params.params() {
|
||||||
let type_ref = TypeRef::from_ast_opt(&ctx, param.ty());
|
let type_ref = TypeRef::from_ast_opt(&ctx, param.ty());
|
||||||
|
@ -213,7 +213,6 @@ fn lower_generic_args_from_fn_path(
|
||||||
}
|
}
|
||||||
let arg = GenericArg::Type(TypeRef::Tuple(param_types));
|
let arg = GenericArg::Type(TypeRef::Tuple(param_types));
|
||||||
args.push(arg);
|
args.push(arg);
|
||||||
}
|
|
||||||
if let Some(ret_type) = ret_type {
|
if let Some(ret_type) = ret_type {
|
||||||
let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.ty());
|
let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.ty());
|
||||||
bindings.push(AssociatedTypeBinding {
|
bindings.push(AssociatedTypeBinding {
|
||||||
|
@ -221,10 +220,14 @@ fn lower_generic_args_from_fn_path(
|
||||||
type_ref: Some(type_ref),
|
type_ref: Some(type_ref),
|
||||||
bounds: Vec::new(),
|
bounds: Vec::new(),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if args.is_empty() && bindings.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
} else {
|
||||||
Some(GenericArgs { args, has_self_type: false, bindings })
|
// -> ()
|
||||||
|
let type_ref = TypeRef::Tuple(Vec::new());
|
||||||
|
bindings.push(AssociatedTypeBinding {
|
||||||
|
name: name![Output],
|
||||||
|
type_ref: Some(type_ref),
|
||||||
|
bounds: Vec::new(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Some(GenericArgs { args, has_self_type: false, bindings })
|
||||||
}
|
}
|
||||||
|
|
|
@ -778,9 +778,11 @@ fn write_bounds_like_dyn_trait(
|
||||||
}
|
}
|
||||||
WhereClause::AliasEq(alias_eq) if is_fn_trait => {
|
WhereClause::AliasEq(alias_eq) if is_fn_trait => {
|
||||||
is_fn_trait = false;
|
is_fn_trait = false;
|
||||||
|
if !alias_eq.ty.is_unit() {
|
||||||
write!(f, " -> ")?;
|
write!(f, " -> ")?;
|
||||||
alias_eq.ty.hir_fmt(f)?;
|
alias_eq.ty.hir_fmt(f)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
WhereClause::AliasEq(AliasEq { ty, alias }) => {
|
WhereClause::AliasEq(AliasEq { ty, alias }) => {
|
||||||
// in types in actual Rust, these will always come
|
// in types in actual Rust, these will always come
|
||||||
// after the corresponding Implemented predicate
|
// after the corresponding Implemented predicate
|
||||||
|
|
|
@ -3078,7 +3078,7 @@ fn infer_fn_trait_arg() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_box_fn_arg() {
|
fn infer_box_fn_arg() {
|
||||||
// The type mismatch is a bug
|
// The type mismatch is because we don't define Unsize and CoerceUnsized
|
||||||
check_infer_with_mismatches(
|
check_infer_with_mismatches(
|
||||||
r#"
|
r#"
|
||||||
//- /lib.rs deps:std
|
//- /lib.rs deps:std
|
||||||
|
@ -3138,7 +3138,7 @@ fn foo() {
|
||||||
555..557 'ps': {unknown}
|
555..557 'ps': {unknown}
|
||||||
559..561 '{}': ()
|
559..561 '{}': ()
|
||||||
568..569 'f': Box<dyn FnOnce(&Option<i32>)>
|
568..569 'f': Box<dyn FnOnce(&Option<i32>)>
|
||||||
568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
|
568..573 'f(&s)': ()
|
||||||
570..572 '&s': &Option<i32>
|
570..572 '&s': &Option<i32>
|
||||||
571..572 's': Option<i32>
|
571..572 's': Option<i32>
|
||||||
549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
|
549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
|
||||||
|
@ -3608,3 +3608,25 @@ fn main() {
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fn_returning_unit() {
|
||||||
|
check_infer_with_mismatches(
|
||||||
|
r#"
|
||||||
|
#[lang = "fn_once"]
|
||||||
|
trait FnOnce<Args> {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<F: FnOnce()>(f: F) {
|
||||||
|
let _: () = f();
|
||||||
|
}"#,
|
||||||
|
expect![[r#"
|
||||||
|
82..83 'f': F
|
||||||
|
88..112 '{ ...f(); }': ()
|
||||||
|
98..99 '_': ()
|
||||||
|
106..107 'f': F
|
||||||
|
106..109 'f()': ()
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue