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 {
257
257
( core:: ops:: RangeToInclusive ) => { } ;
258
258
( core:: ops:: RangeInclusive ) => { } ;
259
259
( core:: future:: Future ) => { } ;
260
+ ( core:: future:: IntoFuture ) => { } ;
260
261
( core:: ops:: Try ) => { } ;
261
262
( $path: path) => {
262
263
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 {
258
258
Try ,
259
259
Ok ,
260
260
Future ,
261
+ IntoFuture ,
261
262
Result ,
262
263
Option ,
263
264
Output ,
@@ -391,6 +392,7 @@ pub mod known {
391
392
future_trait,
392
393
index,
393
394
index_mut,
395
+ into_future,
394
396
mul_assign,
395
397
mul,
396
398
neg,
Original file line number Diff line number Diff line change @@ -875,7 +875,10 @@ impl<'a> InferenceContext<'a> {
875
875
}
876
876
877
877
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 ( ) ) ?;
879
882
self . db . trait_data ( trait_) . associated_type_by_name ( & name ! [ Output ] )
880
883
}
881
884
Original file line number Diff line number Diff line change @@ -137,6 +137,31 @@ fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
137
137
) ;
138
138
}
139
139
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
+
140
165
#[ test]
141
166
fn infer_try ( ) {
142
167
check_types (
Original file line number Diff line number Diff line change @@ -2780,6 +2780,8 @@ impl Type {
2780
2780
/// Checks that particular type `ty` implements `std::future::Future`.
2781
2781
/// This function is used in `.await` syntax completion.
2782
2782
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.
2783
2785
let std_future_trait = db
2784
2786
. lang_item ( self . env . krate , SmolStr :: new_inline ( "future_trait" ) )
2785
2787
. and_then ( |it| it. as_trait ( ) ) ;
Original file line number Diff line number Diff line change @@ -269,6 +269,8 @@ impl SourceAnalyzer {
269
269
db : & dyn HirDatabase ,
270
270
await_expr : & ast:: AwaitExpr ,
271
271
) -> 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.
272
274
let ty = self . ty_of_expr ( db, & await_expr. expr ( ) ?. into ( ) ) ?;
273
275
274
276
let op_fn = db
Original file line number Diff line number Diff line change @@ -55,6 +55,7 @@ const USELESS_METHODS: &[&str] = &[
55
55
"iter" ,
56
56
"into_iter" ,
57
57
"iter_mut" ,
58
+ "into_future" ,
58
59
] ;
59
60
60
61
pub ( 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 {}
75
75
fn foo(a: A) { a.$0 }
76
76
"# ,
77
77
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
88
89
"# ] ] ,
89
90
) ;
90
91
@@ -98,18 +99,19 @@ fn foo() {
98
99
}
99
100
"# ,
100
101
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
111
113
"# ] ] ,
112
- )
114
+ ) ;
113
115
}
114
116
115
117
#[ test]
Original file line number Diff line number Diff line change @@ -471,6 +471,21 @@ pub mod future {
471
471
#[ lang = "poll" ]
472
472
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > ;
473
473
}
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
+ }
474
489
}
475
490
pub mod task {
476
491
pub enum Poll < T > {
You can’t perform that action at this time.
0 commit comments