mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-31 20:09:01 +00:00 
			
		
		
		
	Merge pull request #19466 from ChayimFriedman2/bug-coherence
fix: Fix a bug in orphan rules calculation
This commit is contained in:
		
						commit
						11c9c4d207
					
				
					 2 changed files with 30 additions and 12 deletions
				
			
		|  | @ -874,21 +874,26 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     let unwrap_fundamental = |ty: Ty| match ty.kind(Interner) { | ||||
|         TyKind::Ref(_, _, referenced) => referenced.clone(), | ||||
|         &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => { | ||||
|             let struct_data = db.struct_data(s); | ||||
|             if struct_data.flags.contains(StructFlags::IS_FUNDAMENTAL) { | ||||
|                 let next = subs.type_parameters(Interner).next(); | ||||
|                 match next { | ||||
|                     Some(ty) => ty, | ||||
|                     None => ty, | ||||
|     let unwrap_fundamental = |mut ty: Ty| { | ||||
|         // Unwrap all layers of fundamental types with a loop.
 | ||||
|         loop { | ||||
|             match ty.kind(Interner) { | ||||
|                 TyKind::Ref(_, _, referenced) => ty = referenced.clone(), | ||||
|                 &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => { | ||||
|                     let struct_data = db.struct_data(s); | ||||
|                     if struct_data.flags.contains(StructFlags::IS_FUNDAMENTAL) { | ||||
|                         let next = subs.type_parameters(Interner).next(); | ||||
|                         match next { | ||||
|                             Some(it) => ty = it, | ||||
|                             None => break ty, | ||||
|                         } | ||||
|                     } else { | ||||
|                         break ty; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 ty | ||||
|                 _ => break ty, | ||||
|             } | ||||
|         } | ||||
|         _ => ty, | ||||
|     }; | ||||
|     //   - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type.
 | ||||
|     let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| { | ||||
|  |  | |||
|  | @ -104,4 +104,17 @@ impl<T> foo::Foo<dyn LocalTrait> for Bar {} | |||
| "#,
 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn twice_fundamental() { | ||||
|         check_diagnostics( | ||||
|             r#" | ||||
| //- /foo.rs crate:foo
 | ||||
| pub trait Trait {} | ||||
| //- /bar.rs crate:bar deps:foo
 | ||||
| struct Foo; | ||||
| impl foo::Trait for &&Foo {} | ||||
|         "#,
 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 David Barsky
						David Barsky