Skip to content

Commit

Permalink
address review
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood committed Dec 15, 2024
1 parent 4297cf9 commit 774ee81
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def _(flag: bool):
def f(y: X):
reveal_type(y) # revealed: Unknown | bool

# error: [invalid-type-form] "`Annotated` requires at least two arguments when used in an annotation or type expression"
def _(x: Annotated | bool):
reveal_type(x) # revealed: Unknown | bool

# error: [invalid-type-form]
def _(x: Annotated[()]):
reveal_type(x) # revealed: Unknown
Expand Down
31 changes: 26 additions & 5 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::stdlib::{
use crate::symbol::{Boundness, Symbol};
use crate::types::call::{CallDunderResult, CallOutcome};
use crate::types::class_base::ClassBase;
use crate::types::diagnostic::TypeCheckDiagnosticsBuilder;
use crate::types::diagnostic::{TypeCheckDiagnosticsBuilder, INVALID_TYPE_FORM};
use crate::types::mro::{Mro, MroError, MroIterator};
use crate::types::narrow::narrowing_constraint;
use crate::{Db, FxOrderSet, Module, Program, PythonVersion};
Expand Down Expand Up @@ -1889,7 +1889,7 @@ impl<'db> Type<'db> {
Type::KnownInstance(KnownInstanceType::Tuple) => Ok(KnownClass::Tuple.to_instance(db)),
Type::Union(union) => {
let mut builder = UnionBuilder::new(db);
let mut invalid_expressions = vec![];
let mut invalid_expressions = smallvec::SmallVec::default();
for element in union.elements(db) {
match element.in_type_expression(db) {
Ok(type_expr) => builder = builder.add(type_expr),
Expand Down Expand Up @@ -1922,11 +1922,11 @@ impl<'db> Type<'db> {
Type::KnownInstance(KnownInstanceType::Any) => Ok(Type::Any),
// TODO: Should emit a diagnostic
Type::KnownInstance(KnownInstanceType::Annotated) => Err(InvalidTypeExpressionError {
invalid_expressions: vec![InvalidTypeExpression::BareAnnotated],
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::BareAnnotated],
fallback_type: Type::Unknown,
}),
Type::KnownInstance(KnownInstanceType::Literal) => Err(InvalidTypeExpressionError {
invalid_expressions: vec![InvalidTypeExpression::BareLiteral],
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::BareLiteral],
fallback_type: Type::Unknown,
}),
Type::Todo(_) => Ok(*self),
Expand Down Expand Up @@ -2067,7 +2067,28 @@ impl<'db> From<Type<'db>> for Symbol<'db> {
#[derive(Debug, PartialEq, Eq)]
pub struct InvalidTypeExpressionError<'db> {
fallback_type: Type<'db>,
invalid_expressions: Vec<InvalidTypeExpression>,
invalid_expressions: smallvec::SmallVec<[InvalidTypeExpression; 1]>,
}

impl<'db> InvalidTypeExpressionError<'db> {
fn into_fallback_type(
self,
diagnostics: &mut TypeCheckDiagnosticsBuilder,
node: &ast::Expr,
) -> Type<'db> {
let InvalidTypeExpressionError {
fallback_type,
invalid_expressions,
} = self;
for error in invalid_expressions {
diagnostics.add_lint(
&INVALID_TYPE_FORM,
node.into(),
format_args!("{}", error.reason()),
);
}
fallback_type
}
}

/// Enumeration of various types that are invalid in type-expression contexts
Expand Down
35 changes: 10 additions & 25 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ use crate::types::unpacker::{UnpackResult, Unpacker};
use crate::types::{
bindings_ty, builtins_symbol, declarations_ty, global_symbol, symbol, todo_type,
typing_extensions_symbol, Boundness, Class, ClassLiteralType, FunctionType, InstanceType,
IntersectionBuilder, IntersectionType, InvalidTypeExpressionError, IterationOutcome,
KnownClass, KnownFunction, KnownInstanceType, MetaclassCandidate, MetaclassErrorKind,
SliceLiteralType, Symbol, Truthiness, TupleType, Type, TypeAliasType, TypeArrayDisplay,
TypeVarBoundOrConstraints, TypeVarInstance, UnionBuilder, UnionType,
IntersectionBuilder, IntersectionType, IterationOutcome, KnownClass, KnownFunction,
KnownInstanceType, MetaclassCandidate, MetaclassErrorKind, SliceLiteralType, Symbol,
Truthiness, TupleType, Type, TypeAliasType, TypeArrayDisplay, TypeVarBoundOrConstraints,
TypeVarInstance, UnionBuilder, UnionType,
};
use crate::unpack::Unpack;
use crate::util::subscript::{PyIndex, PySlice};
Expand Down Expand Up @@ -4468,7 +4468,9 @@ impl<'db> TypeInferenceBuilder<'db> {
ast::ExprContext::Load => self
.infer_name_expression(name)
.in_type_expression(self.db)
.unwrap_or_else(|error| self.infer_invalid_type_expression(expression, error)),
.unwrap_or_else(|error| {
error.into_fallback_type(&mut self.diagnostics, expression)
}),
ast::ExprContext::Invalid => Type::Unknown,
ast::ExprContext::Store | ast::ExprContext::Del => todo_type!(),
},
Expand All @@ -4477,7 +4479,9 @@ impl<'db> TypeInferenceBuilder<'db> {
ast::ExprContext::Load => self
.infer_attribute_expression(attribute_expression)
.in_type_expression(self.db)
.unwrap_or_else(|error| self.infer_invalid_type_expression(expression, error)),
.unwrap_or_else(|error| {
error.into_fallback_type(&mut self.diagnostics, expression)
}),
ast::ExprContext::Invalid => Type::Unknown,
ast::ExprContext::Store | ast::ExprContext::Del => todo_type!(),
},
Expand Down Expand Up @@ -4633,25 +4637,6 @@ impl<'db> TypeInferenceBuilder<'db> {
}
}

fn infer_invalid_type_expression(
&mut self,
expression: &ast::Expr,
error: InvalidTypeExpressionError<'db>,
) -> Type<'db> {
let InvalidTypeExpressionError {
fallback_type,
invalid_expressions,
} = error;
for error in invalid_expressions {
self.diagnostics.add_lint(
&INVALID_TYPE_FORM,
expression.into(),
format_args!("{}", error.reason()),
);
}
fallback_type
}

/// Infer the type of a string type expression.
fn infer_string_type_expression(&mut self, string: &ast::ExprStringLiteral) -> Type<'db> {
match parse_string_annotation(self.db, self.file, string) {
Expand Down

0 comments on commit 774ee81

Please sign in to comment.