Skip to content

Commit 97b80e3

Browse files
yangdanny97facebook-github-bot
authored andcommitted
generate TypeFormContext from AnnotationTarget
Summary: As suggested by Rebecca, this avoids some duplication in the annotation binding/solving logic. The more granular AnnotationTarget will also allow us to better model *args and *kwargs types, to help us fix facebook/pyrefly#16 (comment) Reviewed By: rchen152 Differential Revision: D71012503 fbshipit-source-id: 4015d42dcd520821f9de21421f4f8c3b0d68d10e
1 parent 97c8666 commit 97b80e3

File tree

7 files changed

+36
-37
lines changed

7 files changed

+36
-37
lines changed

pyre2/pyre2/lib/alt/solve.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
195195
errors: &ErrorCollector,
196196
) -> Arc<AnnotationWithTarget> {
197197
match binding {
198-
BindingAnnotation::AnnotateExpr(target, x, self_type, ctx) => {
199-
let mut ann = self.expr_annotation(x, *ctx, errors);
198+
BindingAnnotation::AnnotateExpr(target, x, self_type) => {
199+
let type_form_context = target.type_form_context();
200+
let mut ann = self.expr_annotation(x, type_form_context, errors);
200201
if let Some(self_type) = self_type
201202
&& let Some(ty) = &mut ann.ty
202203
{

pyre2/pyre2/lib/binding/binding.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,8 @@ impl Display for AnnotationWithTarget {
942942
pub enum AnnotationTarget {
943943
/// A function parameter with a type annotation
944944
Param(Name),
945+
ArgsParam(Name),
946+
KwargsParam(Name),
945947
/// A return type annotation on a function. The name is that of the function
946948
Return(Name),
947949
/// An annotated assignment. For attribute assignments, the name is the attribute name ("attr" in "x.attr")
@@ -954,32 +956,42 @@ impl Display for AnnotationTarget {
954956
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
955957
match self {
956958
Self::Param(name) => write!(f, "param {name}"),
959+
Self::ArgsParam(name) => write!(f, "args {name}"),
960+
Self::KwargsParam(name) => write!(f, "kwargs {name}"),
957961
Self::Return(name) => write!(f, "{name} return"),
958962
Self::Assign(name) => write!(f, "var {name}"),
959963
Self::ClassMember(name) => write!(f, "attr {name}"),
960964
}
961965
}
962966
}
963967

968+
impl AnnotationTarget {
969+
pub fn type_form_context(&self) -> TypeFormContext {
970+
match self {
971+
Self::Param(_) => TypeFormContext::ParameterAnnotation,
972+
Self::ArgsParam(_) => TypeFormContext::ParameterArgsAnnotation,
973+
Self::KwargsParam(_) => TypeFormContext::ParameterKwargsAnnotation,
974+
Self::Return(_) => TypeFormContext::ReturnAnnotation,
975+
Self::Assign(_) => TypeFormContext::VarAnnotation,
976+
Self::ClassMember(_) => TypeFormContext::ClassVarAnnotation,
977+
}
978+
}
979+
}
980+
964981
/// Values that return an annotation.
965982
#[derive(Clone, Debug)]
966983
pub enum BindingAnnotation {
967984
/// The type is annotated to be this key, will have the outer type removed.
968985
/// Optionally occuring within a class, in which case Self refers to this class.
969-
AnnotateExpr(
970-
AnnotationTarget,
971-
Expr,
972-
Option<Idx<KeyClass>>,
973-
TypeFormContext,
974-
),
986+
AnnotateExpr(AnnotationTarget, Expr, Option<Idx<KeyClass>>),
975987
/// A literal type we know statically.
976988
Type(AnnotationTarget, Type),
977989
}
978990

979991
impl DisplayWith<Bindings> for BindingAnnotation {
980992
fn fmt(&self, f: &mut fmt::Formatter<'_>, ctx: &Bindings) -> fmt::Result {
981993
match self {
982-
Self::AnnotateExpr(_, x, self_type, _) => write!(
994+
Self::AnnotateExpr(_, x, self_type) => write!(
983995
f,
984996
"_: {}{}",
985997
ctx.module_info().display(x),

pyre2/pyre2/lib/binding/bindings.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use starlark_map::small_map::SmallMap;
3333
use starlark_map::small_set::SmallSet;
3434
use vec1::Vec1;
3535

36-
use crate::alt::solve::TypeFormContext;
3736
use crate::binding::binding::AnnotationTarget;
3837
use crate::binding::binding::Binding;
3938
use crate::binding::binding::BindingAnnotation;
@@ -673,21 +672,16 @@ impl<'a> BindingsBuilder<'a> {
673672

674673
pub fn bind_function_param(
675674
&mut self,
675+
target: AnnotationTarget,
676676
x: AnyParameterRef,
677677
function_idx: Idx<KeyFunction>,
678678
self_type: Option<Idx<KeyClass>>,
679-
ctx: TypeFormContext,
680679
) {
681680
let name = x.name();
682681
let annot = x.annotation().map(|x| {
683682
self.table.insert(
684683
KeyAnnotation::Annotation(ShortIdentifier::new(name)),
685-
BindingAnnotation::AnnotateExpr(
686-
AnnotationTarget::Param(name.id.clone()),
687-
x.clone(),
688-
self_type,
689-
ctx,
690-
),
684+
BindingAnnotation::AnnotateExpr(target.clone(), x.clone(), self_type),
691685
)
692686
});
693687
let (annot, def) = match annot {
@@ -696,10 +690,7 @@ impl<'a> BindingsBuilder<'a> {
696690
let var = self.solver.fresh_contained(self.uniques);
697691
let annot = self.table.insert(
698692
KeyAnnotation::Annotation(ShortIdentifier::new(name)),
699-
BindingAnnotation::Type(
700-
AnnotationTarget::Param(name.id.clone()),
701-
var.to_type(),
702-
),
693+
BindingAnnotation::Type(target, var.to_type()),
703694
);
704695
(annot, Either::Right((var, function_idx)))
705696
}

pyre2/pyre2/lib/binding/class.rs

-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use ruff_text_size::TextRange;
2222
use starlark_map::small_map::SmallMap;
2323

2424
use crate::alt::class::class_metadata::BaseClass;
25-
use crate::alt::solve::TypeFormContext;
2625
use crate::binding::binding::AnnotationTarget;
2726
use crate::binding::binding::Binding;
2827
use crate::binding::binding::BindingAnnotation;
@@ -360,7 +359,6 @@ impl<'a> BindingsBuilder<'a> {
360359
AnnotationTarget::ClassMember(member_name.clone()),
361360
annotation,
362361
None,
363-
TypeFormContext::ClassVarAnnotation,
364362
)
365363
};
366364
Some(self.table.insert(ann_key, ann_val))

pyre2/pyre2/lib/binding/function.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use ruff_python_ast::StmtExpr;
1717
use ruff_python_ast::StmtFunctionDef;
1818
use ruff_text_size::Ranged;
1919

20-
use crate::alt::solve::TypeFormContext;
2120
use crate::ast::Ast;
2221
use crate::binding::binding::AnnotationTarget;
2322
use crate::binding::binding::Binding;
@@ -61,26 +60,26 @@ impl<'a> BindingsBuilder<'a> {
6160
self_name = Some(x.parameter.name.clone());
6261
}
6362
self.bind_function_param(
63+
AnnotationTarget::Param(x.parameter.name.id.clone()),
6464
AnyParameterRef::NonVariadic(x),
6565
function_idx,
6666
self_type,
67-
TypeFormContext::ParameterAnnotation,
6867
);
6968
}
7069
if let Some(box args) = &x.vararg {
7170
self.bind_function_param(
71+
AnnotationTarget::ArgsParam(args.name.id.clone()),
7272
AnyParameterRef::Variadic(args),
7373
function_idx,
7474
self_type,
75-
TypeFormContext::ParameterArgsAnnotation,
7675
);
7776
}
7877
if let Some(box kwargs) = &x.kwarg {
7978
self.bind_function_param(
79+
AnnotationTarget::KwargsParam(kwargs.name.id.clone()),
8080
AnyParameterRef::Variadic(kwargs),
8181
function_idx,
8282
self_type,
83-
TypeFormContext::ParameterKwargsAnnotation,
8483
);
8584
}
8685
if let Scope {
@@ -155,7 +154,6 @@ impl<'a> BindingsBuilder<'a> {
155154
AnnotationTarget::Return(func_name.id.clone()),
156155
*x,
157156
self_type,
158-
TypeFormContext::ReturnAnnotation,
159157
),
160158
),
161159
)

pyre2/pyre2/lib/binding/stmt.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use ruff_python_ast::StmtImportFrom;
1818
use ruff_text_size::Ranged;
1919
use ruff_text_size::TextRange;
2020

21-
use crate::alt::solve::TypeFormContext;
2221
use crate::ast::Ast;
2322
use crate::binding::binding::AnnotationStyle;
2423
use crate::binding::binding::AnnotationTarget;
@@ -345,14 +344,13 @@ impl<'a> BindingsBuilder<'a> {
345344
)
346345
} else {
347346
BindingAnnotation::AnnotateExpr(
348-
AnnotationTarget::Assign(name.id.clone()),
349-
*x.annotation.clone(),
350-
None,
351347
if in_class_body {
352-
TypeFormContext::ClassVarAnnotation
348+
AnnotationTarget::ClassMember(name.id.clone())
353349
} else {
354-
TypeFormContext::VarAnnotation
350+
AnnotationTarget::Assign(name.id.clone())
355351
},
352+
*x.annotation.clone(),
353+
None,
356354
)
357355
};
358356
let ann_key = self.table.insert(ann_key, ann_val);
@@ -410,10 +408,9 @@ impl<'a> BindingsBuilder<'a> {
410408
let ann_key = self.table.insert(
411409
KeyAnnotation::AttrAnnotation(x.annotation.range()),
412410
BindingAnnotation::AnnotateExpr(
413-
AnnotationTarget::Assign(attr.attr.id.clone()),
411+
AnnotationTarget::ClassMember(attr.attr.id.clone()),
414412
*x.annotation,
415413
None,
416-
TypeFormContext::ClassVarAnnotation,
417414
),
418415
);
419416
let value_binding = match &x.value {

pyre2/pyre2/lib/error/context.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ pub enum TypeCheckKind {
112112
impl TypeCheckKind {
113113
pub fn from_annotation_target(target: &AnnotationTarget) -> Self {
114114
match target {
115-
AnnotationTarget::Param(_) => Self::Unknown,
115+
AnnotationTarget::Param(_)
116+
| AnnotationTarget::ArgsParam(_)
117+
| AnnotationTarget::KwargsParam(_) => Self::Unknown,
116118
AnnotationTarget::Return(_func) => Self::ExplicitFunctionReturn,
117119
AnnotationTarget::Assign(name) => Self::AnnotatedName(name.clone()),
118120
AnnotationTarget::ClassMember(member) => Self::Attribute(member.clone()),

0 commit comments

Comments
 (0)