@@ -32,8 +32,8 @@ use triomphe::Arc;
3232use tt:: TextRange ;
3333
3434use crate :: {
35- AdtId , BlockId , BlockLoc , DefWithBodyId , FunctionId , GenericDefId , ImplId , MacroId ,
36- ModuleDefId , ModuleId , TraitId , TypeAliasId , UnresolvedMacro ,
35+ AdtId , BlockId , BlockLoc , DefWithBodyId , FunctionId , GenericDefId , ImplId , ItemContainerId ,
36+ MacroId , ModuleDefId , ModuleId , TraitId , TypeAliasId , UnresolvedMacro ,
3737 attrs:: AttrFlags ,
3838 db:: DefDatabase ,
3939 expr_store:: {
@@ -141,9 +141,19 @@ pub(super) fn lower_body(
141141 source_map_self_param = Some ( collector. expander . in_file ( AstPtr :: new ( & self_param_syn) ) ) ;
142142 }
143143
144+ let is_extern = matches ! (
145+ owner,
146+ DefWithBodyId :: FunctionId ( id)
147+ if matches!( id. loc( db) . container, ItemContainerId :: ExternBlockId ( _) ) ,
148+ ) ;
149+
144150 for param in param_list. params ( ) {
145151 if collector. check_cfg ( & param) {
146- let param_pat = collector. collect_pat_top ( param. pat ( ) ) ;
152+ let param_pat = if is_extern {
153+ collector. collect_extern_fn_param ( param. pat ( ) )
154+ } else {
155+ collector. collect_pat_top ( param. pat ( ) )
156+ } ;
147157 params. push ( param_pat) ;
148158 }
149159 }
@@ -2248,6 +2258,32 @@ impl<'db> ExprCollector<'db> {
22482258 }
22492259 }
22502260
2261+ fn collect_extern_fn_param ( & mut self , pat : Option < ast:: Pat > ) -> PatId {
2262+ // `extern` functions cannot have pattern-matched parameters, and furthermore, the identifiers
2263+ // in their parameters are always interpreted as bindings, even if in a normal function they
2264+ // won't be, because they would refer to a path pattern.
2265+ let Some ( pat) = pat else { return self . missing_pat ( ) } ;
2266+
2267+ match & pat {
2268+ ast:: Pat :: IdentPat ( bp) => {
2269+ // FIXME: Emit an error if `!bp.is_simple_ident()`.
2270+
2271+ let name = bp. name ( ) . map ( |nr| nr. as_name ( ) ) . unwrap_or_else ( Name :: missing) ;
2272+ let hygiene = bp
2273+ . name ( )
2274+ . map ( |name| self . hygiene_id_for ( name. syntax ( ) . text_range ( ) ) )
2275+ . unwrap_or ( HygieneId :: ROOT ) ;
2276+ let binding = self . alloc_binding ( name, BindingAnnotation :: Unannotated , hygiene) ;
2277+ let pat =
2278+ self . alloc_pat ( Pat :: Bind { id : binding, subpat : None } , AstPtr :: new ( & pat) ) ;
2279+ self . add_definition_to_binding ( binding, pat) ;
2280+ pat
2281+ }
2282+ // FIXME: Emit an error.
2283+ _ => self . missing_pat ( ) ,
2284+ }
2285+ }
2286+
22512287 // region: patterns
22522288
22532289 fn collect_pat_top ( & mut self , pat : Option < ast:: Pat > ) -> PatId {
0 commit comments