@@ -37,7 +37,7 @@ use crate::{
3737 attrs:: AttrFlags ,
3838 db:: DefDatabase ,
3939 expr_store:: {
40- Body , BodySourceMap , ExprPtr , ExpressionStore , ExpressionStoreBuilder ,
40+ Body , BodySourceMap , ConstExprOrigin , ExprPtr , ExpressionStore , ExpressionStoreBuilder ,
4141 ExpressionStoreDiagnostics , ExpressionStoreSourceMap , HygieneId , LabelPtr , LifetimePtr ,
4242 PatPtr , TypePtr ,
4343 expander:: Expander ,
@@ -79,7 +79,7 @@ pub(super) fn lower_body(
7979 let mut self_param = None ;
8080 let mut source_map_self_param = None ;
8181 let mut params = vec ! [ ] ;
82- let mut collector = ExprCollector :: new ( db, module, current_file_id) ;
82+ let mut collector = ExprCollector :: body ( db, module, current_file_id) ;
8383
8484 let skip_body = AttrFlags :: query (
8585 db,
@@ -186,7 +186,7 @@ pub(crate) fn lower_type_ref(
186186 module : ModuleId ,
187187 type_ref : InFile < Option < ast:: Type > > ,
188188) -> ( ExpressionStore , ExpressionStoreSourceMap , TypeRefId ) {
189- let mut expr_collector = ExprCollector :: new ( db, module, type_ref. file_id ) ;
189+ let mut expr_collector = ExprCollector :: signature ( db, module, type_ref. file_id ) ;
190190 let type_ref =
191191 expr_collector. lower_type_ref_opt ( type_ref. value , & mut ExprCollector :: impl_trait_allocator) ;
192192 let ( store, source_map) = expr_collector. store . finish ( ) ;
@@ -201,7 +201,7 @@ pub(crate) fn lower_generic_params(
201201 param_list : Option < ast:: GenericParamList > ,
202202 where_clause : Option < ast:: WhereClause > ,
203203) -> ( Arc < ExpressionStore > , Arc < GenericParams > , ExpressionStoreSourceMap ) {
204- let mut expr_collector = ExprCollector :: new ( db, module, file_id) ;
204+ let mut expr_collector = ExprCollector :: signature ( db, module, file_id) ;
205205 let mut collector = generics:: GenericParamsCollector :: new ( def) ;
206206 collector. lower ( & mut expr_collector, param_list, where_clause) ;
207207 let params = collector. finish ( ) ;
@@ -215,7 +215,7 @@ pub(crate) fn lower_impl(
215215 impl_syntax : InFile < ast:: Impl > ,
216216 impl_id : ImplId ,
217217) -> ( ExpressionStore , ExpressionStoreSourceMap , TypeRefId , Option < TraitRef > , Arc < GenericParams > ) {
218- let mut expr_collector = ExprCollector :: new ( db, module, impl_syntax. file_id ) ;
218+ let mut expr_collector = ExprCollector :: signature ( db, module, impl_syntax. file_id ) ;
219219 let self_ty =
220220 expr_collector. lower_type_ref_opt_disallow_impl_trait ( impl_syntax. value . self_ty ( ) ) ;
221221 let trait_ = impl_syntax. value . trait_ ( ) . and_then ( |it| match & it {
@@ -243,7 +243,7 @@ pub(crate) fn lower_trait(
243243 trait_syntax : InFile < ast:: Trait > ,
244244 trait_id : TraitId ,
245245) -> ( ExpressionStore , ExpressionStoreSourceMap , Arc < GenericParams > ) {
246- let mut expr_collector = ExprCollector :: new ( db, module, trait_syntax. file_id ) ;
246+ let mut expr_collector = ExprCollector :: signature ( db, module, trait_syntax. file_id ) ;
247247 let mut collector = generics:: GenericParamsCollector :: with_self_param (
248248 & mut expr_collector,
249249 trait_id. into ( ) ,
@@ -271,7 +271,7 @@ pub(crate) fn lower_type_alias(
271271 Box < [ TypeBound ] > ,
272272 Option < TypeRefId > ,
273273) {
274- let mut expr_collector = ExprCollector :: new ( db, module, alias. file_id ) ;
274+ let mut expr_collector = ExprCollector :: signature ( db, module, alias. file_id ) ;
275275 let bounds = alias
276276 . value
277277 . type_bound_list ( )
@@ -313,7 +313,7 @@ pub(crate) fn lower_function(
313313 bool ,
314314 bool ,
315315) {
316- let mut expr_collector = ExprCollector :: new ( db, module, fn_. file_id ) ;
316+ let mut expr_collector = ExprCollector :: signature ( db, module, fn_. file_id ) ;
317317 let mut collector = generics:: GenericParamsCollector :: new ( function_id. into ( ) ) ;
318318 collector. lower ( & mut expr_collector, fn_. value . generic_param_list ( ) , fn_. value . where_clause ( ) ) ;
319319 let mut params = vec ! [ ] ;
@@ -532,7 +532,20 @@ impl BindingList {
532532}
533533
534534impl < ' db > ExprCollector < ' db > {
535- pub fn new (
535+ /// Creates a collector for a signature store, this will populate `const_expr_origins` to any
536+ /// top level const arg roots.
537+ pub fn signature (
538+ db : & dyn DefDatabase ,
539+ module : ModuleId ,
540+ current_file_id : HirFileId ,
541+ ) -> ExprCollector < ' _ > {
542+ let mut this = Self :: body ( db, module, current_file_id) ;
543+ this. store . const_expr_origins = Some ( Default :: default ( ) ) ;
544+ this
545+ }
546+
547+ /// Creates a collector for a bidy store.
548+ pub fn body (
536549 db : & dyn DefDatabase ,
537550 module : ModuleId ,
538551 current_file_id : HirFileId ,
@@ -577,7 +590,10 @@ impl<'db> ExprCollector<'db> {
577590 self . expander . span_map ( )
578591 }
579592
580- pub fn lower_lifetime_ref ( & mut self , lifetime : ast:: Lifetime ) -> LifetimeRefId {
593+ pub ( in crate :: expr_store) fn lower_lifetime_ref (
594+ & mut self ,
595+ lifetime : ast:: Lifetime ,
596+ ) -> LifetimeRefId {
581597 // FIXME: Keyword check?
582598 let lifetime_ref = match & * lifetime. text ( ) {
583599 "" | "'" => LifetimeRef :: Error ,
@@ -588,15 +604,18 @@ impl<'db> ExprCollector<'db> {
588604 self . alloc_lifetime_ref ( lifetime_ref, AstPtr :: new ( & lifetime) )
589605 }
590606
591- pub fn lower_lifetime_ref_opt ( & mut self , lifetime : Option < ast:: Lifetime > ) -> LifetimeRefId {
607+ pub ( in crate :: expr_store) fn lower_lifetime_ref_opt (
608+ & mut self ,
609+ lifetime : Option < ast:: Lifetime > ,
610+ ) -> LifetimeRefId {
592611 match lifetime {
593612 Some ( lifetime) => self . lower_lifetime_ref ( lifetime) ,
594613 None => self . alloc_lifetime_ref_desugared ( LifetimeRef :: Placeholder ) ,
595614 }
596615 }
597616
598617 /// Converts an `ast::TypeRef` to a `hir::TypeRef`.
599- pub fn lower_type_ref (
618+ pub ( in crate :: expr_store ) fn lower_type_ref (
600619 & mut self ,
601620 node : ast:: Type ,
602621 impl_trait_lower_fn : ImplTraitLowerFn < ' _ > ,
@@ -621,6 +640,9 @@ impl<'db> ExprCollector<'db> {
621640 }
622641 ast:: Type :: ArrayType ( inner) => {
623642 let len = self . lower_const_arg_opt ( inner. const_arg ( ) ) ;
643+ if let Some ( const_expr_origins) = & mut self . store . const_expr_origins {
644+ const_expr_origins. push ( ( len. expr , ConstExprOrigin :: ArrayLength ) ) ;
645+ }
624646 TypeRef :: Array ( ArrayType {
625647 ty : self . lower_type_ref_opt ( inner. ty ( ) , impl_trait_lower_fn) ,
626648 len,
@@ -810,7 +832,7 @@ impl<'db> ExprCollector<'db> {
810832
811833 /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
812834 /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
813- pub fn lower_generic_args_from_fn_path (
835+ pub ( in crate :: expr_store ) fn lower_generic_args_from_fn_path (
814836 & mut self ,
815837 args : Option < ast:: ParenthesizedArgList > ,
816838 ret_type : Option < ast:: RetType > ,
@@ -905,6 +927,9 @@ impl<'db> ExprCollector<'db> {
905927 }
906928 ast:: GenericArg :: ConstArg ( arg) => {
907929 let arg = self . lower_const_arg ( arg) ;
930+ if let Some ( const_expr_origins) = & mut self . store . const_expr_origins {
931+ const_expr_origins. push ( ( arg. expr , ConstExprOrigin :: GenericArgsPath ) ) ;
932+ }
908933 args. push ( GenericArg :: Const ( arg) )
909934 }
910935 }
@@ -1045,17 +1070,30 @@ impl<'db> ExprCollector<'db> {
10451070 }
10461071
10471072 fn lower_const_arg_opt ( & mut self , arg : Option < ast:: ConstArg > ) -> ConstRef {
1048- ConstRef { expr : self . collect_expr_opt ( arg. and_then ( |it| it. expr ( ) ) ) }
1073+ let const_expr_origins = self . store . const_expr_origins . take ( ) ;
1074+ let r = ConstRef { expr : self . collect_expr_opt ( arg. and_then ( |it| it. expr ( ) ) ) } ;
1075+ self . store . const_expr_origins = const_expr_origins;
1076+ r
10491077 }
10501078
1051- fn lower_const_arg ( & mut self , arg : ast:: ConstArg ) -> ConstRef {
1052- ConstRef { expr : self . collect_expr_opt ( arg. expr ( ) ) }
1079+ pub fn lower_const_arg ( & mut self , arg : ast:: ConstArg ) -> ConstRef {
1080+ let const_expr_origins = self . store . const_expr_origins . take ( ) ;
1081+ let r = ConstRef { expr : self . collect_expr_opt ( arg. expr ( ) ) } ;
1082+ self . store . const_expr_origins = const_expr_origins;
1083+ r
10531084 }
10541085
10551086 fn collect_expr ( & mut self , expr : ast:: Expr ) -> ExprId {
10561087 self . maybe_collect_expr ( expr) . unwrap_or_else ( || self . missing_expr ( ) )
10571088 }
10581089
1090+ pub ( in crate :: expr_store) fn collect_expr_opt ( & mut self , expr : Option < ast:: Expr > ) -> ExprId {
1091+ match expr {
1092+ Some ( expr) => self . collect_expr ( expr) ,
1093+ None => self . missing_expr ( ) ,
1094+ }
1095+ }
1096+
10591097 /// Returns `None` if and only if the expression is `#[cfg]`d out.
10601098 fn maybe_collect_expr ( & mut self , expr : ast:: Expr ) -> Option < ExprId > {
10611099 let syntax_ptr = AstPtr :: new ( & expr) ;
@@ -2065,13 +2103,6 @@ impl<'db> ExprCollector<'db> {
20652103 }
20662104 }
20672105
2068- pub fn collect_expr_opt ( & mut self , expr : Option < ast:: Expr > ) -> ExprId {
2069- match expr {
2070- Some ( expr) => self . collect_expr ( expr) ,
2071- None => self . missing_expr ( ) ,
2072- }
2073- }
2074-
20752106 fn collect_macro_as_stmt (
20762107 & mut self ,
20772108 statements : & mut Vec < Statement > ,
0 commit comments