mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Skip checks for cast to dyn traits
This commit is contained in:
parent
e35227d186
commit
569ac44daf
3 changed files with 139 additions and 0 deletions
|
@ -120,6 +120,13 @@ impl CastCheck {
|
|||
});
|
||||
}
|
||||
|
||||
// Chalk doesn't support trait upcasting and fails to solve some obvious goals
|
||||
// when the trait environment contains some recursive traits (See issue #18047)
|
||||
// We skip cast checks for such cases for now, until the next-gen solver.
|
||||
if contains_dyn_trait(&self.cast_ty) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Ok((adj, _)) = table.coerce(&self.expr_ty, &self.cast_ty) {
|
||||
apply_adjustments(self.source_expr, adj);
|
||||
set_coercion_cast(self.source_expr);
|
||||
|
@ -410,3 +417,35 @@ fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<Pointe
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_dyn_trait(ty: &Ty) -> bool {
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use chalk_ir::{
|
||||
visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
|
||||
DebruijnIndex,
|
||||
};
|
||||
|
||||
struct DynTraitVisitor;
|
||||
|
||||
impl TypeVisitor<Interner> for DynTraitVisitor {
|
||||
type BreakTy = ();
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
|
||||
self
|
||||
}
|
||||
|
||||
fn interner(&self) -> Interner {
|
||||
Interner
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Dyn(_) => ControlFlow::Break(()),
|
||||
_ => ty.super_visit_with(self.as_dyn(), outer_binder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty.visit_with(DynTraitVisitor.as_dyn(), DebruijnIndex::INNERMOST).is_break()
|
||||
}
|
||||
|
|
|
@ -902,6 +902,10 @@ impl<'a> InferenceTable<'a> {
|
|||
|
||||
/// Check if given type is `Sized` or not
|
||||
pub(crate) fn is_sized(&mut self, ty: &Ty) -> bool {
|
||||
// Early return for some obvious types
|
||||
if matches!(ty.kind(Interner), TyKind::Scalar(..) | TyKind::Ref(..) | TyKind::Raw(..)) {
|
||||
return true;
|
||||
}
|
||||
if let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
|
||||
let struct_data = self.db.struct_data(id);
|
||||
if let Some((last_field, _)) = struct_data.variant_data.fields().iter().last() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue