[ty] Ban protocols from inheriting from non-protocol generic classes (#19941)

This commit is contained in:
Alex Waygood 2025-08-16 19:38:43 +01:00 committed by GitHub
parent f4d8826428
commit 9ac39cee98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 10 deletions

View file

@ -1117,13 +1117,6 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
// - Check for inheritance from a `@final` classes
// - If the class is a protocol class: check for inheritance from a non-protocol class
for (i, base_class) in class.explicit_bases(self.db()).iter().enumerate() {
if let Some((class, solid_base)) = base_class
.to_class_type(self.db())
.and_then(|class| Some((class, class.nearest_solid_base(self.db())?)))
{
solid_bases.insert(solid_base, i, class.class_literal(self.db()).0);
}
let base_class = match base_class {
Type::SpecialForm(SpecialFormType::Generic) => {
if let Some(builder) = self
@ -1155,13 +1148,17 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
);
continue;
}
Type::ClassLiteral(class) => class,
// dynamic/unknown bases are never `@final`
Type::ClassLiteral(class) => ClassType::NonGeneric(*class),
Type::GenericAlias(class) => ClassType::Generic(*class),
_ => continue,
};
if let Some(solid_base) = base_class.nearest_solid_base(self.db()) {
solid_bases.insert(solid_base, i, base_class.class_literal(self.db()).0);
}
if is_protocol
&& !(base_class.is_protocol(self.db())
&& !(base_class.class_literal(self.db()).0.is_protocol(self.db())
|| base_class.is_known(self.db(), KnownClass::Object))
{
if let Some(builder) = self