mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	Merge pull request #18843 from Veykril/push-usuzxtzsnrpt
fix: Handle newstyle `rustc_intrinsic` safety correctly
This commit is contained in:
		
						commit
						5769685199
					
				
					 2 changed files with 24 additions and 9 deletions
				
			
		| 
						 | 
					@ -270,17 +270,15 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let is_intrinsic = db.attrs(func.into()).by_key(&sym::rustc_intrinsic).exists()
 | 
					 | 
				
			||||||
        || data.abi.as_ref() == Some(&sym::rust_dash_intrinsic);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let loc = func.lookup(db.upcast());
 | 
					    let loc = func.lookup(db.upcast());
 | 
				
			||||||
    match loc.container {
 | 
					    match loc.container {
 | 
				
			||||||
        hir_def::ItemContainerId::ExternBlockId(block) => {
 | 
					        hir_def::ItemContainerId::ExternBlockId(block) => {
 | 
				
			||||||
            if is_intrinsic || {
 | 
					 | 
				
			||||||
            let id = block.lookup(db.upcast()).id;
 | 
					            let id = block.lookup(db.upcast()).id;
 | 
				
			||||||
                id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic)
 | 
					            let is_intrinsic_block =
 | 
				
			||||||
            } {
 | 
					                id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
 | 
				
			||||||
                // Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
 | 
					            if is_intrinsic_block {
 | 
				
			||||||
 | 
					                // legacy intrinsics
 | 
				
			||||||
 | 
					                // extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
 | 
				
			||||||
                !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
 | 
					                !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // Function in an `extern` block are always unsafe to call, except when
 | 
					                // Function in an `extern` block are always unsafe to call, except when
 | 
				
			||||||
| 
						 | 
					@ -288,7 +286,6 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
 | 
				
			||||||
                !data.is_safe()
 | 
					                !data.is_safe()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        _ if is_intrinsic => !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists(),
 | 
					 | 
				
			||||||
        _ => false,
 | 
					        _ => false,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,6 +237,24 @@ fn main() {
 | 
				
			||||||
    fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
 | 
					    fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
 | 
				
			||||||
        check_diagnostics(
 | 
					        check_diagnostics(
 | 
				
			||||||
            r#"
 | 
					            r#"
 | 
				
			||||||
 | 
					#[rustc_intrinsic]
 | 
				
			||||||
 | 
					pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
 | 
				
			||||||
 | 
					#[rustc_intrinsic]
 | 
				
			||||||
 | 
					pub unsafe fn floorf32(x: f32) -> f32; // Unsafe intrinsic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let _ = bitreverse(12);
 | 
				
			||||||
 | 
					    let _ = floorf32(12.0);
 | 
				
			||||||
 | 
					          //^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					"#,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn no_missing_unsafe_diagnostic_with_legacy_safe_intrinsic() {
 | 
				
			||||||
 | 
					        check_diagnostics(
 | 
				
			||||||
 | 
					            r#"
 | 
				
			||||||
extern "rust-intrinsic" {
 | 
					extern "rust-intrinsic" {
 | 
				
			||||||
    #[rustc_safe_intrinsic]
 | 
					    #[rustc_safe_intrinsic]
 | 
				
			||||||
    pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
 | 
					    pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue