Skip to content

Commit 0cdb959

Browse files
committed
use the FnPtr trait
1 parent 04accf1 commit 0cdb959

File tree

3 files changed

+177
-108
lines changed

3 files changed

+177
-108
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+7
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,13 @@ pub fn trait_ref_is_knowable<'tcx>(
412412
trait_ref: ty::TraitRef<'tcx>,
413413
) -> Option<Conflict> {
414414
debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref);
415+
if Some(trait_ref.def_id) == tcx.lang_items().fn_ptr_trait() {
416+
// The only types implementing `FnPtr` are function pointers,
417+
// so if there's no impl of `FnPtr` in the current crate,
418+
// then such an impl will never be added in the future.
419+
return None;
420+
}
421+
415422
if orphan_check_trait_ref(tcx, trait_ref, InCrate::Remote).is_ok() {
416423
// A downstream or cousin crate is allowed to implement some
417424
// substitution of this trait-ref.

library/core/src/marker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ mod copy_impls {
843843
#[unstable(feature = "fn_ptr_trait", issue = "none", reason = "recently added")]
844844
#[lang = "fn_ptr_trait"]
845845
#[cfg(not(bootstrap))]
846-
pub trait FnPtr {
846+
pub trait FnPtr: Copy + Clone {
847847
/// Returns the adress of the function pointer.
848848
#[lang = "fn_ptr_addr"]
849849
fn addr(self) -> usize;

library/core/src/ptr/mod.rs

+169-107
Original file line numberDiff line numberDiff line change
@@ -1825,138 +1825,200 @@ pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
18251825
hashee.hash(into);
18261826
}
18271827

1828-
// If this is a unary fn pointer, it adds a doc comment.
1829-
// Otherwise, it hides the docs entirely.
1830-
macro_rules! maybe_fnptr_doc {
1831-
(@ #[$meta:meta] $item:item) => {
1832-
#[doc(hidden)]
1833-
#[$meta]
1834-
$item
1835-
};
1836-
($a:ident @ #[$meta:meta] $item:item) => {
1837-
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1838-
#[doc = "This trait is implemented for function pointers with up to twelve arguments."]
1839-
#[$meta]
1840-
$item
1841-
};
1842-
($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
1843-
#[doc(hidden)]
1844-
#[$meta]
1845-
$item
1846-
};
1847-
}
1828+
#[cfg(bootstrap)]
1829+
mod old_fn_ptr_impl {
1830+
use super::*;
1831+
// If this is a unary fn pointer, it adds a doc comment.
1832+
// Otherwise, it hides the docs entirely.
1833+
macro_rules! maybe_fnptr_doc {
1834+
(@ #[$meta:meta] $item:item) => {
1835+
#[doc(hidden)]
1836+
#[$meta]
1837+
$item
1838+
};
1839+
($a:ident @ #[$meta:meta] $item:item) => {
1840+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1841+
#[doc = "This trait is implemented for function pointers with up to twelve arguments."]
1842+
#[$meta]
1843+
$item
1844+
};
1845+
($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
1846+
#[doc(hidden)]
1847+
#[$meta]
1848+
$item
1849+
};
1850+
}
18481851

1849-
// FIXME(strict_provenance_magic): function pointers have buggy codegen that
1850-
// necessitates casting to a usize to get the backend to do the right thing.
1851-
// for now I will break AVR to silence *a billion* lints. We should probably
1852-
// have a proper "opaque function pointer type" to handle this kind of thing.
1853-
1854-
// Impls for function pointers
1855-
macro_rules! fnptr_impls_safety_abi {
1856-
($FnTy: ty, $($Arg: ident),*) => {
1857-
maybe_fnptr_doc! {
1858-
$($Arg)* @
1859-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1860-
impl<Ret, $($Arg),*> PartialEq for $FnTy {
1861-
#[inline]
1862-
fn eq(&self, other: &Self) -> bool {
1863-
*self as usize == *other as usize
1852+
// FIXME(strict_provenance_magic): function pointers have buggy codegen that
1853+
// necessitates casting to a usize to get the backend to do the right thing.
1854+
// for now I will break AVR to silence *a billion* lints. We should probably
1855+
// have a proper "opaque function pointer type" to handle this kind of thing.
1856+
1857+
// Impls for function pointers
1858+
macro_rules! fnptr_impls_safety_abi {
1859+
($FnTy: ty, $($Arg: ident),*) => {
1860+
maybe_fnptr_doc! {
1861+
$($Arg)* @
1862+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1863+
impl<Ret, $($Arg),*> PartialEq for $FnTy {
1864+
#[inline]
1865+
fn eq(&self, other: &Self) -> bool {
1866+
*self as usize == *other as usize
1867+
}
18641868
}
18651869
}
1866-
}
18671870

1868-
maybe_fnptr_doc! {
1869-
$($Arg)* @
1870-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1871-
impl<Ret, $($Arg),*> Eq for $FnTy {}
1872-
}
1871+
maybe_fnptr_doc! {
1872+
$($Arg)* @
1873+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1874+
impl<Ret, $($Arg),*> Eq for $FnTy {}
1875+
}
18731876

1874-
maybe_fnptr_doc! {
1875-
$($Arg)* @
1876-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1877-
impl<Ret, $($Arg),*> PartialOrd for $FnTy {
1878-
#[inline]
1879-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1880-
(*self as usize).partial_cmp(&(*other as usize))
1877+
maybe_fnptr_doc! {
1878+
$($Arg)* @
1879+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1880+
impl<Ret, $($Arg),*> PartialOrd for $FnTy {
1881+
#[inline]
1882+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1883+
(*self as usize).partial_cmp(&(*other as usize))
1884+
}
18811885
}
18821886
}
1883-
}
18841887

1885-
maybe_fnptr_doc! {
1886-
$($Arg)* @
1887-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1888-
impl<Ret, $($Arg),*> Ord for $FnTy {
1889-
#[inline]
1890-
fn cmp(&self, other: &Self) -> Ordering {
1891-
(*self as usize).cmp(&(*other as usize))
1888+
maybe_fnptr_doc! {
1889+
$($Arg)* @
1890+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1891+
impl<Ret, $($Arg),*> Ord for $FnTy {
1892+
#[inline]
1893+
fn cmp(&self, other: &Self) -> Ordering {
1894+
(*self as usize).cmp(&(*other as usize))
1895+
}
18921896
}
18931897
}
1894-
}
18951898

1896-
maybe_fnptr_doc! {
1897-
$($Arg)* @
1898-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1899-
impl<Ret, $($Arg),*> hash::Hash for $FnTy {
1900-
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
1901-
state.write_usize(*self as usize)
1899+
maybe_fnptr_doc! {
1900+
$($Arg)* @
1901+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1902+
impl<Ret, $($Arg),*> hash::Hash for $FnTy {
1903+
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
1904+
state.write_usize(*self as usize)
1905+
}
19021906
}
19031907
}
1904-
}
19051908

1906-
maybe_fnptr_doc! {
1907-
$($Arg)* @
1908-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1909-
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
1910-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1911-
fmt::pointer_fmt_inner(*self as usize, f)
1909+
maybe_fnptr_doc! {
1910+
$($Arg)* @
1911+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1912+
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
1913+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1914+
fmt::pointer_fmt_inner(*self as usize, f)
1915+
}
19121916
}
19131917
}
1914-
}
19151918

1916-
maybe_fnptr_doc! {
1917-
$($Arg)* @
1918-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1919-
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
1920-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1921-
fmt::pointer_fmt_inner(*self as usize, f)
1919+
maybe_fnptr_doc! {
1920+
$($Arg)* @
1921+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1922+
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
1923+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1924+
fmt::pointer_fmt_inner(*self as usize, f)
1925+
}
19221926
}
19231927
}
19241928
}
19251929
}
1926-
}
19271930

1928-
macro_rules! fnptr_impls_args {
1929-
($($Arg: ident),+) => {
1930-
fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
1931-
fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
1932-
fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
1933-
fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
1934-
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
1935-
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
1936-
};
1937-
() => {
1938-
// No variadic functions with 0 parameters
1939-
fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
1940-
fnptr_impls_safety_abi! { extern "C" fn() -> Ret, }
1941-
fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, }
1942-
fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, }
1943-
};
1931+
macro_rules! fnptr_impls_args {
1932+
($($Arg: ident),+) => {
1933+
fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
1934+
fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
1935+
fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
1936+
fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
1937+
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
1938+
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
1939+
};
1940+
() => {
1941+
// No variadic functions with 0 parameters
1942+
fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
1943+
fnptr_impls_safety_abi! { extern "C" fn() -> Ret, }
1944+
fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, }
1945+
fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, }
1946+
};
1947+
}
1948+
1949+
fnptr_impls_args! {}
1950+
fnptr_impls_args! { T }
1951+
fnptr_impls_args! { A, B }
1952+
fnptr_impls_args! { A, B, C }
1953+
fnptr_impls_args! { A, B, C, D }
1954+
fnptr_impls_args! { A, B, C, D, E }
1955+
fnptr_impls_args! { A, B, C, D, E, F }
1956+
fnptr_impls_args! { A, B, C, D, E, F, G }
1957+
fnptr_impls_args! { A, B, C, D, E, F, G, H }
1958+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
1959+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J }
1960+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K }
1961+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
19441962
}
19451963

1946-
fnptr_impls_args! {}
1947-
fnptr_impls_args! { T }
1948-
fnptr_impls_args! { A, B }
1949-
fnptr_impls_args! { A, B, C }
1950-
fnptr_impls_args! { A, B, C, D }
1951-
fnptr_impls_args! { A, B, C, D, E }
1952-
fnptr_impls_args! { A, B, C, D, E, F }
1953-
fnptr_impls_args! { A, B, C, D, E, F, G }
1954-
fnptr_impls_args! { A, B, C, D, E, F, G, H }
1955-
fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
1956-
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J }
1957-
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K }
1958-
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
1964+
#[cfg(not(bootstrap))]
1965+
mod new_fn_ptr_impl {
1966+
use super::*;
1967+
use crate::marker::FnPtr;
1968+
1969+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1970+
#[rustc_select_quick_discard]
1971+
impl<F: FnPtr> PartialEq for F {
1972+
#[inline]
1973+
fn eq(&self, other: &Self) -> bool {
1974+
self.addr() == other.addr()
1975+
}
1976+
}
1977+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1978+
#[rustc_select_quick_discard]
1979+
impl<F: FnPtr> Eq for F {}
1980+
1981+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1982+
#[rustc_select_quick_discard]
1983+
impl<F: FnPtr> PartialOrd for F {
1984+
#[inline]
1985+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1986+
self.addr().partial_cmp(&other.addr())
1987+
}
1988+
}
1989+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1990+
#[rustc_select_quick_discard]
1991+
impl<F: FnPtr> Ord for F {
1992+
#[inline]
1993+
fn cmp(&self, other: &Self) -> Ordering {
1994+
self.addr().cmp(&other.addr())
1995+
}
1996+
}
1997+
1998+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1999+
#[rustc_select_quick_discard]
2000+
impl<F: FnPtr> hash::Hash for F {
2001+
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
2002+
state.write_usize(self.addr())
2003+
}
2004+
}
19592005

2006+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
2007+
#[rustc_select_quick_discard]
2008+
impl<F: FnPtr> fmt::Pointer for F {
2009+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2010+
fmt::pointer_fmt_inner(self.addr(), f)
2011+
}
2012+
}
2013+
2014+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
2015+
#[rustc_select_quick_discard]
2016+
impl<F: FnPtr> fmt::Debug for F {
2017+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2018+
fmt::pointer_fmt_inner(self.addr(), f)
2019+
}
2020+
}
2021+
}
19602022
/// Create a `const` raw pointer to a place, without creating an intermediate reference.
19612023
///
19622024
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned

0 commit comments

Comments
 (0)