Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6438554

Browse files
committed
Show fn traits in signature info for trait implementors
1 parentf42e55d commit6438554

File tree

8 files changed

+196
-68
lines changed

8 files changed

+196
-68
lines changed

‎src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -797,19 +797,22 @@ impl<'a> InferenceTable<'a> {
797797
})
798798
.build();
799799

800-
let projection ={
801-
let b =TyBuilder::subst_for_def(self.db, fn_once_trait,None);
802-
if b.remaining() !=2{
803-
returnNone;
804-
}
805-
let fn_once_subst = b.push(ty.clone()).push(arg_ty).build();
800+
let b =TyBuilder::trait_ref(self.db, fn_once_trait);
801+
if b.remaining() !=2{
802+
returnNone;
803+
}
804+
letmut trait_ref = b.push(ty.clone()).push(arg_ty).build();
806805

807-
TyBuilder::assoc_type_projection(self.db, output_assoc_type,Some(fn_once_subst))
808-
.build()
806+
let projection ={
807+
TyBuilder::assoc_type_projection(
808+
self.db,
809+
output_assoc_type,
810+
Some(trait_ref.substitution.clone()),
811+
)
812+
.build()
809813
};
810814

811815
let trait_env =self.trait_env.env.clone();
812-
letmut trait_ref = projection.trait_ref(self.db);
813816
let obligation =InEnvironment{
814817
goal: trait_ref.clone().cast(Interner),
815818
environment: trait_env.clone(),

‎src/tools/rust-analyzer/crates/hir-ty/src/lib.rs‎

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,10 @@ impl CallableSig {
570570
}
571571
}
572572

573+
pubfnabi(&self) ->FnAbi{
574+
self.abi
575+
}
576+
573577
pubfnparams(&self) ->&[Ty]{
574578
&self.params_and_return[0..self.params_and_return.len() -1]
575579
}
@@ -892,20 +896,16 @@ where
892896
Canonical{ value,binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds)}
893897
}
894898

895-
pubfncallable_sig_from_fnonce(
896-
mutself_ty:&Ty,
897-
env:Arc<TraitEnvironment>,
899+
pubfncallable_sig_from_fn_trait(
900+
self_ty:&Ty,
901+
trait_env:Arc<TraitEnvironment>,
898902
db:&dynHirDatabase,
899-
) ->Option<CallableSig>{
900-
ifletSome((ty, _, _)) = self_ty.as_reference(){
901-
// This will happen when it implements fn or fn mut, since we add a autoborrow adjustment
902-
self_ty = ty;
903-
}
904-
let krate = env.krate;
903+
) ->Option<(FnTrait,CallableSig)>{
904+
let krate = trait_env.krate;
905905
let fn_once_trait =FnTrait::FnOnce.get_id(db, krate)?;
906906
let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
907907

908-
letmut table =InferenceTable::new(db,env);
908+
letmut table =InferenceTable::new(db,trait_env.clone());
909909
let b =TyBuilder::trait_ref(db, fn_once_trait);
910910
if b.remaining() !=2{
911911
returnNone;
@@ -915,23 +915,56 @@ pub fn callable_sig_from_fnonce(
915915
// - Self: FnOnce<?args_ty>
916916
// - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
917917
let args_ty = table.new_type_var();
918-
let trait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build();
918+
letmuttrait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build();
919919
let projection =TyBuilder::assoc_type_projection(
920920
db,
921921
output_assoc_type,
922922
Some(trait_ref.substitution.clone()),
923923
)
924924
.build();
925-
table.register_obligation(trait_ref.cast(Interner));
926-
let ret_ty = table.normalize_projection_ty(projection);
927-
928-
let ret_ty = table.resolve_completely(ret_ty);
929-
let args_ty = table.resolve_completely(args_ty);
930925

931-
let params =
932-
args_ty.as_tuple()?.iter(Interner).map(|it| it.assert_ty_ref(Interner)).cloned().collect();
933-
934-
Some(CallableSig::from_params_and_return(params, ret_ty,false,Safety::Safe,FnAbi::RustCall))
926+
let block = trait_env.block;
927+
let trait_env = trait_env.env.clone();
928+
let obligation =
929+
InEnvironment{goal: trait_ref.clone().cast(Interner),environment: trait_env.clone()};
930+
let canonical = table.canonicalize(obligation.clone());
931+
if db.trait_solve(krate, block, canonical.cast(Interner)).is_some(){
932+
table.register_obligation(obligation.goal);
933+
let return_ty = table.normalize_projection_ty(projection);
934+
for fn_xin[FnTrait::Fn,FnTrait::FnMut,FnTrait::FnOnce]{
935+
let fn_x_trait = fn_x.get_id(db, krate)?;
936+
trait_ref.trait_id =to_chalk_trait_id(fn_x_trait);
937+
let obligation: chalk_ir::InEnvironment<chalk_ir::Goal<Interner>> =InEnvironment{
938+
goal: trait_ref.clone().cast(Interner),
939+
environment: trait_env.clone(),
940+
};
941+
let canonical = table.canonicalize(obligation.clone());
942+
if db.trait_solve(krate, block, canonical.cast(Interner)).is_some(){
943+
let ret_ty = table.resolve_completely(return_ty);
944+
let args_ty = table.resolve_completely(args_ty);
945+
let params = args_ty
946+
.as_tuple()?
947+
.iter(Interner)
948+
.map(|it| it.assert_ty_ref(Interner))
949+
.cloned()
950+
.collect();
951+
952+
returnSome((
953+
fn_x,
954+
CallableSig::from_params_and_return(
955+
params,
956+
ret_ty,
957+
false,
958+
Safety::Safe,
959+
FnAbi::RustCall,
960+
),
961+
));
962+
}
963+
}
964+
unreachable!("It should at least implement FnOnce at this point");
965+
}else{
966+
None
967+
}
935968
}
936969

937970
structPlaceholderCollector<'db>{

‎src/tools/rust-analyzer/crates/hir-ty/src/traits.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ impl fmt::Display for FnTrait {
221221
}
222222

223223
implFnTrait{
224+
pubconstfnfunction_name(&self) ->&'staticstr{
225+
matchself{
226+
FnTrait::FnOnce =>"call_once",
227+
FnTrait::FnMut =>"call_mut",
228+
FnTrait::Fn =>"call",
229+
}
230+
}
231+
224232
constfnlang_item(self) ->LangItem{
225233
matchself{
226234
FnTrait::FnOnce =>LangItem::FnOnce,

‎src/tools/rust-analyzer/crates/hir/src/lib.rs‎

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub use {
140140
display::{ClosureStyle,HirDisplay,HirDisplayError,HirWrite},
141141
layout::LayoutError,
142142
mir::{MirEvalError,MirLowerError},
143-
PointerCast,Safety,
143+
FnAbi,PointerCast,Safety,
144144
},
145145
// FIXME: Properly encapsulate mir
146146
hir_ty::{mir,InternerasChalkTyInterner},
@@ -2227,7 +2227,7 @@ impl Param {
22272227
letInFile{ file_id, value} =Function{id: func}.source(db)?;
22282228
let params = value.param_list()?;
22292229
ifletSome(self_param) = params.self_param(){
2230-
ifletSome(idx) =self.idx.checked_sub(1asusize){
2230+
ifletSome(idx) =self.idx.checked_sub(1){
22312231
params.params().nth(idx).map(Either::Right)
22322232
}else{
22332233
Some(Either::Left(self_param))
@@ -4321,23 +4321,26 @@ impl Type {
43214321
TyKind::Function(_) =>Callee::FnPtr,
43224322
TyKind::FnDef(..) =>Callee::Def(self.ty.callable_def(db)?),
43234323
kind =>{
4324-
// This branch shouldn't be necessary?
4325-
ifletTyKind::Ref(_, _, ty) = kind{
4326-
ifletTyKind::Closure(closure, subst) = ty.kind(Interner){
4327-
let sig = ty.callable_sig(db)?;
4328-
returnSome(Callable{
4329-
ty:self.clone(),
4330-
sig,
4331-
callee:Callee::Closure(*closure, subst.clone()),
4332-
is_bound_method:false,
4333-
});
4334-
}
4324+
// This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
4325+
let(ty, kind) =ifletTyKind::Ref(_, _, ty) = kind{
4326+
(ty, ty.kind(Interner))
4327+
}else{
4328+
(&self.ty, kind)
4329+
};
4330+
ifletTyKind::Closure(closure, subst) = kind{
4331+
let sig = ty.callable_sig(db)?;
4332+
returnSome(Callable{
4333+
ty:self.clone(),
4334+
sig,
4335+
callee:Callee::Closure(*closure, subst.clone()),
4336+
is_bound_method:false,
4337+
});
43354338
}
4336-
let sig = hir_ty::callable_sig_from_fnonce(&self.ty,self.env.clone(), db)?;
4339+
let(fn_trait,sig) = hir_ty::callable_sig_from_fn_trait(ty,self.env.clone(), db)?;
43374340
returnSome(Callable{
43384341
ty:self.clone(),
43394342
sig,
4340-
callee:Callee::Other,
4343+
callee:Callee::FnImpl(fn_trait),
43414344
is_bound_method:false,
43424345
});
43434346
}
@@ -4968,7 +4971,7 @@ enum Callee {
49684971
Def(CallableDefId),
49694972
Closure(ClosureId,Substitution),
49704973
FnPtr,
4971-
Other,
4974+
FnImpl(FnTrait),
49724975
}
49734976

49744977
pubenumCallableKind{
@@ -4977,8 +4980,7 @@ pub enum CallableKind {
49774980
TupleEnumVariant(Variant),
49784981
Closure(Closure),
49794982
FnPtr,
4980-
/// Some other type that implements `FnOnce`.
4981-
Other,
4983+
FnImpl(FnTrait),
49824984
}
49834985

49844986
implCallable{
@@ -4993,7 +4995,7 @@ impl Callable {
49934995
CallableKind::Closure(Closure{ id,subst: subst.clone()})
49944996
}
49954997
Callee::FnPtr =>CallableKind::FnPtr,
4996-
Callee::Other =>CallableKind::Other,
4998+
Callee::FnImpl(fn_) =>CallableKind::FnImpl(fn_),
49974999
}
49985000
}
49995001
pubfnreceiver_param(&self,db:&dynHirDatabase) ->Option<(SelfParam,Type)>{
@@ -5023,6 +5025,10 @@ impl Callable {
50235025
pubfnsig(&self) ->&CallableSig{
50245026
&self.sig
50255027
}
5028+
5029+
pubfnty(&self) ->&Type{
5030+
&self.ty
5031+
}
50265032
}
50275033

50285034
#[derive(Clone,Debug,Eq,PartialEq)]

‎src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ impl SourceAnalyzer {
307307
db:&dynHirDatabase,
308308
call:&ast::Expr,
309309
) ->Option<Callable>{
310-
self.type_of_expr(db,&call.clone())?.0.as_callable(db)
310+
let(orig, adjusted) =self.type_of_expr(db,&call.clone())?;
311+
adjusted.unwrap_or(orig).as_callable(db)
311312
}
312313

313314
pub(crate)fnresolve_field(

‎src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ pub fn callable_for_node(
6060
token:&SyntaxToken,
6161
) ->Option<(hir::Callable,Option<usize>)>{
6262
let callable =match calling_node{
63-
ast::CallableExpr::Call(call) =>{
64-
let expr = call.expr()?;
65-
sema.type_of_expr(&expr)?.adjusted().as_callable(sema.db)
66-
}
63+
ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?),
6764
ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call),
6865
}?;
6966
let active_param = calling_node.arg_list().map(|arg_list|{

‎src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ pub(crate) fn outgoing_calls(
109109
let expr = call.expr()?;
110110
let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?;
111111
match callable.kind(){
112-
hir::CallableKind::Function(it) =>{
113-
let range = expr.syntax().text_range();
114-
it.try_to_nav(db).zip(Some(range))
115-
}
112+
hir::CallableKind::Function(it) => it.try_to_nav(db),
113+
hir::CallableKind::TupleEnumVariant(it) => it.try_to_nav(db),
114+
hir::CallableKind::TupleStruct(it) => it.try_to_nav(db),
116115
_ =>None,
117116
}
117+
.zip(Some(expr.syntax().text_range()))
118118
}
119119
ast::CallableExpr::MethodCall(expr) =>{
120120
let range = expr.name_ref()?.syntax().text_range();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp