[ty] Improve the display of various special-form types (#21775)
This commit is contained in:
@@ -7331,7 +7331,7 @@ impl<'db> Type<'db> {
|
||||
| SpecialFormType::Union
|
||||
| SpecialFormType::Intersection => Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec_inline![
|
||||
InvalidTypeExpression::RequiresArguments(*self)
|
||||
InvalidTypeExpression::RequiresArguments(*special_form)
|
||||
],
|
||||
fallback_type: Type::unknown(),
|
||||
}),
|
||||
@@ -7357,7 +7357,7 @@ impl<'db> Type<'db> {
|
||||
| SpecialFormType::Unpack
|
||||
| SpecialFormType::CallableTypeOf => Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec_inline![
|
||||
InvalidTypeExpression::RequiresOneArgument(*self)
|
||||
InvalidTypeExpression::RequiresOneArgument(*special_form)
|
||||
],
|
||||
fallback_type: Type::unknown(),
|
||||
}),
|
||||
@@ -7365,7 +7365,7 @@ impl<'db> Type<'db> {
|
||||
SpecialFormType::Annotated | SpecialFormType::Concatenate => {
|
||||
Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec_inline![
|
||||
InvalidTypeExpression::RequiresTwoArguments(*self)
|
||||
InvalidTypeExpression::RequiresTwoArguments(*special_form)
|
||||
],
|
||||
fallback_type: Type::unknown(),
|
||||
})
|
||||
@@ -9087,11 +9087,11 @@ impl<'db> InvalidTypeExpressionError<'db> {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
enum InvalidTypeExpression<'db> {
|
||||
/// Some types always require exactly one argument when used in a type expression
|
||||
RequiresOneArgument(Type<'db>),
|
||||
RequiresOneArgument(SpecialFormType),
|
||||
/// Some types always require at least one argument when used in a type expression
|
||||
RequiresArguments(Type<'db>),
|
||||
RequiresArguments(SpecialFormType),
|
||||
/// Some types always require at least two arguments when used in a type expression
|
||||
RequiresTwoArguments(Type<'db>),
|
||||
RequiresTwoArguments(SpecialFormType),
|
||||
/// The `Protocol` class is invalid in type expressions
|
||||
Protocol,
|
||||
/// Same for `Generic`
|
||||
@@ -9131,20 +9131,17 @@ impl<'db> InvalidTypeExpression<'db> {
|
||||
impl std::fmt::Display for Display<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self.error {
|
||||
InvalidTypeExpression::RequiresOneArgument(ty) => write!(
|
||||
InvalidTypeExpression::RequiresOneArgument(special_form) => write!(
|
||||
f,
|
||||
"`{ty}` requires exactly one argument when used in a type expression",
|
||||
ty = ty.display(self.db)
|
||||
"`{special_form}` requires exactly one argument when used in a type expression",
|
||||
),
|
||||
InvalidTypeExpression::RequiresArguments(ty) => write!(
|
||||
InvalidTypeExpression::RequiresArguments(special_form) => write!(
|
||||
f,
|
||||
"`{ty}` requires at least one argument when used in a type expression",
|
||||
ty = ty.display(self.db)
|
||||
"`{special_form}` requires at least one argument when used in a type expression",
|
||||
),
|
||||
InvalidTypeExpression::RequiresTwoArguments(ty) => write!(
|
||||
InvalidTypeExpression::RequiresTwoArguments(special_form) => write!(
|
||||
f,
|
||||
"`{ty}` requires at least two arguments when used in a type expression",
|
||||
ty = ty.display(self.db)
|
||||
"`{special_form}` requires at least two arguments when used in a type expression",
|
||||
),
|
||||
InvalidTypeExpression::Protocol => {
|
||||
f.write_str("`typing.Protocol` is not allowed in type expressions")
|
||||
|
||||
@@ -2998,11 +2998,10 @@ pub(crate) fn report_invalid_arguments_to_annotated(
|
||||
let Some(builder) = context.report_lint(&INVALID_TYPE_FORM, subscript) else {
|
||||
return;
|
||||
};
|
||||
builder.into_diagnostic(format_args!(
|
||||
"Special form `{}` expected at least 2 arguments \
|
||||
builder.into_diagnostic(
|
||||
"Special form `typing.Annotated` expected at least 2 arguments \
|
||||
(one type and at least one metadata element)",
|
||||
SpecialFormType::Annotated
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn report_invalid_argument_number_to_special_form(
|
||||
@@ -3103,8 +3102,7 @@ pub(crate) fn report_invalid_arguments_to_callable(
|
||||
return;
|
||||
};
|
||||
builder.into_diagnostic(format_args!(
|
||||
"Special form `{}` expected exactly two arguments (parameter types and return type)",
|
||||
SpecialFormType::Callable
|
||||
"Special form `typing.Callable` expected exactly two arguments (parameter types and return type)",
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -696,7 +696,8 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||
),
|
||||
},
|
||||
Type::SpecialForm(special_form) => {
|
||||
write!(f.with_type(self.ty), "{special_form}")
|
||||
f.set_invalid_syntax();
|
||||
write!(f.with_type(self.ty), "<special form '{special_form}'>")
|
||||
}
|
||||
Type::KnownInstance(known_instance) => known_instance
|
||||
.display_with(self.db, self.settings.clone())
|
||||
@@ -2173,16 +2174,24 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
|
||||
let ty = Type::KnownInstance(self.known_instance);
|
||||
match self.known_instance {
|
||||
KnownInstanceType::SubscriptedProtocol(generic_context) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<special form '")?;
|
||||
f.with_type(ty).write_str("typing.Protocol")?;
|
||||
f.write_str(&generic_context.display(self.db).to_string())
|
||||
f.write_str(&generic_context.display(self.db).to_string())?;
|
||||
f.write_str("'>")
|
||||
}
|
||||
KnownInstanceType::SubscriptedGeneric(generic_context) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<special form '")?;
|
||||
f.with_type(ty).write_str("typing.Generic")?;
|
||||
f.write_str(&generic_context.display(self.db).to_string())
|
||||
f.write_str(&generic_context.display(self.db).to_string())?;
|
||||
f.write_str("'>")
|
||||
}
|
||||
KnownInstanceType::TypeAliasType(alias) => {
|
||||
if let Some(specialization) = alias.specialization(self.db) {
|
||||
f.write_str(alias.name(self.db))?;
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<type alias '")?;
|
||||
f.with_type(ty).write_str(alias.name(self.db))?;
|
||||
f.write_str(
|
||||
&specialization
|
||||
.display_short(
|
||||
@@ -2191,7 +2200,8 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
|
||||
DisplaySettings::default(),
|
||||
)
|
||||
.to_string(),
|
||||
)
|
||||
)?;
|
||||
f.write_str("'>")
|
||||
} else {
|
||||
f.with_type(ty).write_str("typing.TypeAliasType")
|
||||
}
|
||||
@@ -2201,9 +2211,9 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
|
||||
// have a `Type::TypeVar(_)`, which is rendered as the typevar's name.
|
||||
KnownInstanceType::TypeVar(typevar_instance) => {
|
||||
if typevar_instance.kind(self.db).is_paramspec() {
|
||||
f.write_str("typing.ParamSpec")
|
||||
f.with_type(ty).write_str("typing.ParamSpec")
|
||||
} else {
|
||||
f.write_str("typing.TypeVar")
|
||||
f.with_type(ty).write_str("typing.TypeVar")
|
||||
}
|
||||
}
|
||||
KnownInstanceType::Deprecated(_) => f.write_str("warnings.deprecated"),
|
||||
@@ -2226,22 +2236,56 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
|
||||
f.with_type(ty).write_str("ty_extensions.Specialization")?;
|
||||
write!(f, "{}", specialization.display_full(self.db))
|
||||
}
|
||||
KnownInstanceType::UnionType(_) => f.with_type(ty).write_str("types.UnionType"),
|
||||
KnownInstanceType::Literal(_) => {
|
||||
KnownInstanceType::UnionType(union) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<typing.Literal special form>")
|
||||
f.write_char('<')?;
|
||||
f.with_type(ty).write_str("types.UnionType")?;
|
||||
f.write_str(" special form")?;
|
||||
if let Ok(ty) = union.union_type(self.db) {
|
||||
write!(f, " '{}'", ty.display(self.db))?;
|
||||
}
|
||||
f.write_char('>')
|
||||
}
|
||||
KnownInstanceType::Annotated(_) => {
|
||||
KnownInstanceType::Literal(inner) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<typing.Annotated special form>")
|
||||
write!(
|
||||
f,
|
||||
"<special form '{}'>",
|
||||
inner.inner(self.db).display(self.db)
|
||||
)
|
||||
}
|
||||
KnownInstanceType::TypeGenericAlias(_) | KnownInstanceType::Callable(_) => {
|
||||
f.with_type(ty).write_str("GenericAlias")
|
||||
KnownInstanceType::Annotated(inner) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<special form '")?;
|
||||
f.with_type(ty).write_str("typing.Annotated")?;
|
||||
write!(
|
||||
f,
|
||||
"[{}, <metadata>]'>",
|
||||
inner.inner(self.db).display(self.db)
|
||||
)
|
||||
}
|
||||
KnownInstanceType::Callable(callable) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_char('<')?;
|
||||
f.with_type(ty).write_str("typing.Callable")?;
|
||||
write!(f, " special form '{}'>", callable.display(self.db))
|
||||
}
|
||||
KnownInstanceType::TypeGenericAlias(inner) => {
|
||||
f.set_invalid_syntax();
|
||||
f.write_str("<special form '")?;
|
||||
write!(
|
||||
f.with_type(ty),
|
||||
"type[{}]",
|
||||
inner.inner(self.db).display(self.db)
|
||||
)?;
|
||||
f.write_str("'>")
|
||||
}
|
||||
KnownInstanceType::LiteralStringAlias(_) => f.write_str("str"),
|
||||
KnownInstanceType::NewType(declaration) => {
|
||||
f.set_invalid_syntax();
|
||||
write!(f, "<NewType pseudo-class '{}'>", declaration.name(self.db))
|
||||
f.write_str("<NewType pseudo-class '")?;
|
||||
f.with_type(ty).write_str(declaration.name(self.db))?;
|
||||
f.write_str("'>")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user