Skip to content

Commit 11c9c4d

Browse files
authored
Merge pull request #19466 from ChayimFriedman2/bug-coherence
fix: Fix a bug in orphan rules calculation
2 parents 5bbf2ce + 246d678 commit 11c9c4d

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

Diff for: crates/hir-ty/src/method_resolution.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -874,21 +874,26 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
874874
return true;
875875
}
876876

877-
let unwrap_fundamental = |ty: Ty| match ty.kind(Interner) {
878-
TyKind::Ref(_, _, referenced) => referenced.clone(),
879-
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => {
880-
let struct_data = db.struct_data(s);
881-
if struct_data.flags.contains(StructFlags::IS_FUNDAMENTAL) {
882-
let next = subs.type_parameters(Interner).next();
883-
match next {
884-
Some(ty) => ty,
885-
None => ty,
877+
let unwrap_fundamental = |mut ty: Ty| {
878+
// Unwrap all layers of fundamental types with a loop.
879+
loop {
880+
match ty.kind(Interner) {
881+
TyKind::Ref(_, _, referenced) => ty = referenced.clone(),
882+
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => {
883+
let struct_data = db.struct_data(s);
884+
if struct_data.flags.contains(StructFlags::IS_FUNDAMENTAL) {
885+
let next = subs.type_parameters(Interner).next();
886+
match next {
887+
Some(it) => ty = it,
888+
None => break ty,
889+
}
890+
} else {
891+
break ty;
892+
}
886893
}
887-
} else {
888-
ty
894+
_ => break ty,
889895
}
890896
}
891-
_ => ty,
892897
};
893898
// - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type.
894899
let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| {

Diff for: crates/ide-diagnostics/src/handlers/trait_impl_orphan.rs

+13
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,17 @@ impl<T> foo::Foo<dyn LocalTrait> for Bar {}
104104
"#,
105105
);
106106
}
107+
108+
#[test]
109+
fn twice_fundamental() {
110+
check_diagnostics(
111+
r#"
112+
//- /foo.rs crate:foo
113+
pub trait Trait {}
114+
//- /bar.rs crate:bar deps:foo
115+
struct Foo;
116+
impl foo::Trait for &&Foo {}
117+
"#,
118+
);
119+
}
107120
}

0 commit comments

Comments
 (0)