55mod generics;
66mod path;
77
8- use std:: mem;
8+ use std:: { cell :: OnceCell , mem} ;
99
1010use base_db:: FxIndexSet ;
1111use cfg:: CfgOptions ;
@@ -57,7 +57,7 @@ use crate::{
5757 } ,
5858 item_scope:: BuiltinShadowMode ,
5959 item_tree:: FieldsShape ,
60- lang_item:: LangItem ,
60+ lang_item:: { LangItemTarget , LangItems } ,
6161 nameres:: { DefMap , LocalDefMap , MacroSubNs , block_def_map} ,
6262 type_ref:: {
6363 ArrayType , ConstRef , FnType , LifetimeRef , LifetimeRefId , Mutability , PathId , Rawness ,
@@ -416,6 +416,7 @@ pub struct ExprCollector<'db> {
416416 def_map : & ' db DefMap ,
417417 local_def_map : & ' db LocalDefMap ,
418418 module : ModuleId ,
419+ lang_items : OnceCell < & ' db LangItems > ,
419420 pub store : ExpressionStoreBuilder ,
420421
421422 // state stuff
@@ -513,7 +514,7 @@ impl BindingList {
513514 }
514515}
515516
516- impl ExprCollector < ' _ > {
517+ impl < ' db > ExprCollector < ' db > {
517518 pub fn new (
518519 db : & dyn DefDatabase ,
519520 module : ModuleId ,
@@ -527,6 +528,7 @@ impl ExprCollector<'_> {
527528 module,
528529 def_map,
529530 local_def_map,
531+ lang_items : OnceCell :: new ( ) ,
530532 store : ExpressionStoreBuilder :: default ( ) ,
531533 expander,
532534 current_try_block_label : None ,
@@ -539,6 +541,11 @@ impl ExprCollector<'_> {
539541 }
540542 }
541543
544+ #[ inline]
545+ pub ( crate ) fn lang_items ( & self ) -> & ' db LangItems {
546+ self . lang_items . get_or_init ( || crate :: lang_item:: lang_items ( self . db , self . module . krate ) )
547+ }
548+
542549 #[ inline]
543550 pub ( crate ) fn span_map ( & self ) -> SpanMapRef < ' _ > {
544551 self . expander . span_map ( )
@@ -1654,7 +1661,7 @@ impl ExprCollector<'_> {
16541661 /// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }`
16551662 /// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator.
16561663 fn desugar_try_block ( & mut self , e : BlockExpr ) -> ExprId {
1657- let try_from_output = self . lang_path ( LangItem :: TryTraitFromOutput ) ;
1664+ let try_from_output = self . lang_path ( self . lang_items ( ) . TryTraitFromOutput ) ;
16581665 let label = self . alloc_label_desugared ( Label {
16591666 name : Name :: generate_new_name ( self . store . labels . len ( ) ) ,
16601667 } ) ;
@@ -1753,10 +1760,11 @@ impl ExprCollector<'_> {
17531760 /// }
17541761 /// ```
17551762 fn collect_for_loop ( & mut self , syntax_ptr : AstPtr < ast:: Expr > , e : ast:: ForExpr ) -> ExprId {
1756- let into_iter_fn = self . lang_path ( LangItem :: IntoIterIntoIter ) ;
1757- let iter_next_fn = self . lang_path ( LangItem :: IteratorNext ) ;
1758- let option_some = self . lang_path ( LangItem :: OptionSome ) ;
1759- let option_none = self . lang_path ( LangItem :: OptionNone ) ;
1763+ let lang_items = self . lang_items ( ) ;
1764+ let into_iter_fn = self . lang_path ( lang_items. IntoIterIntoIter ) ;
1765+ let iter_next_fn = self . lang_path ( lang_items. IteratorNext ) ;
1766+ let option_some = self . lang_path ( lang_items. OptionSome ) ;
1767+ let option_none = self . lang_path ( lang_items. OptionNone ) ;
17601768 let head = self . collect_expr_opt ( e. iterable ( ) ) ;
17611769 let into_iter_fn_expr =
17621770 self . alloc_expr ( into_iter_fn. map_or ( Expr :: Missing , Expr :: Path ) , syntax_ptr) ;
@@ -1836,10 +1844,11 @@ impl ExprCollector<'_> {
18361844 /// }
18371845 /// ```
18381846 fn collect_try_operator ( & mut self , syntax_ptr : AstPtr < ast:: Expr > , e : ast:: TryExpr ) -> ExprId {
1839- let try_branch = self . lang_path ( LangItem :: TryTraitBranch ) ;
1840- let cf_continue = self . lang_path ( LangItem :: ControlFlowContinue ) ;
1841- let cf_break = self . lang_path ( LangItem :: ControlFlowBreak ) ;
1842- let try_from_residual = self . lang_path ( LangItem :: TryTraitFromResidual ) ;
1847+ let lang_items = self . lang_items ( ) ;
1848+ let try_branch = self . lang_path ( lang_items. TryTraitBranch ) ;
1849+ let cf_continue = self . lang_path ( lang_items. ControlFlowContinue ) ;
1850+ let cf_break = self . lang_path ( lang_items. ControlFlowBreak ) ;
1851+ let try_from_residual = self . lang_path ( lang_items. TryTraitFromResidual ) ;
18431852 let operand = self . collect_expr_opt ( e. expr ( ) ) ;
18441853 let try_branch = self . alloc_expr ( try_branch. map_or ( Expr :: Missing , Expr :: Path ) , syntax_ptr) ;
18451854 let expr = self
@@ -2773,11 +2782,10 @@ impl ExprCollector<'_> {
27732782
27742783 // Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists
27752784 // but `format_unsafe_arg` does not
2776- let fmt_args =
2777- || crate :: lang_item:: lang_item ( self . db , self . module . krate ( ) , LangItem :: FormatArguments ) ;
2778- let fmt_unsafe_arg =
2779- || crate :: lang_item:: lang_item ( self . db , self . module . krate ( ) , LangItem :: FormatUnsafeArg ) ;
2780- let use_format_args_since_1_89_0 = fmt_args ( ) . is_some ( ) && fmt_unsafe_arg ( ) . is_none ( ) ;
2785+ let lang_items = self . lang_items ( ) ;
2786+ let fmt_args = lang_items. FormatArguments ;
2787+ let fmt_unsafe_arg = lang_items. FormatUnsafeArg ;
2788+ let use_format_args_since_1_89_0 = fmt_args. is_some ( ) && fmt_unsafe_arg. is_none ( ) ;
27812789
27822790 let idx = if use_format_args_since_1_89_0 {
27832791 self . collect_format_args_impl ( syntax_ptr, fmt, argmap, lit_pieces, format_options)
@@ -2856,16 +2864,13 @@ impl ExprCollector<'_> {
28562864 // unsafe { ::core::fmt::UnsafeArg::new() }
28572865 // )
28582866
2859- let new_v1_formatted = LangItem :: FormatArguments . ty_rel_path (
2860- self . db ,
2861- self . module . krate ( ) ,
2867+ let lang_items = self . lang_items ( ) ;
2868+ let new_v1_formatted = self . ty_rel_lang_path (
2869+ lang_items . FormatArguments ,
28622870 Name :: new_symbol_root ( sym:: new_v1_formatted) ,
28632871 ) ;
2864- let unsafe_arg_new = LangItem :: FormatUnsafeArg . ty_rel_path (
2865- self . db ,
2866- self . module . krate ( ) ,
2867- Name :: new_symbol_root ( sym:: new) ,
2868- ) ;
2872+ let unsafe_arg_new =
2873+ self . ty_rel_lang_path ( lang_items. FormatUnsafeArg , Name :: new_symbol_root ( sym:: new) ) ;
28692874 let new_v1_formatted =
28702875 self . alloc_expr_desugared ( new_v1_formatted. map_or ( Expr :: Missing , Expr :: Path ) ) ;
28712876
@@ -3044,9 +3049,8 @@ impl ExprCollector<'_> {
30443049 // )
30453050 // }
30463051
3047- let new_v1_formatted = LangItem :: FormatArguments . ty_rel_path (
3048- self . db ,
3049- self . module . krate ( ) ,
3052+ let new_v1_formatted = self . ty_rel_lang_path (
3053+ self . lang_items ( ) . FormatArguments ,
30503054 Name :: new_symbol_root ( sym:: new_v1_formatted) ,
30513055 ) ;
30523056 let new_v1_formatted =
@@ -3099,6 +3103,7 @@ impl ExprCollector<'_> {
30993103 placeholder : & FormatPlaceholder ,
31003104 argmap : & mut FxIndexSet < ( usize , ArgumentType ) > ,
31013105 ) -> ExprId {
3106+ let lang_items = self . lang_items ( ) ;
31023107 let position = match placeholder. argument . index {
31033108 Ok ( arg_index) => {
31043109 let ( i, _) =
@@ -3159,15 +3164,14 @@ impl ExprCollector<'_> {
31593164 let width =
31603165 RecordLitField { name : Name :: new_symbol_root ( sym:: width) , expr : width_expr } ;
31613166 self . alloc_expr_desugared ( Expr :: RecordLit {
3162- path : LangItem :: FormatPlaceholder . path ( self . db , self . module . krate ( ) ) . map ( Box :: new) ,
3167+ path : self . lang_path ( lang_items . FormatPlaceholder ) . map ( Box :: new) ,
31633168 fields : Box :: new ( [ position, flags, precision, width] ) ,
31643169 spread : None ,
31653170 } )
31663171 } else {
31673172 let format_placeholder_new = {
3168- let format_placeholder_new = LangItem :: FormatPlaceholder . ty_rel_path (
3169- self . db ,
3170- self . module . krate ( ) ,
3173+ let format_placeholder_new = self . ty_rel_lang_path (
3174+ lang_items. FormatPlaceholder ,
31713175 Name :: new_symbol_root ( sym:: new) ,
31723176 ) ;
31733177 match format_placeholder_new {
@@ -3188,9 +3192,8 @@ impl ExprCollector<'_> {
31883192 ) ) ) ;
31893193 let fill = self . alloc_expr_desugared ( Expr :: Literal ( Literal :: Char ( fill. unwrap_or ( ' ' ) ) ) ) ;
31903194 let align = {
3191- let align = LangItem :: FormatAlignment . ty_rel_path (
3192- self . db ,
3193- self . module . krate ( ) ,
3195+ let align = self . ty_rel_lang_path (
3196+ lang_items. FormatAlignment ,
31943197 match alignment {
31953198 Some ( FormatAlignment :: Left ) => Name :: new_symbol_root ( sym:: Left ) ,
31963199 Some ( FormatAlignment :: Right ) => Name :: new_symbol_root ( sym:: Right ) ,
@@ -3234,18 +3237,17 @@ impl ExprCollector<'_> {
32343237 count : & Option < FormatCount > ,
32353238 argmap : & mut FxIndexSet < ( usize , ArgumentType ) > ,
32363239 ) -> ExprId {
3240+ let lang_items = self . lang_items ( ) ;
32373241 match count {
32383242 Some ( FormatCount :: Literal ( n) ) => {
32393243 let args = self . alloc_expr_desugared ( Expr :: Literal ( Literal :: Uint (
32403244 * n as u128 ,
32413245 // FIXME: Change this to Some(BuiltinUint::U16) once we drop support for toolchains < 1.88
32423246 None ,
32433247 ) ) ) ;
3244- let count_is = match LangItem :: FormatCount . ty_rel_path (
3245- self . db ,
3246- self . module . krate ( ) ,
3247- Name :: new_symbol_root ( sym:: Is ) ,
3248- ) {
3248+ let count_is = match self
3249+ . ty_rel_lang_path ( lang_items. FormatCount , Name :: new_symbol_root ( sym:: Is ) )
3250+ {
32493251 Some ( count_is) => self . alloc_expr_desugared ( Expr :: Path ( count_is) ) ,
32503252 None => self . missing_expr ( ) ,
32513253 } ;
@@ -3259,11 +3261,9 @@ impl ExprCollector<'_> {
32593261 i as u128 ,
32603262 Some ( BuiltinUint :: Usize ) ,
32613263 ) ) ) ;
3262- let count_param = match LangItem :: FormatCount . ty_rel_path (
3263- self . db ,
3264- self . module . krate ( ) ,
3265- Name :: new_symbol_root ( sym:: Param ) ,
3266- ) {
3264+ let count_param = match self
3265+ . ty_rel_lang_path ( lang_items. FormatCount , Name :: new_symbol_root ( sym:: Param ) )
3266+ {
32673267 Some ( count_param) => self . alloc_expr_desugared ( Expr :: Path ( count_param) ) ,
32683268 None => self . missing_expr ( ) ,
32693269 } ;
@@ -3277,11 +3277,9 @@ impl ExprCollector<'_> {
32773277 self . missing_expr ( )
32783278 }
32793279 }
3280- None => match LangItem :: FormatCount . ty_rel_path (
3281- self . db ,
3282- self . module . krate ( ) ,
3283- Name :: new_symbol_root ( sym:: Implied ) ,
3284- ) {
3280+ None => match self
3281+ . ty_rel_lang_path ( lang_items. FormatCount , Name :: new_symbol_root ( sym:: Implied ) )
3282+ {
32853283 Some ( count_param) => self . alloc_expr_desugared ( Expr :: Path ( count_param) ) ,
32863284 None => self . missing_expr ( ) ,
32873285 } ,
@@ -3299,9 +3297,8 @@ impl ExprCollector<'_> {
32993297 use ArgumentType :: * ;
33003298 use FormatTrait :: * ;
33013299
3302- let new_fn = match LangItem :: FormatArgument . ty_rel_path (
3303- self . db ,
3304- self . module . krate ( ) ,
3300+ let new_fn = match self . ty_rel_lang_path (
3301+ self . lang_items ( ) . FormatArgument ,
33053302 Name :: new_symbol_root ( match ty {
33063303 Format ( Display ) => sym:: new_display,
33073304 Format ( Debug ) => sym:: new_debug,
@@ -3323,8 +3320,16 @@ impl ExprCollector<'_> {
33233320
33243321 // endregion: format
33253322
3326- fn lang_path ( & self , lang : LangItem ) -> Option < Path > {
3327- lang. path ( self . db , self . module . krate ( ) )
3323+ fn lang_path ( & self , lang : Option < impl Into < LangItemTarget > > ) -> Option < Path > {
3324+ Some ( Path :: LangItem ( lang?. into ( ) , None ) )
3325+ }
3326+
3327+ fn ty_rel_lang_path (
3328+ & self ,
3329+ lang : Option < impl Into < LangItemTarget > > ,
3330+ relative_name : Name ,
3331+ ) -> Option < Path > {
3332+ Some ( Path :: LangItem ( lang?. into ( ) , Some ( relative_name) ) )
33283333 }
33293334}
33303335
0 commit comments