File tree Expand file tree Collapse file tree 9 files changed +75
-22
lines changed
ide-completion/src/completions Expand file tree Collapse file tree 9 files changed +75
-22
lines changed Original file line number Diff line number Diff line change @@ -257,6 +257,7 @@ macro_rules! __known_path {
257257 ( core:: ops:: RangeToInclusive ) => { } ;
258258 ( core:: ops:: RangeInclusive ) => { } ;
259259 ( core:: future:: Future ) => { } ;
260+ ( core:: future:: IntoFuture ) => { } ;
260261 ( core:: ops:: Try ) => { } ;
261262 ( $path: path) => {
262263 compile_error!( "Please register your known path in the path module" )
Original file line number Diff line number Diff line change @@ -258,6 +258,7 @@ pub mod known {
258258 Try ,
259259 Ok ,
260260 Future ,
261+ IntoFuture ,
261262 Result ,
262263 Option ,
263264 Output ,
@@ -391,6 +392,7 @@ pub mod known {
391392 future_trait,
392393 index,
393394 index_mut,
395+ into_future,
394396 mul_assign,
395397 mul,
396398 neg,
Original file line number Diff line number Diff line change @@ -875,7 +875,10 @@ impl<'a> InferenceContext<'a> {
875875 }
876876
877877 fn resolve_future_future_output ( & self ) -> Option < TypeAliasId > {
878- let trait_ = self . resolve_lang_item ( name ! [ future_trait] ) ?. as_trait ( ) ?;
878+ let trait_ = self
879+ . resolver
880+ . resolve_known_trait ( self . db . upcast ( ) , & path ! [ core:: future:: IntoFuture ] )
881+ . or_else ( || self . resolve_lang_item ( name ! [ future_trait] ) ?. as_trait ( ) ) ?;
879882 self . db . trait_data ( trait_) . associated_type_by_name ( & name ! [ Output ] )
880883 }
881884
Original file line number Diff line number Diff line change @@ -137,6 +137,31 @@ fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
137137 ) ;
138138}
139139
140+ #[ test]
141+ fn into_future_trait ( ) {
142+ check_types (
143+ r#"
144+ //- minicore: future
145+ struct Futurable;
146+ impl core::future::IntoFuture for Futurable {
147+ type Output = u64;
148+ type IntoFuture = IntFuture;
149+ }
150+
151+ struct IntFuture;
152+ impl core::future::Future for IntFuture {
153+ type Output = u64;
154+ }
155+
156+ fn test() {
157+ let r = Futurable;
158+ let v = r.await;
159+ v;
160+ } //^ u64
161+ "# ,
162+ ) ;
163+ }
164+
140165#[ test]
141166fn infer_try ( ) {
142167 check_types (
Original file line number Diff line number Diff line change @@ -2780,6 +2780,8 @@ impl Type {
27802780 /// Checks that particular type `ty` implements `std::future::Future`.
27812781 /// This function is used in `.await` syntax completion.
27822782 pub fn impls_future ( & self , db : & dyn HirDatabase ) -> bool {
2783+ // FIXME: This should be checking for IntoFuture trait, but I don't know how to find the
2784+ // right TraitId in this crate.
27832785 let std_future_trait = db
27842786 . lang_item ( self . env . krate , SmolStr :: new_inline ( "future_trait" ) )
27852787 . and_then ( |it| it. as_trait ( ) ) ;
Original file line number Diff line number Diff line change @@ -269,6 +269,8 @@ impl SourceAnalyzer {
269269 db : & dyn HirDatabase ,
270270 await_expr : & ast:: AwaitExpr ,
271271 ) -> Option < FunctionId > {
272+ // FIXME This should be pointing to the poll of IntoFuture::Output's Future impl, but I
273+ // don't know how to resolve the Output type so that we can query for its poll method.
272274 let ty = self . ty_of_expr ( db, & await_expr. expr ( ) ?. into ( ) ) ?;
273275
274276 let op_fn = db
Original file line number Diff line number Diff line change @@ -55,6 +55,7 @@ const USELESS_METHODS: &[&str] = &[
5555 "iter" ,
5656 "into_iter" ,
5757 "iter_mut" ,
58+ "into_future" ,
5859] ;
5960
6061pub ( crate ) fn for_generic_parameter ( ty : & ast:: ImplTraitType ) -> SmolStr {
Original file line number Diff line number Diff line change @@ -75,16 +75,17 @@ impl Future for A {}
7575fn foo(a: A) { a.$0 }
7676"# ,
7777 expect ! [ [ r#"
78- kw await expr.await
79- sn box Box::new(expr)
80- sn call function(expr)
81- sn dbg dbg!(expr)
82- sn dbgr dbg!(&expr)
83- sn let let
84- sn letm let mut
85- sn match match expr {}
86- sn ref &expr
87- sn refm &mut expr
78+ kw await expr.await
79+ me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
80+ sn box Box::new(expr)
81+ sn call function(expr)
82+ sn dbg dbg!(expr)
83+ sn dbgr dbg!(&expr)
84+ sn let let
85+ sn letm let mut
86+ sn match match expr {}
87+ sn ref &expr
88+ sn refm &mut expr
8889 "# ] ] ,
8990 ) ;
9091
@@ -98,18 +99,19 @@ fn foo() {
9899}
99100"# ,
100101 expect ! [ [ r#"
101- kw await expr.await
102- sn box Box::new(expr)
103- sn call function(expr)
104- sn dbg dbg!(expr)
105- sn dbgr dbg!(&expr)
106- sn let let
107- sn letm let mut
108- sn match match expr {}
109- sn ref &expr
110- sn refm &mut expr
102+ kw await expr.await
103+ me into_future() (use core::future::IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
104+ sn box Box::new(expr)
105+ sn call function(expr)
106+ sn dbg dbg!(expr)
107+ sn dbgr dbg!(&expr)
108+ sn let let
109+ sn letm let mut
110+ sn match match expr {}
111+ sn ref &expr
112+ sn refm &mut expr
111113 "# ] ] ,
112- )
114+ ) ;
113115 }
114116
115117 #[ test]
Original file line number Diff line number Diff line change @@ -471,6 +471,21 @@ pub mod future {
471471 #[ lang = "poll" ]
472472 fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > ;
473473 }
474+
475+ pub trait IntoFuture {
476+ type Output ;
477+ type IntoFuture : Future < Output = Self :: Output > ;
478+ #[ lang = "into_future" ]
479+ fn into_future ( self ) -> Self :: IntoFuture ;
480+ }
481+
482+ impl < F : Future > IntoFuture for F {
483+ type Output = F :: Output ;
484+ type IntoFuture = F ;
485+ fn into_future ( self ) -> F {
486+ self
487+ }
488+ }
474489}
475490pub mod task {
476491 pub enum Poll < T > {
You can’t perform that action at this time.
0 commit comments