mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	hir_ty: use async ret type for inference inside async bodies
This commit is contained in:
		
							parent
							
								
									3fa3343e47
								
							
						
					
					
						commit
						54d60fdee9
					
				@ -22,6 +22,7 @@ pub struct FunctionData {
 | 
				
			|||||||
    pub name: Name,
 | 
					    pub name: Name,
 | 
				
			||||||
    pub params: Vec<Interned<TypeRef>>,
 | 
					    pub params: Vec<Interned<TypeRef>>,
 | 
				
			||||||
    pub ret_type: Interned<TypeRef>,
 | 
					    pub ret_type: Interned<TypeRef>,
 | 
				
			||||||
 | 
					    pub async_ret_type: Option<Interned<TypeRef>>,
 | 
				
			||||||
    pub attrs: Attrs,
 | 
					    pub attrs: Attrs,
 | 
				
			||||||
    pub visibility: RawVisibility,
 | 
					    pub visibility: RawVisibility,
 | 
				
			||||||
    pub abi: Option<Interned<str>>,
 | 
					    pub abi: Option<Interned<str>>,
 | 
				
			||||||
@ -63,6 +64,7 @@ impl FunctionData {
 | 
				
			|||||||
                })
 | 
					                })
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
            ret_type: func.ret_type.clone(),
 | 
					            ret_type: func.ret_type.clone(),
 | 
				
			||||||
 | 
					            async_ret_type: func.async_ret_type.clone(),
 | 
				
			||||||
            attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
 | 
					            attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
 | 
				
			||||||
            visibility: item_tree[func.visibility].clone(),
 | 
					            visibility: item_tree[func.visibility].clone(),
 | 
				
			||||||
            abi: func.abi.clone(),
 | 
					            abi: func.abi.clone(),
 | 
				
			||||||
 | 
				
			|||||||
@ -580,6 +580,7 @@ pub struct Function {
 | 
				
			|||||||
    pub abi: Option<Interned<str>>,
 | 
					    pub abi: Option<Interned<str>>,
 | 
				
			||||||
    pub params: IdRange<Param>,
 | 
					    pub params: IdRange<Param>,
 | 
				
			||||||
    pub ret_type: Interned<TypeRef>,
 | 
					    pub ret_type: Interned<TypeRef>,
 | 
				
			||||||
 | 
					    pub async_ret_type: Option<Interned<TypeRef>>,
 | 
				
			||||||
    pub ast_id: FileAstId<ast::Fn>,
 | 
					    pub ast_id: FileAstId<ast::Fn>,
 | 
				
			||||||
    pub(crate) flags: FnFlags,
 | 
					    pub(crate) flags: FnFlags,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -356,12 +356,13 @@ impl<'a> Ctx<'a> {
 | 
				
			|||||||
            _ => TypeRef::unit(),
 | 
					            _ => TypeRef::unit(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ret_type = if func.async_token().is_some() {
 | 
					        let (ret_type, async_ret_type) = if func.async_token().is_some() {
 | 
				
			||||||
 | 
					            let async_ret_type = ret_type.clone();
 | 
				
			||||||
            let future_impl = desugar_future_path(ret_type);
 | 
					            let future_impl = desugar_future_path(ret_type);
 | 
				
			||||||
            let ty_bound = Interned::new(TypeBound::Path(future_impl));
 | 
					            let ty_bound = Interned::new(TypeBound::Path(future_impl));
 | 
				
			||||||
            TypeRef::ImplTrait(vec![ty_bound])
 | 
					            (TypeRef::ImplTrait(vec![ty_bound]), Some(async_ret_type))
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            ret_type
 | 
					            (ret_type, None)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let abi = func.abi().map(lower_abi);
 | 
					        let abi = func.abi().map(lower_abi);
 | 
				
			||||||
@ -395,6 +396,7 @@ impl<'a> Ctx<'a> {
 | 
				
			|||||||
            abi,
 | 
					            abi,
 | 
				
			||||||
            params,
 | 
					            params,
 | 
				
			||||||
            ret_type: Interned::new(ret_type),
 | 
					            ret_type: Interned::new(ret_type),
 | 
				
			||||||
 | 
					            async_ret_type: async_ret_type.map(Interned::new),
 | 
				
			||||||
            ast_id,
 | 
					            ast_id,
 | 
				
			||||||
            flags,
 | 
					            flags,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
				
			|||||||
@ -235,6 +235,7 @@ impl<'a> Printer<'a> {
 | 
				
			|||||||
                    abi,
 | 
					                    abi,
 | 
				
			||||||
                    params,
 | 
					                    params,
 | 
				
			||||||
                    ret_type,
 | 
					                    ret_type,
 | 
				
			||||||
 | 
					                    async_ret_type: _,
 | 
				
			||||||
                    ast_id: _,
 | 
					                    ast_id: _,
 | 
				
			||||||
                    flags,
 | 
					                    flags,
 | 
				
			||||||
                } = &self.tree[it];
 | 
					                } = &self.tree[it];
 | 
				
			||||||
 | 
				
			|||||||
@ -558,7 +558,13 @@ impl<'a> InferenceContext<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            self.infer_pat(*pat, &ty, BindingMode::default());
 | 
					            self.infer_pat(*pat, &ty, BindingMode::default());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
 | 
					        let error_ty = &TypeRef::Error;
 | 
				
			||||||
 | 
					        let return_ty = if data.is_async() {
 | 
				
			||||||
 | 
					            data.async_ret_type.as_deref().unwrap_or(error_ty)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            &*data.ret_type
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
 | 
				
			||||||
        self.return_ty = return_ty;
 | 
					        self.return_ty = return_ty;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3660,3 +3660,52 @@ impl foo::Foo for u32 {
 | 
				
			|||||||
        "#]],
 | 
					        "#]],
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn infer_async_ret_type() {
 | 
				
			||||||
 | 
					    check_types(
 | 
				
			||||||
 | 
					        r#"
 | 
				
			||||||
 | 
					//- /main.rs crate:main deps:core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Result<T, E> {
 | 
				
			||||||
 | 
					    Ok(T),
 | 
				
			||||||
 | 
					    Err(E),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Result::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Fooey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Fooey {
 | 
				
			||||||
 | 
					    fn collect<B: Convert>(self) -> B {
 | 
				
			||||||
 | 
					        B::new()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait Convert {
 | 
				
			||||||
 | 
					    fn new() -> Self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl Convert for u32 {
 | 
				
			||||||
 | 
					    fn new() -> Self {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn get_accounts() -> Result<u32, ()> {
 | 
				
			||||||
 | 
					    let ret = Fooey.collect();
 | 
				
			||||||
 | 
					    //                      ^ u32
 | 
				
			||||||
 | 
					    Ok(ret)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//- /core.rs crate:core
 | 
				
			||||||
 | 
					#[prelude_import] use future::*;
 | 
				
			||||||
 | 
					mod future {
 | 
				
			||||||
 | 
					    #[lang = "future_trait"]
 | 
				
			||||||
 | 
					    trait Future {
 | 
				
			||||||
 | 
					        type Output;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					"#,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user