Skip to content

Commit 5423492

Browse files
stepanchegfacebook-github-bot
authored andcommitted
TyUserFields
Summary: `TyUserFields` has a `unknown` flag, which is used when all fields are not known, that is when the type is "abstract", like `Provider` which is implemented in the following diff D48893103. Reviewed By: ianlevesque Differential Revision: D48893102 fbshipit-source-id: c660e1a7f1a6166163d4c2fb69a0985509fec41f
1 parent 697ced3 commit 5423492

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

starlark/src/typing/user.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use std::hash::Hasher;
2121

2222
use allocative::Allocative;
2323
use dupe::Dupe;
24-
use dupe::OptionDupedExt;
2524
use starlark_map::sorted_map::SortedMap;
2625
use starlark_syntax::codemap::Span;
2726
use starlark_syntax::codemap::Spanned;
@@ -64,6 +63,25 @@ pub(crate) struct TyUserIndex {
6463
pub(crate) result: Ty,
6564
}
6665

66+
/// Fields of the struct.
67+
#[derive(Allocative, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
68+
pub(crate) struct TyUserFields {
69+
/// Known fields.
70+
pub(crate) known: SortedMap<String, Ty>,
71+
/// Are there unknown fields?
72+
/// Unknown fields are possible if this type represents an abstract type like a provider.
73+
pub(crate) unknown: bool,
74+
}
75+
76+
impl TyUserFields {
77+
pub(crate) fn no_fields() -> TyUserFields {
78+
TyUserFields {
79+
known: SortedMap::new(),
80+
unknown: false,
81+
}
82+
}
83+
}
84+
6785
/// Type description for arbitrary type.
6886
#[derive(Allocative, Debug, derive_more::Display)]
6987
#[display(fmt = "{}", name)]
@@ -73,7 +91,7 @@ pub(crate) struct TyUser {
7391
base: TyStarlarkValue,
7492
matcher: Option<TypeMatcherFactory>,
7593
id: TypeInstanceId,
76-
fields: SortedMap<String, Ty>,
94+
fields: TyUserFields,
7795
/// Set if more precise callable signature is known than `base` provides.
7896
callable: Option<TyFunction>,
7997
/// Set if more precise index signature is known than `base` provides.
@@ -88,7 +106,7 @@ impl TyUser {
88106
base: TyStarlarkValue,
89107
matcher: Option<TypeMatcherFactory>,
90108
id: TypeInstanceId,
91-
fields: SortedMap<String, Ty>,
109+
fields: TyUserFields,
92110
callable: Option<TyFunction>,
93111
index: Option<TyUserIndex>,
94112
iter_item: Option<Ty>,
@@ -157,7 +175,16 @@ impl TyCustomImpl for TyUser {
157175
if let Ok(ty) = self.base.attr_from_methods(attr) {
158176
Ok(ty)
159177
} else {
160-
self.fields.get(attr).duped().ok_or(())
178+
match self.fields.known.get(attr) {
179+
Some(ty) => Ok(ty.dupe()),
180+
None => {
181+
if self.fields.unknown {
182+
Ok(Ty::any())
183+
} else {
184+
Err(())
185+
}
186+
}
187+
}
161188
}
162189
}
163190

starlark/src/values/types/enumeration/enum_type.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use starlark_derive::NoSerialize;
3333
use starlark_derive::StarlarkDocs;
3434
use starlark_derive::Trace;
3535
use starlark_map::small_map::SmallMap;
36-
use starlark_map::sorted_map::SortedMap;
3736
use starlark_map::Equivalent;
3837

3938
use crate as starlark;
@@ -45,6 +44,7 @@ use crate::eval::Arguments;
4544
use crate::eval::Evaluator;
4645
use crate::typing::starlark_value::TyStarlarkValue;
4746
use crate::typing::user::TyUser;
47+
use crate::typing::user::TyUserFields;
4848
use crate::typing::user::TyUserIndex;
4949
use crate::typing::Ty;
5050
use crate::values::enumeration::matcher::EnumTypeMatcher;
@@ -303,7 +303,7 @@ where
303303
TyStarlarkValue::new::<EnumValue>(),
304304
Some(TypeMatcherFactory::new(EnumTypeMatcher { id: self.id })),
305305
self.id,
306-
SortedMap::new(),
306+
TyUserFields::no_fields(),
307307
None,
308308
None,
309309
None,
@@ -313,7 +313,7 @@ where
313313
TyStarlarkValue::new::<EnumType>(),
314314
None,
315315
TypeInstanceId::gen(),
316-
SortedMap::new(),
316+
TyUserFields::no_fields(),
317317
None,
318318
Some(TyUserIndex {
319319
index: Ty::int(),

starlark/src/values/types/record/record_type.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use crate::eval::ParametersSpec;
4646
use crate::starlark_complex_values;
4747
use crate::typing::starlark_value::TyStarlarkValue;
4848
use crate::typing::user::TyUser;
49+
use crate::typing::user::TyUserFields;
4950
use crate::typing::Param;
5051
use crate::typing::Ty;
5152
use crate::typing::TyFunction;
@@ -302,7 +303,10 @@ where
302303
TyStarlarkValue::new::<Record>(),
303304
Some(TypeMatcherFactory::new(RecordTypeMatcher { id: self.id })),
304305
self.id,
305-
fields,
306+
TyUserFields {
307+
known: fields,
308+
unknown: false,
309+
},
306310
None,
307311
None,
308312
None,
@@ -313,7 +317,7 @@ where
313317
TyStarlarkValue::new::<RecordType>(),
314318
None,
315319
TypeInstanceId::gen(),
316-
SortedMap::new(),
320+
TyUserFields::no_fields(),
317321
Some(TyFunction::new(
318322
// TODO(nga): more precise parameter types.
319323
vec![Param::kwargs(Ty::any())],

0 commit comments

Comments
 (0)