@@ -1295,9 +1295,9 @@ impl<'db> TypeInferenceBuilder<'db> {
1295
1295
}
1296
1296
1297
1297
fn infer_definition ( & mut self , node : impl Into < DefinitionNodeKey > ) {
1298
- for definition in self . index . definitions ( node) {
1299
- self . extend ( infer_definition_types ( self . db ( ) , * definition ) ) ;
1300
- }
1298
+ let definitions = self . index . definitions ( node) ;
1299
+ debug_assert_eq ! ( definitions . len ( ) , 1 ) ;
1300
+ self . extend ( infer_definition_types ( self . db ( ) , definitions [ 0 ] ) ) ;
1301
1301
}
1302
1302
1303
1303
fn infer_function_definition_statement ( & mut self , function : & ast:: StmtFunctionDef ) {
@@ -2985,7 +2985,16 @@ impl<'db> TypeInferenceBuilder<'db> {
2985
2985
} = import;
2986
2986
2987
2987
for alias in names {
2988
- self . infer_definition ( alias) ;
2988
+ let definitions = self . index . definitions ( alias) ;
2989
+ if definitions. is_empty ( ) {
2990
+ // Ensure `from foo import *` is flagged as invalid if `foo` can't be resolved,
2991
+ // *even if* `foo` is an empty module (and thus has no `Definition`s associated with it)
2992
+ self . resolve_import_from_module ( import, alias) ;
2993
+ } else {
2994
+ for definition in definitions {
2995
+ self . extend ( infer_definition_types ( self . db ( ) , * definition) ) ;
2996
+ }
2997
+ }
2989
2998
}
2990
2999
}
2991
3000
@@ -3037,12 +3046,13 @@ impl<'db> TypeInferenceBuilder<'db> {
3037
3046
}
3038
3047
}
3039
3048
3040
- fn infer_import_from_definition (
3049
+ /// Resolve the [`ModuleName`], and the type of the module, being referred to by an
3050
+ /// [`ast::StmtImportFrom`] node. Emit a diagnostic if the module cannot be resolved.
3051
+ fn resolve_import_from_module (
3041
3052
& mut self ,
3042
- import_from : & ' db ast:: StmtImportFrom ,
3053
+ import_from : & ast:: StmtImportFrom ,
3043
3054
alias : & ast:: Alias ,
3044
- definition : Definition < ' db > ,
3045
- ) {
3055
+ ) -> Option < ( ModuleName , Type < ' db > ) > {
3046
3056
let ast:: StmtImportFrom { module, level, .. } = import_from;
3047
3057
// For diagnostics, we want to highlight the unresolvable
3048
3058
// module and not the entire `from ... import ...` statement.
@@ -3065,17 +3075,15 @@ impl<'db> TypeInferenceBuilder<'db> {
3065
3075
Err ( ModuleNameResolutionError :: InvalidSyntax ) => {
3066
3076
tracing:: debug!( "Failed to resolve import due to invalid syntax" ) ;
3067
3077
// Invalid syntax diagnostics are emitted elsewhere.
3068
- self . add_unknown_declaration_with_binding ( alias. into ( ) , definition) ;
3069
- return ;
3078
+ return None ;
3070
3079
}
3071
3080
Err ( ModuleNameResolutionError :: TooManyDots ) => {
3072
3081
tracing:: debug!(
3073
3082
"Relative module resolution `{}` failed: too many leading dots" ,
3074
3083
format_import_from_module( * level, module) ,
3075
3084
) ;
3076
3085
report_unresolved_module ( & self . context , module_ref, * level, module) ;
3077
- self . add_unknown_declaration_with_binding ( alias. into ( ) , definition) ;
3078
- return ;
3086
+ return None ;
3079
3087
}
3080
3088
Err ( ModuleNameResolutionError :: UnknownCurrentModule ) => {
3081
3089
tracing:: debug!(
@@ -3084,13 +3092,26 @@ impl<'db> TypeInferenceBuilder<'db> {
3084
3092
self . file( ) . path( self . db( ) )
3085
3093
) ;
3086
3094
report_unresolved_module ( & self . context , module_ref, * level, module) ;
3087
- self . add_unknown_declaration_with_binding ( alias. into ( ) , definition) ;
3088
- return ;
3095
+ return None ;
3089
3096
}
3090
3097
} ;
3091
3098
3092
3099
let Some ( module_ty) = self . module_type_from_name ( & module_name) else {
3093
3100
report_unresolved_module ( & self . context , module_ref, * level, module) ;
3101
+ return None ;
3102
+ } ;
3103
+
3104
+ Some ( ( module_name, module_ty) )
3105
+ }
3106
+
3107
+ fn infer_import_from_definition (
3108
+ & mut self ,
3109
+ import_from : & ' db ast:: StmtImportFrom ,
3110
+ alias : & ast:: Alias ,
3111
+ definition : Definition < ' db > ,
3112
+ ) {
3113
+ let Some ( ( module_name, module_ty) ) = self . resolve_import_from_module ( import_from, alias)
3114
+ else {
3094
3115
self . add_unknown_declaration_with_binding ( alias. into ( ) , definition) ;
3095
3116
return ;
3096
3117
} ;
@@ -3102,23 +3123,12 @@ impl<'db> TypeInferenceBuilder<'db> {
3102
3123
None
3103
3124
} ;
3104
3125
3105
- let is_meaningful_star_import = star_import_info. is_some ( ) ;
3106
-
3107
3126
let name = if let Some ( ( star_import, symbol_table) ) = star_import_info. as_ref ( ) {
3108
3127
symbol_table. symbol ( star_import. symbol_id ( ) ) . name ( )
3109
3128
} else {
3110
3129
& alias. name . id
3111
3130
} ;
3112
3131
3113
- if & alias. name == "*" && !is_meaningful_star_import {
3114
- self . add_declaration_with_binding (
3115
- alias. into ( ) ,
3116
- definition,
3117
- & DeclaredAndInferredType :: AreTheSame ( Type :: Never ) ,
3118
- ) ;
3119
- return ;
3120
- }
3121
-
3122
3132
// First try loading the requested attribute from the module.
3123
3133
if let Symbol :: Type ( ty, boundness) = module_ty. member ( self . db ( ) , name) . symbol {
3124
3134
if & alias. name != "*" && boundness == Boundness :: PossiblyUnbound {
0 commit comments