mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #34012 - eddyb:tick-erased, r=nikomatsakis
rustc: add ReErased to be used by trait selection, MIR and trans. `ReErased` replaces `ReStatic` (i.e. `'static`) for erasing regions. Using a distinct lifetime helps prevent accidental mix-ups between the two. It also allows cleaner type printing (see test changes), including in symbol names: ```rust str..pattern..CharSearcher$LT$$u27$static$GT$::drop.30560::h840c2f2afc03bbea // before str..pattern..CharSearcher::drop.30561::h6bd31d2af614377a // after ``` Not that we should be producing symbols this way, but it's still better.
This commit is contained in:
commit
f35255038b
@ -337,8 +337,10 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
|
||||
match r {
|
||||
// Never make variables for regions bound within the type itself.
|
||||
ty::ReLateBound(..) => { return r; }
|
||||
// Never make variables for regions bound within the type itself,
|
||||
// nor for erased regions.
|
||||
ty::ReLateBound(..) |
|
||||
ty::ReErased => { return r; }
|
||||
|
||||
// Early-bound regions should really have been substituted away before
|
||||
// we get to this point.
|
||||
|
@ -216,7 +216,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
//
|
||||
// We shouldn't really be having unification failures with ReVar
|
||||
// and ReLateBound though.
|
||||
ty::ReSkolemized(..) | ty::ReVar(_) | ty::ReLateBound(..) => {
|
||||
ty::ReSkolemized(..) |
|
||||
ty::ReVar(_) |
|
||||
ty::ReLateBound(..) |
|
||||
ty::ReErased => {
|
||||
(format!("lifetime {:?}", region), None)
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@
|
||||
//! error messages or in any other form. Freshening is only really useful as an internal detail.
|
||||
//!
|
||||
//! __An important detail concerning regions.__ The freshener also replaces *all* regions with
|
||||
//! 'static. The reason behind this is that, in general, we do not take region relationships into
|
||||
//! 'erased. The reason behind this is that, in general, we do not take region relationships into
|
||||
//! account when making type-overloaded decisions. This is important because of the design of the
|
||||
//! region inferencer, which is not based on unification but rather on accumulating and then
|
||||
//! solving a set of constraints. In contrast, the type inferencer assigns a value to each type
|
||||
@ -96,9 +96,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
||||
ty::ReScope(_) |
|
||||
ty::ReVar(_) |
|
||||
ty::ReSkolemized(..) |
|
||||
ty::ReEmpty => {
|
||||
// replace all free regions with 'static
|
||||
ty::ReStatic
|
||||
ty::ReEmpty |
|
||||
ty::ReErased => {
|
||||
// replace all free regions with 'erased
|
||||
ty::ReErased
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use rustc_data_structures::unify::{self, UnificationTable};
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::{BoundRegion, Region, RegionVid};
|
||||
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound};
|
||||
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased};
|
||||
use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -918,8 +918,10 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
||||
(ReLateBound(..), _) |
|
||||
(_, ReLateBound(..)) |
|
||||
(ReEarlyBound(..), _) |
|
||||
(_, ReEarlyBound(..)) => {
|
||||
bug!("cannot relate bound region: LUB({:?}, {:?})", a, b);
|
||||
(_, ReEarlyBound(..)) |
|
||||
(ReErased, _) |
|
||||
(_, ReErased) => {
|
||||
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
|
||||
}
|
||||
|
||||
(ReStatic, _) | (_, ReStatic) => {
|
||||
|
@ -187,7 +187,7 @@ impl FlagComputation {
|
||||
}
|
||||
ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
|
||||
ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
|
||||
ty::ReStatic => {}
|
||||
ty::ReStatic | ty::ReErased => {}
|
||||
_ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
|
||||
}
|
||||
|
||||
|
@ -421,12 +421,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
collector.regions
|
||||
}
|
||||
|
||||
/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
|
||||
/// Replace any late-bound regions bound in `value` with `'erased`. Useful in trans but also
|
||||
/// method lookup and a few other places where precise region relationships are not required.
|
||||
pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
self.replace_late_bound_regions(value, |_| ty::ReStatic).0
|
||||
self.replace_late_bound_regions(value, |_| ty::ReErased).0
|
||||
}
|
||||
|
||||
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
|
||||
@ -547,15 +547,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
|
||||
// because late-bound regions affect subtyping, we can't
|
||||
// erase the bound/free distinction, but we can replace
|
||||
// all free regions with 'static.
|
||||
// all free regions with 'erased.
|
||||
//
|
||||
// Note that we *CAN* replace early-bound regions -- the
|
||||
// type system never "sees" those, they get substituted
|
||||
// away. In trans, they will always be erased to 'static
|
||||
// away. In trans, they will always be erased to 'erased
|
||||
// whenever a substitution occurs.
|
||||
match r {
|
||||
ty::ReLateBound(..) => r,
|
||||
_ => ty::ReStatic
|
||||
_ => ty::ReErased
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -651,7 +651,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
||||
// does this represent a region that cannot be named
|
||||
// in a global way? used in fulfillment caching.
|
||||
match r {
|
||||
ty::ReStatic | ty::ReEmpty => {}
|
||||
ty::ReStatic | ty::ReEmpty | ty::ReErased => {}
|
||||
_ => return true,
|
||||
}
|
||||
}
|
||||
|
@ -705,6 +705,9 @@ pub enum Region {
|
||||
/// The only way to get an instance of ReEmpty is to have a region
|
||||
/// variable with no constraints.
|
||||
ReEmpty,
|
||||
|
||||
/// Erased region, used by trait selection, in MIR and during trans.
|
||||
ReErased,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||
|
@ -89,7 +89,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
|
||||
pub fn erase_regions(self) -> Substs<'tcx> {
|
||||
let Substs { types, regions } = self;
|
||||
let regions = regions.map(|_| ty::ReStatic);
|
||||
let regions = regions.map(|_| ty::ReErased);
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let region = |state: &mut SipHasher, r: ty::Region| {
|
||||
match r {
|
||||
ty::ReStatic => {}
|
||||
ty::ReStatic | ty::ReErased => {}
|
||||
ty::ReLateBound(db, ty::BrAnon(i)) => {
|
||||
db.hash(state);
|
||||
i.hash(state);
|
||||
|
@ -148,28 +148,36 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
||||
write!(f, "{}", cont)
|
||||
}
|
||||
};
|
||||
let print_region = |f: &mut fmt::Formatter, region: &ty::Region| -> _ {
|
||||
if verbose {
|
||||
write!(f, "{:?}", region)
|
||||
} else {
|
||||
let s = region.to_string();
|
||||
if s.is_empty() {
|
||||
// This happens when the value of the region
|
||||
// parameter is not easily serialized. This may be
|
||||
// because the user omitted it in the first place,
|
||||
// or because it refers to some block in the code,
|
||||
// etc. I'm not sure how best to serialize this.
|
||||
write!(f, "'_")
|
||||
|
||||
let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| {
|
||||
// Don't print any regions if they're all erased.
|
||||
if regions.iter().all(|r| *r == ty::ReErased) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for region in regions {
|
||||
start_or_continue(f, start, ", ")?;
|
||||
if verbose {
|
||||
write!(f, "{:?}", region)?;
|
||||
} else {
|
||||
write!(f, "{}", s)
|
||||
let s = region.to_string();
|
||||
if s.is_empty() {
|
||||
// This happens when the value of the region
|
||||
// parameter is not easily serialized. This may be
|
||||
// because the user omitted it in the first place,
|
||||
// or because it refers to some block in the code,
|
||||
// etc. I'm not sure how best to serialize this.
|
||||
write!(f, "'_")?;
|
||||
} else {
|
||||
write!(f, "{}", s)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
for region in substs.regions.get_slice(subst::TypeSpace) {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
print_region(f, region)?;
|
||||
}
|
||||
print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;
|
||||
|
||||
let num_supplied_defaults = if verbose {
|
||||
0
|
||||
@ -211,10 +219,7 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
||||
write!(f, "::{}", item_name)?;
|
||||
}
|
||||
|
||||
for region in substs.regions.get_slice(subst::FnSpace) {
|
||||
start_or_continue(f, "::<", ", ")?;
|
||||
print_region(f, region)?;
|
||||
}
|
||||
print_regions(f, "::<", substs.regions.get_slice(subst::FnSpace))?;
|
||||
|
||||
// FIXME: consider being smart with defaults here too
|
||||
for ty in substs.types.get_slice(subst::FnSpace) {
|
||||
@ -536,7 +541,9 @@ impl fmt::Debug for ty::Region {
|
||||
write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
|
||||
}
|
||||
|
||||
ty::ReEmpty => write!(f, "ReEmpty")
|
||||
ty::ReEmpty => write!(f, "ReEmpty"),
|
||||
|
||||
ty::ReErased => write!(f, "ReErased")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -600,7 +607,8 @@ impl fmt::Display for ty::Region {
|
||||
write!(f, "{}", br)
|
||||
}
|
||||
ty::ReScope(_) |
|
||||
ty::ReVar(_) => Ok(()),
|
||||
ty::ReVar(_) |
|
||||
ty::ReErased => Ok(()),
|
||||
ty::ReStatic => write!(f, "'static"),
|
||||
ty::ReEmpty => write!(f, "'<empty>"),
|
||||
}
|
||||
|
@ -369,7 +369,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||
ty::ReLateBound(..) |
|
||||
ty::ReEarlyBound(..) |
|
||||
ty::ReVar(..) |
|
||||
ty::ReSkolemized(..) => {
|
||||
ty::ReSkolemized(..) |
|
||||
ty::ReErased => {
|
||||
span_bug!(
|
||||
cmt.span,
|
||||
"invalid borrow lifetime: {:?}",
|
||||
|
@ -221,12 +221,9 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
|
||||
assert_eq!(self.next(), '|');
|
||||
ty::ReScope(scope)
|
||||
}
|
||||
't' => {
|
||||
ty::ReStatic
|
||||
}
|
||||
'e' => {
|
||||
ty::ReStatic
|
||||
}
|
||||
't' => ty::ReStatic,
|
||||
'e' => ty::ReEmpty,
|
||||
'E' => ty::ReErased,
|
||||
_ => bug!("parse_region: bad input")
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +283,9 @@ pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
|
||||
ty::ReEmpty => {
|
||||
write!(w, "e");
|
||||
}
|
||||
ty::ReErased => {
|
||||
write!(w, "E");
|
||||
}
|
||||
ty::ReVar(_) | ty::ReSkolemized(..) => {
|
||||
// these should not crop up after typeck
|
||||
bug!("cannot encode region variables");
|
||||
|
@ -731,7 +731,7 @@ fn bind_subslice_pat(bcx: Block,
|
||||
let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]);
|
||||
let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right);
|
||||
let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
|
||||
let slice_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic),
|
||||
let slice_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReErased),
|
||||
bcx.tcx().mk_slice(unit_ty));
|
||||
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
|
||||
Store(bcx, slice_begin, expr::get_dataptr(bcx, scratch.val));
|
||||
|
@ -328,7 +328,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||
};
|
||||
|
||||
let bare_fn_ty_maybe_ref = if is_by_ref {
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), bare_fn_ty)
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), bare_fn_ty)
|
||||
} else {
|
||||
bare_fn_ty
|
||||
};
|
||||
|
@ -123,10 +123,10 @@ fn get_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
-> Ty<'tcx> {
|
||||
match tcx.closure_kind(closure_id) {
|
||||
ty::ClosureKind::Fn => {
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), fn_ty)
|
||||
tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), fn_ty)
|
||||
}
|
||||
ty::ClosureKind::FnMut => {
|
||||
tcx.mk_mut_ref(tcx.mk_region(ty::ReStatic), fn_ty)
|
||||
tcx.mk_mut_ref(tcx.mk_region(ty::ReErased), fn_ty)
|
||||
}
|
||||
ty::ClosureKind::FnOnce => fn_ty,
|
||||
}
|
||||
@ -344,7 +344,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
// Find a version of the closure type. Substitute static for the
|
||||
// region since it doesn't really matter.
|
||||
let closure_ty = tcx.mk_closure_from_closure_substs(closure_def_id, substs);
|
||||
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty);
|
||||
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), closure_ty);
|
||||
|
||||
// Make a version with the type of by-ref closure.
|
||||
let ty::ClosureTy { unsafety, abi, mut sig } =
|
||||
|
@ -382,7 +382,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
// Don't copy data to do a deref+ref
|
||||
// (i.e., skip the last auto-deref).
|
||||
llconst = addr_of(cx, llconst, type_of::align_of(cx, ty), "autoref");
|
||||
ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReStatic), ty);
|
||||
ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReErased), ty);
|
||||
}
|
||||
} else if adj.autoderefs > 0 {
|
||||
let (dv, dt) = const_deref(cx, llconst, ty);
|
||||
|
@ -495,7 +495,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
assert!(scheme.generics.types.is_empty());
|
||||
self.tcx().mk_substs(
|
||||
Substs::new(VecPerParamSpace::empty(),
|
||||
scheme.generics.regions.map(|_| ty::ReStatic)))
|
||||
scheme.generics.regions.map(|_| ty::ReErased)))
|
||||
}
|
||||
|
||||
pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
|
||||
|
@ -1978,7 +1978,7 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Compute final type. Note that we are loose with the region and
|
||||
// mutability, since those things don't matter in trans.
|
||||
let referent_ty = lv_datum.ty;
|
||||
let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), referent_ty);
|
||||
let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReErased), referent_ty);
|
||||
|
||||
// Construct the resulting datum. The right datum to return here would be an Lvalue datum,
|
||||
// because there is cleanup scheduled and the datum doesn't own the data, but for thin pointers
|
||||
|
@ -271,7 +271,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// the method may have some early-bound lifetimes, add
|
||||
// regions for those
|
||||
let num_dummy_regions = trait_method_type.generics.regions.len(FnSpace);
|
||||
let dummy_regions = vec![ty::ReStatic; num_dummy_regions];
|
||||
let dummy_regions = vec![ty::ReErased; num_dummy_regions];
|
||||
let method_substs = substs.clone()
|
||||
.with_method(vec![], dummy_regions);
|
||||
let method_substs = tcx.mk_substs(method_substs);
|
||||
|
@ -715,7 +715,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
let tr_lvalue = self.const_lvalue(lvalue, span)?;
|
||||
|
||||
let ty = tr_lvalue.ty;
|
||||
let ref_ty = tcx.mk_ref(tcx.mk_region(ty::ReStatic),
|
||||
let ref_ty = tcx.mk_ref(tcx.mk_region(ty::ReErased),
|
||||
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() });
|
||||
|
||||
let base = match tr_lvalue.base {
|
||||
|
@ -373,7 +373,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
|
||||
let ty = tr_lvalue.ty.to_ty(bcx.tcx());
|
||||
let ref_ty = bcx.tcx().mk_ref(
|
||||
bcx.tcx().mk_region(ty::ReStatic),
|
||||
bcx.tcx().mk_region(ty::ReErased),
|
||||
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() }
|
||||
);
|
||||
|
||||
|
@ -180,7 +180,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||
impl<'tcx> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
|
||||
-> Instance<'tcx> {
|
||||
assert!(substs.regions.iter().all(|&r| r == ty::ReStatic));
|
||||
assert!(substs.regions.iter().all(|&r| r == ty::ReErased));
|
||||
Instance { def: def_id, substs: substs }
|
||||
}
|
||||
pub fn mono<'a>(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||
|
@ -976,7 +976,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
// In general, during probing we erase regions. See
|
||||
// `impl_self_ty()` for an explanation.
|
||||
let region = tcx.mk_region(ty::ReStatic);
|
||||
let region = tcx.mk_region(ty::ReErased);
|
||||
|
||||
// Search through mutabilities in order to find one where pick works:
|
||||
[hir::MutImmutable, hir::MutMutable].iter().filter_map(|&m| {
|
||||
@ -1240,7 +1240,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
let method_regions =
|
||||
method.generics.regions.get_slice(subst::FnSpace)
|
||||
.iter()
|
||||
.map(|_| ty::ReStatic)
|
||||
.map(|_| ty::ReErased)
|
||||
.collect();
|
||||
|
||||
placeholder = (*substs).clone().with_method(Vec::new(), method_regions);
|
||||
@ -1276,7 +1276,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
let region_placeholders =
|
||||
impl_pty.generics.regions.map(
|
||||
|_| ty::ReStatic); // see erase_late_bound_regions() for an expl of why 'static
|
||||
|_| ty::ReErased); // see erase_late_bound_regions() for an expl of why 'erased
|
||||
|
||||
let substs = subst::Substs::new(type_vars, region_placeholders);
|
||||
(impl_pty.ty, substs)
|
||||
|
@ -520,7 +520,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
ty::ReFree(..) | ty::ReScope(..) | ty::ReVar(..) |
|
||||
ty::ReSkolemized(..) | ty::ReEmpty => {
|
||||
ty::ReSkolemized(..) | ty::ReEmpty | ty::ReErased => {
|
||||
// We don't expect to see anything but 'static or bound
|
||||
// regions when visiting member types or method types.
|
||||
bug!("unexpected region encountered in variance \
|
||||
|
@ -827,7 +827,8 @@ impl Clean<Option<Lifetime>> for ty::Region {
|
||||
ty::ReScope(..) |
|
||||
ty::ReVar(..) |
|
||||
ty::ReSkolemized(..) |
|
||||
ty::ReEmpty => None
|
||||
ty::ReEmpty |
|
||||
ty::ReErased => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,22 +60,22 @@ unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
|
||||
|
||||
unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
|
||||
intrinsics::atomic_load(p);
|
||||
//~^ ERROR expected basic integer type, found `&'static std::ops::Fn() + 'static`
|
||||
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
|
||||
}
|
||||
|
||||
unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
|
||||
intrinsics::atomic_store(p, v);
|
||||
//~^ ERROR expected basic integer type, found `&'static std::ops::Fn() + 'static`
|
||||
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
|
||||
}
|
||||
|
||||
unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
|
||||
intrinsics::atomic_xchg(p, v);
|
||||
//~^ ERROR expected basic integer type, found `&'static std::ops::Fn() + 'static`
|
||||
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
|
||||
}
|
||||
|
||||
unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
|
||||
intrinsics::atomic_cxchg(p, v, v);
|
||||
//~^ ERROR expected basic integer type, found `&'static std::ops::Fn() + 'static`
|
||||
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
|
||||
}
|
||||
|
||||
unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
|
||||
|
@ -26,5 +26,5 @@ fn main() {
|
||||
std::intrinsics::type_name::<NT>(),
|
||||
// DST
|
||||
std::intrinsics::type_name::<DST>()
|
||||
)}, ("[u8]", "str", "std::marker::Send + 'static", "NT", "DST"));
|
||||
)}, ("[u8]", "str", "std::marker::Send", "NT", "DST"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user