Begin to implement type system layer of unsafe binders

This commit is contained in:
Michael Goulet
2024-12-21 17:05:40 +00:00
parent b22856d192
commit 9a1c5eb5b3
79 changed files with 536 additions and 305 deletions
@@ -263,7 +263,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
&self,
negative_impls,
span.to(of_trait.as_ref().map_or(span, |t| t.path.span)),
"negative trait bounds are not yet fully implemented; \
"negative trait bounds are not fully implemented; \
use marker types for now"
);
}
+2
View File
@@ -1613,6 +1613,7 @@ fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
@@ -1654,6 +1655,7 @@ fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
| ty::Dynamic(_, _, _)
| ty::CoroutineWitness(..)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
@@ -432,6 +432,7 @@ fn push_debuginfo_type_name<'tcx>(
push_closure_or_coroutine_name(tcx, def_id, args, qualified, output, visited);
}
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"),
ty::Param(_)
| ty::Error(_)
| ty::Infer(_)
@@ -178,7 +178,8 @@ fn const_to_valtree_inner<'tcx>(
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
}
}
@@ -358,7 +359,10 @@ pub fn valtree_to_const_value<'tcx>(
| ty::FnPtr(..)
| ty::Str
| ty::Slice(_)
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
| ty::Dynamic(..)
| ty::UnsafeBinder(_) => {
bug!("no ValTree should have been created for type {:?}", ty.kind())
}
}
}
@@ -90,6 +90,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::CoroutineClosure(_, _)
| ty::Coroutine(_, _)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_)
| ty::Never
| ty::Tuple(_)
| ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
@@ -505,6 +505,8 @@ fn is_very_trivially_sized(ty: Ty<'_>) -> bool {
// We don't want to do any queries, so there is not much we can do with ADTs.
ty::Adt(..) => false,
ty::UnsafeBinder(ty) => is_very_trivially_sized(ty.skip_binder()),
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,
ty::Infer(ty::TyVar(_)) => false,
@@ -768,6 +768,7 @@ fn try_visit_primitive(
// Nothing to check.
interp_ok(true)
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// The above should be all the primitive types. The rest is compound, we
// check them by visiting their fields/variants.
ty::Adt(..)
@@ -38,7 +38,8 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
| ty::FnPtr(..)
| ty::Never
| ty::Tuple(_)
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
| ty::Dynamic(_, _, _)
| ty::UnsafeBinder(_) => self.pretty_print_type(ty),
// Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
@@ -178,7 +178,8 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
| ty::Ref(..)
| ty::Never
| ty::FnPtr(..)
| ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
| ty::Tuple(..)
| ty::UnsafeBinder(_) => self.check_primitive_impl(id, self_ty),
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => {
Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span }))
}
@@ -225,7 +225,8 @@ enum NonlocalImpl {
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Never
| ty::Tuple(..) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
| ty::Tuple(..)
| ty::UnsafeBinder(_) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -2318,13 +2318,13 @@ pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
)
}
hir::TyKind::UnsafeBinder(_binder) => {
let guar = self
.dcx()
.struct_span_err(hir_ty.span, "unsafe binders are not yet implemented")
.emit();
Ty::new_error(tcx, guar)
}
hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
tcx,
ty::Binder::bind_with_vars(
self.lower_ty(binder.inner_ty),
tcx.late_bound_vars(hir_ty.hir_id),
),
),
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
// Don't continue with type analysis if the `dyn` keyword is missing
@@ -322,6 +322,11 @@ fn add_constraints_from_ty(
self.add_constraints_from_sig(current, sig_tys.with(hdr), variance);
}
ty::UnsafeBinder(ty) => {
// FIXME(unsafe_binders): This is covariant, right?
self.add_constraints_from_ty(current, ty.skip_binder(), variance);
}
ty::Error(_) => {
// we encounter this when walking the trait references for object
// types, where we use Error as the Self type
+2
View File
@@ -116,6 +116,8 @@ fn pointer_kind(
Some(&f) => self.pointer_kind(f, span)?,
},
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// Pointers to foreign types are thin, despite being unsized
ty::Foreign(..) => Some(PointerKind::Thin),
// We should really try to normalize here.
+89 -9
View File
@@ -574,8 +574,8 @@ fn check_expr_kind(
self.check_expr_index(base, idx, expr, brackets_span)
}
ExprKind::Yield(value, _) => self.check_expr_yield(value, expr),
ExprKind::UnsafeBinderCast(kind, expr, ty) => {
self.check_expr_unsafe_binder_cast(kind, expr, ty, expected)
ExprKind::UnsafeBinderCast(kind, inner_expr, ty) => {
self.check_expr_unsafe_binder_cast(expr.span, kind, inner_expr, ty, expected)
}
ExprKind::Err(guar) => Ty::new_error(tcx, guar),
}
@@ -1649,14 +1649,94 @@ fn check_expr_cast(
fn check_expr_unsafe_binder_cast(
&self,
_kind: hir::UnsafeBinderCastKind,
expr: &'tcx hir::Expr<'tcx>,
_hir_ty: Option<&'tcx hir::Ty<'tcx>>,
_expected: Expectation<'tcx>,
span: Span,
kind: hir::UnsafeBinderCastKind,
inner_expr: &'tcx hir::Expr<'tcx>,
hir_ty: Option<&'tcx hir::Ty<'tcx>>,
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
let guar =
self.dcx().struct_span_err(expr.span, "unsafe binders are not yet implemented").emit();
Ty::new_error(self.tcx, guar)
self.dcx().span_err(inner_expr.span, "unsafe binder casts are not fully implemented");
match kind {
hir::UnsafeBinderCastKind::Wrap => {
let ascribed_ty =
hir_ty.map(|hir_ty| self.lower_ty_saving_user_provided_ty(hir_ty));
let expected_ty = expected.only_has_type(self);
let binder_ty = match (ascribed_ty, expected_ty) {
(Some(ascribed_ty), Some(expected_ty)) => {
self.demand_eqtype(inner_expr.span, expected_ty, ascribed_ty);
expected_ty
}
(Some(ty), None) | (None, Some(ty)) => ty,
// This will always cause a structural resolve error, but we do it
// so we don't need to manually report an E0282 both on this codepath
// and in the others; it all happens in `structurally_resolve_type`.
(None, None) => self.next_ty_var(inner_expr.span),
};
let binder_ty = self.structurally_resolve_type(inner_expr.span, binder_ty);
let hint_ty = match *binder_ty.kind() {
ty::UnsafeBinder(binder) => self.instantiate_binder_with_fresh_vars(
inner_expr.span,
infer::BoundRegionConversionTime::HigherRankedType,
binder.into(),
),
ty::Error(e) => Ty::new_error(self.tcx, e),
_ => {
let guar = self
.dcx()
.struct_span_err(
hir_ty.map_or(span, |hir_ty| hir_ty.span),
format!(
"`wrap_binder!()` can only wrap into unsafe binder, not {}",
binder_ty.sort_string(self.tcx)
),
)
.with_note("unsafe binders are the only valid output of wrap")
.emit();
Ty::new_error(self.tcx, guar)
}
};
self.check_expr_has_type_or_error(inner_expr, hint_ty, |_| {});
binder_ty
}
hir::UnsafeBinderCastKind::Unwrap => {
let ascribed_ty =
hir_ty.map(|hir_ty| self.lower_ty_saving_user_provided_ty(hir_ty));
let hint_ty = ascribed_ty.unwrap_or_else(|| self.next_ty_var(inner_expr.span));
// FIXME(unsafe_binders): coerce here if needed?
let binder_ty = self.check_expr_has_type_or_error(inner_expr, hint_ty, |_| {});
// Unwrap the binder. This will be ambiguous if it's an infer var, and will error
// if it's not an unsafe binder.
let binder_ty = self.structurally_resolve_type(inner_expr.span, binder_ty);
match *binder_ty.kind() {
ty::UnsafeBinder(binder) => self.instantiate_binder_with_fresh_vars(
inner_expr.span,
infer::BoundRegionConversionTime::HigherRankedType,
binder.into(),
),
ty::Error(e) => Ty::new_error(self.tcx, e),
_ => {
let guar = self
.dcx()
.struct_span_err(
hir_ty.map_or(inner_expr.span, |hir_ty| hir_ty.span),
format!(
"expected unsafe binder, found {} as input of \
`unwrap_binder!()`",
binder_ty.sort_string(self.tcx)
),
)
.with_note("only an unsafe binder type can be unwrapped")
.emit();
Ty::new_error(self.tcx, guar)
}
}
}
}
}
fn check_expr_array(
@@ -441,6 +441,7 @@ fn fold_ty(&mut self, mut t: Ty<'tcx>) -> Ty<'tcx> {
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Dynamic(..)
| ty::UnsafeBinder(_)
| ty::Never
| ty::Tuple(..)
| ty::Alias(..)
+2
View File
@@ -1284,6 +1284,8 @@ fn check_type_for_ffi(
FfiSafe
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
ty::Param(..)
| ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
| ty::Infer(..)
+3 -1
View File
@@ -471,7 +471,8 @@ fn for_each_relevant_impl(
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::Never
| ty::Tuple(_) => {
| ty::Tuple(_)
| ty::UnsafeBinder(_) => {
let simp = ty::fast_reject::simplify_type(
tcx,
self_ty,
@@ -2295,6 +2296,7 @@ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ref,
FnDef,
FnPtr,
UnsafeBinder,
Placeholder,
Coroutine,
CoroutineWitness,
+1
View File
@@ -191,6 +191,7 @@ pub fn prefix_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
_ => "fn item".into(),
},
ty::FnPtr(..) => "fn pointer".into(),
ty::UnsafeBinder(_) => "unsafe binder".into(),
ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
ty::Coroutine(def_id, ..) => {
+6
View File
@@ -253,6 +253,12 @@ fn add_kind(&mut self, kind: &ty::TyKind<'_>) {
&ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| {
computation.add_tys(sig_tys.inputs_and_output);
}),
&ty::UnsafeBinder(bound_ty) => {
self.bound_computation(bound_ty.into(), |computation, ty| {
computation.add_ty(ty);
})
}
}
}
+5
View File
@@ -816,6 +816,11 @@ fn field_ty_or_layout<'tcx>(
bug!("TyAndLayout::field({:?}): not applicable", this)
}
ty::UnsafeBinder(bound_ty) => {
let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
field_ty_or_layout(TyAndLayout { ty, ..this }, cx, i)
}
// Potentially-wide pointers.
ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
assert!(i < this.fields.count());
@@ -291,6 +291,7 @@ fn characteristic_def_id_of_type_cached<'a>(
| ty::Uint(_)
| ty::Str
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Alias(..)
| ty::Placeholder(..)
| ty::Param(_)
@@ -695,6 +695,10 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
}
}
ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
ty::UnsafeBinder(ref bound_ty) => {
// FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`.
self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?;
}
ty::Infer(infer_ty) => {
if self.should_print_verbose() {
p!(write("{:?}", ty.kind()));
@@ -393,6 +393,7 @@ fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
ty::UnsafeBinder(f) => ty::UnsafeBinder(f.try_fold_with(folder)?),
ty::Ref(r, ty, mutbl) => {
ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
}
@@ -443,6 +444,7 @@ fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::
ty::Tuple(ts) => ts.visit_with(visitor),
ty::FnDef(_, args) => args.visit_with(visitor),
ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
ty::UnsafeBinder(ref f) => f.visit_with(visitor),
ty::Ref(r, ty, _) => {
try_visit!(r.visit_with(visitor));
ty.visit_with(visitor)
+17 -1
View File
@@ -673,6 +673,11 @@ pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
Ty::new(tcx, FnPtr(sig_tys, hdr))
}
#[inline]
pub fn new_unsafe_binder(tcx: TyCtxt<'tcx>, b: Binder<'tcx, Ty<'tcx>>) -> Ty<'tcx> {
Ty::new(tcx, UnsafeBinder(b.into()))
}
#[inline]
pub fn new_dynamic(
tcx: TyCtxt<'tcx>,
@@ -962,6 +967,10 @@ fn new_pat(interner: TyCtxt<'tcx>, ty: Self, pat: ty::Pattern<'tcx>) -> Self {
Ty::new_pat(interner, ty, pat)
}
fn new_unsafe_binder(interner: TyCtxt<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>) -> Self {
Ty::new_unsafe_binder(interner, ty)
}
fn new_unit(interner: TyCtxt<'tcx>) -> Self {
interner.types.unit
}
@@ -1480,6 +1489,7 @@ pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Error(_)
| ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8,
@@ -1659,6 +1669,8 @@ pub fn ptr_metadata_ty_or_tail(
// metadata of `tail`.
ty::Param(_) | ty::Alias(..) => Err(tail),
| ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
ty::Infer(ty::TyVar(_))
| ty::Pat(..)
| ty::Bound(..)
@@ -1819,6 +1831,7 @@ pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool {
| ty::Float(_)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::RawPtr(..)
| ty::Char
| ty::Ref(..)
@@ -1898,6 +1911,8 @@ pub fn is_trivially_pure_clone_copy(self) -> bool {
// Might be, but not "trivial" so just giving the safe answer.
ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) => false,
ty::UnsafeBinder(_) => false,
// Needs normalization or revealing to determine, so no is the safe answer.
ty::Alias(..) => false,
@@ -1976,7 +1991,8 @@ pub fn is_known_rigid(self) -> bool {
| Coroutine(_, _)
| CoroutineWitness(..)
| Never
| Tuple(_) => true,
| Tuple(_)
| UnsafeBinder(_) => true,
Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false,
}
}
+8 -2
View File
@@ -1241,6 +1241,7 @@ pub fn is_trivially_freeze(self) -> bool {
| ty::Foreign(_)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
@@ -1281,6 +1282,7 @@ fn is_trivially_unpin(self) -> bool {
| ty::Foreign(_)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
@@ -1322,6 +1324,9 @@ pub fn async_drop_glue_morphology(self, tcx: TyCtxt<'tcx>) -> AsyncDropGlueMorph
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
// FIXME(unsafe_binders):
ty::UnsafeBinder(_) => todo!(),
ty::Tuple(tys) if tys.is_empty() => AsyncDropGlueMorphology::Noop,
ty::Adt(adt_def, _) if adt_def.is_manually_drop() => AsyncDropGlueMorphology::Noop,
@@ -1522,7 +1527,7 @@ pub fn is_structural_eq_shallow(self, tcx: TyCtxt<'tcx>) -> bool {
false
}
ty::Foreign(_) | ty::CoroutineWitness(..) | ty::Error(_) => false,
ty::Foreign(_) | ty::CoroutineWitness(..) | ty::Error(_) | ty::UnsafeBinder(_) => false,
}
}
@@ -1681,7 +1686,8 @@ pub fn needs_drop_components_with_async<'tcx>(
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..) => Ok(smallvec![ty]),
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_) => Ok(smallvec![ty]),
}
}
+3
View File
@@ -194,6 +194,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
sig_tys.skip_binder().inputs_and_output.iter().rev().map(|ty| ty.into()),
);
}
ty::UnsafeBinder(bound_ty) => {
stack.push(bound_ty.skip_binder().into());
}
},
GenericArgKind::Lifetime(_) => {}
GenericArgKind::Const(parent_ct) => match parent_ct.kind() {
@@ -161,6 +161,7 @@ fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
@@ -200,6 +201,7 @@ fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
| ty::Dynamic(_, _, _)
| ty::CoroutineWitness(..)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
@@ -944,7 +944,8 @@ fn try_write_constant<'tcx>(
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::Dynamic(..) => throw_machine_stop_str!("unsupported type"),
| ty::Dynamic(..)
| ty::UnsafeBinder(_) => throw_machine_stop_str!("unsupported type"),
ty::Error(_) | ty::Infer(..) | ty::CoroutineWitness(..) => bug!(),
}
@@ -285,7 +285,9 @@ fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
| ty::Placeholder(_)
| ty::Infer(_)
| ty::Slice(_)
| ty::Array(_, _) => None,
| ty::Array(_, _)
| ty::UnsafeBinder(_) => None,
ty::Adt(adt_def, _) => {
let did = adt_def.did();
let try_local_did_span = |did: DefId| {
@@ -378,6 +378,7 @@ fn cached_fold_ty(&mut self, t: I::Ty) -> I::Ty {
| ty::Pat(_, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -339,7 +339,9 @@ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
| ty::Slice(..)
| ty::RawPtr(..)
| ty::Never
| ty::Tuple(..) => self.found_non_local_ty(ty),
| ty::Tuple(..)
// FIXME(unsafe_binders): Non-local?
| ty::UnsafeBinder(_) => self.found_non_local_ty(ty),
ty::Param(..) => panic!("unexpected ty param"),
@@ -545,6 +545,7 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -634,6 +635,7 @@ fn assemble_object_bound_candidates<G: GoalKind<D>>(
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Alias(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -83,6 +83,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>(
.map(|bty| bty.instantiate(cx, args))
.collect()),
ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]),
// For `PhantomData<T>`, we pass `T`.
ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
@@ -144,6 +146,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<D, I>(
panic!("unexpected type `{ty:?}`")
}
ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]),
// impl Sized for ()
// impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])),
@@ -239,6 +243,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>(
}
},
ty::UnsafeBinder(_) => Err(NoSolution),
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
ty::CoroutineWitness(def_id, args) => Ok(ecx
.cx()
@@ -374,6 +380,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
| ty::Never
| ty::Tuple(_)
| ty::Pat(_, _)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Placeholder(..)
@@ -544,6 +551,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
| ty::Coroutine(_, _)
| ty::CoroutineWitness(..)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Param(_)
@@ -694,7 +702,8 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
| ty::Param(_)
| ty::Placeholder(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Error(_) => return Err(NoSolution),
| ty::Error(_)
| ty::UnsafeBinder(_) => return Err(NoSolution),
ty::Bound(..)
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
@@ -764,6 +773,10 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
| ty::Coroutine(_, _)
| ty::CoroutineWitness(_, _) => Err(NoSolution),
// FIXME(unsafe_binders): Unsafe binders could implement `~const Drop`
// if their inner type implements it.
ty::UnsafeBinder(_) => Err(NoSolution),
ty::Dynamic(..) | ty::Param(_) | ty::Alias(..) | ty::Placeholder(_) | ty::Foreign(_) => {
Err(NoSolution)
}
@@ -619,6 +619,11 @@ fn consider_builtin_pointee_candidate(
Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]),
},
ty::UnsafeBinder(_) => {
// FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders.
todo!()
}
ty::Infer(
ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
)
@@ -822,6 +827,11 @@ fn consider_builtin_discriminant_kind_candidate(
| ty::Tuple(_)
| ty::Error(_) => self_ty.discriminant_ty(ecx.cx()),
ty::UnsafeBinder(_) => {
// FIXME(unsafe_binders): instantiate this with placeholders?? i guess??
todo!("discr subgoal...")
}
// We do not call `Ty::discriminant_ty` on alias, param, or placeholder
// types, which return `<self_ty as DiscriminantKind>::Discriminant`
// (or ICE in the case of placeholders). Projecting a type to itself
@@ -869,6 +879,11 @@ fn consider_builtin_async_destruct_candidate(
| ty::Tuple(_)
| ty::Error(_) => self_ty.async_destructor_ty(ecx.cx()),
ty::UnsafeBinder(_) => {
// FIXME(unsafe_binders): Instantiate the binder with placeholders I guess.
todo!()
}
// We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
// types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
// (or ICE in the case of placeholders). Projecting a type to itself
@@ -1100,7 +1100,8 @@ fn disqualify_auto_trait_candidate_due_to_possible_impl(
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::Adt(_, _) => {
| ty::Adt(_, _)
| ty::UnsafeBinder(_) => {
let mut disqualifying_impl = None;
self.cx().for_each_relevant_impl(
goal.predicate.def_id(),
@@ -415,6 +415,7 @@ pub fn ctors_for_ty(
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Error(_) => ConstructorSet::Unlistable,
+1
View File
@@ -285,6 +285,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
| ty::Ref(..)
| ty::Pat(..)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Param(..)
| ty::Bound(..)
| ty::Error(_)
@@ -621,6 +621,11 @@ pub(crate) fn encode_ty<'tcx>(
typeid.push_str(&s);
}
// FIXME(unsafe_binders): Implement this.
ty::UnsafeBinder(_) => {
todo!()
}
// Trait types
ty::Dynamic(predicates, region, kind) => {
// u3dynI<element-type1[..element-typeN]>E, where <element-type> is <predicate>, as
@@ -64,7 +64,8 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
| ty::Pat(..)
| ty::Slice(..)
| ty::Str
| ty::Tuple(..) => t.super_fold_with(self),
| ty::Tuple(..)
| ty::UnsafeBinder(_) => t.super_fold_with(self),
ty::Bool => {
if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
@@ -356,6 +356,8 @@ fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
ty::FnPtr(sig_tys, hdr) => {
TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables)))
}
// FIXME(unsafe_binders):
ty::UnsafeBinder(_) => todo!(),
ty::Dynamic(existential_predicates, region, dyn_kind) => {
TyKind::RigidTy(RigidTy::Dynamic(
existential_predicates
+1
View File
@@ -2149,6 +2149,7 @@
unwrap,
unwrap_binder,
unwrap_or,
unwrap_unsafe_binder,
use_extern_macros,
use_nested_groups,
used,
+3
View File
@@ -466,6 +466,9 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
})?;
}
// FIXME(unsafe_binder):
ty::UnsafeBinder(..) => todo!(),
ty::Dynamic(predicates, r, kind) => {
self.push(match kind {
ty::Dyn => "D",
@@ -1532,6 +1532,7 @@ fn type_category(tcx: TyCtxt<'_>, t: Ty<'_>) -> Option<u32> {
ty::CoroutineWitness(..) => Some(20),
ty::CoroutineClosure(..) => Some(21),
ty::Pat(..) => Some(22),
ty::UnsafeBinder(..) => Some(23),
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
}
}
@@ -1047,6 +1047,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// Integers and floats always have `u8` as their discriminant.
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// type parameters, opaques, and unnormalized projections don't have
// a known discriminant and may need to be normalized further or rely
// on param env for discriminant projections
@@ -1072,6 +1074,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -1163,6 +1166,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
true
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
ty::Param(_)
| ty::Alias(..)
@@ -83,7 +83,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
| ty::Placeholder(..)
| ty::Infer(_)
| ty::Bound(..)
| ty::Coroutine(..) => false,
| ty::Coroutine(..)
| ty::UnsafeBinder(_) => false,
}
}
@@ -336,6 +337,11 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
constraints.dtorck_types.push(ty);
}
// Can't instantiate binder here.
ty::UnsafeBinder(_) => {
constraints.dtorck_types.push(ty);
}
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => {
// By the time this code runs, all type variables ought to
// be fully resolved.
@@ -619,7 +619,8 @@ fn reject_fn_ptr_impls(
continue;
}
match obligation.self_ty().skip_binder().kind() {
let self_ty = obligation.self_ty().skip_binder();
match self_ty.kind() {
// Fast path to avoid evaluating an obligation that trivially holds.
// There may be more bounds, but these are checked by the regular path.
ty::FnPtr(..) => return false,
@@ -651,6 +652,7 @@ fn reject_fn_ptr_impls(
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_)
| ty::Never
| ty::Tuple(_)
| ty::Error(_) => return true,
@@ -794,7 +796,8 @@ fn assemble_candidates_from_auto_impls(
| ty::Coroutine(..)
| ty::Never
| ty::Tuple(_)
| ty::CoroutineWitness(..) => {
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_) => {
// Only consider auto impls of unsafe traits when there are
// no unsafe fields.
if self.tcx().trait_is_unsafe(def_id) && self_ty.has_unsafe_fields() {
@@ -1176,6 +1179,7 @@ fn assemble_candidate_for_tuple(
| ty::FnDef(_, _)
| ty::Pat(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -1220,6 +1224,7 @@ fn assemble_candidates_for_fn_ptr_trait(
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_)
| ty::Never
| ty::Tuple(..)
| ty::Alias(..)
@@ -2095,6 +2095,9 @@ fn sized_conditions(
}
}
// FIXME(unsafe_binders): This binder needs to be squashed
ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])),
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None,
ty::Infer(ty::TyVar(_)) => Ambiguous,
@@ -2133,6 +2136,10 @@ fn copy_clone_conditions(
None
}
// FIXME(unsafe_binder): Should we conditionally
// (i.e. universally) implement copy/clone?
ty::UnsafeBinder(_) => None,
ty::Dynamic(..)
| ty::Str
| ty::Slice(..)
@@ -2285,6 +2292,9 @@ fn constituent_types_for_ty(
| ty::Never
| ty::Char => ty::Binder::dummy(Vec::new()),
// FIXME(unsafe_binders): Squash the double binder for now, I guess.
ty::UnsafeBinder(_) => return Err(SelectionError::Unimplemented),
// Treat this like `struct str([u8]);`
ty::Str => ty::Binder::dummy(vec![Ty::new_slice(self.tcx(), self.tcx().types.u8)]),
@@ -828,6 +828,9 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
// Let the visitor iterate into the argument/return
// types appearing in the fn signature.
}
ty::UnsafeBinder(_) => {
// FIXME(unsafe_binders): We should also recurse into the binder here.
}
ty::Dynamic(data, r, _) => {
// WfObject
+2 -1
View File
@@ -49,7 +49,8 @@ fn resolve_instance_raw<'tcx>(
| ty::Adt(..)
| ty::Dynamic(..)
| ty::Array(..)
| ty::Slice(..) => {}
| ty::Slice(..)
| ty::UnsafeBinder(..) => {}
// Drop shims can only be built from ADTs.
_ => return Ok(None),
}
+5
View File
@@ -666,6 +666,11 @@ fn layout_of_uncached<'tcx>(
tcx.mk_layout(layout)
}
ty::UnsafeBinder(bound_ty) => {
let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
cx.layout_of(ty)?.layout
}
// Types with no meaningful known layout.
ty::Alias(..) => {
// NOTE(eddyb) `layout_of` query should've normalized these away,
@@ -202,6 +202,11 @@ fn next(&mut self) -> Option<NeedsDropResult<Ty<'tcx>>> {
}
}
ty::UnsafeBinder(bound_ty) => {
let ty = self.tcx.instantiate_bound_regions_with_erased(bound_ty.into());
queue_type(self, ty);
}
_ if tcx.type_is_copy_modulo_regions(self.typing_env, component) => {}
ty::Closure(_, args) => {
+2
View File
@@ -37,6 +37,8 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'
| Never
| Dynamic(_, _, ty::DynStar) => None,
UnsafeBinder(_) => todo!(),
// these are never sized
Str | Slice(..) | Dynamic(_, _, ty::Dyn) | Foreign(..) => Some(ty),
+3 -5
View File
@@ -6,8 +6,6 @@
use derive_where::derive_where;
#[cfg(feature = "nightly")]
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
#[cfg(feature = "nightly")]
use rustc_serialize::Decodable;
use tracing::instrument;
use crate::data_structures::SsoHashSet;
@@ -69,14 +67,14 @@ fn encode(&self, e: &mut E) {
self.as_ref().skip_binder().encode(e);
}
}
impl<I: Interner, D: crate::TyDecoder<I = I>> Decodable<D> for ty::Binder<I, $t>
impl<I: Interner, D: crate::TyDecoder<I = I>> rustc_serialize::Decodable<D> for ty::Binder<I, $t>
where
$t: TypeVisitable<I> + rustc_serialize::Decodable<D>,
I::BoundVarKinds: rustc_serialize::Decodable<D>,
{
fn decode(decoder: &mut D) -> Self {
let bound_vars = Decodable::decode(decoder);
ty::Binder::bind_with_vars(<$t>::decode(decoder), bound_vars)
let bound_vars = rustc_serialize::Decodable::decode(decoder);
ty::Binder::bind_with_vars(rustc_serialize::Decodable::decode(decoder), bound_vars)
}
}
)*
+11 -1
View File
@@ -41,6 +41,7 @@ pub enum SimplifiedType<DefId> {
Coroutine(DefId),
CoroutineWitness(DefId),
Function(usize),
UnsafeBinder,
Placeholder,
Error,
}
@@ -138,6 +139,7 @@ pub fn simplify_type<I: Interner>(
ty::FnPtr(sig_tys, _hdr) => {
Some(SimplifiedType::Function(sig_tys.skip_binder().inputs().len()))
}
ty::UnsafeBinder(_) => Some(SimplifiedType::UnsafeBinder),
ty::Placeholder(..) => Some(SimplifiedType::Placeholder),
ty::Param(_) => match treat_params {
TreatParams::AsRigid => Some(SimplifiedType::Placeholder),
@@ -290,7 +292,8 @@ fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool {
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Foreign(_)
| ty::Placeholder(_) => {}
| ty::Placeholder(_)
| ty::UnsafeBinder(_) => {}
};
// The type system needs to support exponentially large types
@@ -447,6 +450,13 @@ fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool {
matches!(rhs.kind(), ty::Pat(rhs_ty, _) if self.types_may_unify_inner(lhs_ty, rhs_ty, depth))
}
ty::UnsafeBinder(lhs_ty) => match rhs.kind() {
ty::UnsafeBinder(rhs_ty) => {
self.types_may_unify(lhs_ty.skip_binder(), rhs_ty.skip_binder())
}
_ => false,
},
ty::Error(..) => true,
}
}
+3
View File
@@ -112,6 +112,8 @@ fn new_tup_from_iter<It, T>(interner: I, iter: It) -> T::Output
fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self;
fn new_unsafe_binder(interner: I, ty: ty::Binder<I, I::Ty>) -> Self;
fn tuple_fields(self) -> I::Tys;
fn to_opt_closure_kind(self) -> Option<ty::ClosureKind>;
@@ -185,6 +187,7 @@ fn is_known_rigid(self) -> bool {
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Closure(_, _)
| ty::CoroutineClosure(_, _)
+1
View File
@@ -202,6 +202,7 @@ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Tuple(_) => {
ty.super_visit_with(self);
+4
View File
@@ -549,6 +549,10 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
Ok(Ty::new_pat(cx, ty, pat))
}
(ty::UnsafeBinder(a_binder), ty::UnsafeBinder(b_binder)) => {
Ok(Ty::new_unsafe_binder(cx, relation.binders(*a_binder, *b_binder)?))
}
_ => Err(TypeError::Sorts(ExpectedFound::new(a, b))),
}
}
+71
View File
@@ -1,4 +1,5 @@
use std::fmt;
use std::ops::Deref;
use derive_where::derive_where;
use rustc_ast_ir::Mutability;
@@ -13,6 +14,7 @@
use self::TyKind::*;
pub use self::closure::*;
use crate::inherent::*;
use crate::visit::TypeVisitable;
use crate::{self as ty, DebruijnIndex, Interner};
mod closure;
@@ -150,6 +152,13 @@ pub enum TyKind<I: Interner> {
/// worth the mild inconvenience.
FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
/// An unsafe binder type.
///
/// A higher-ranked type used to represent a type which has had some of its
/// lifetimes erased. This can be used to represent types in positions where
/// a lifetime is literally inexpressible, such as self-referential types.
UnsafeBinder(UnsafeBinderInner<I>),
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
@@ -287,6 +296,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
// FIXME(unsafe_binder): print this like `unsafe<'a> T<'a>`.
UnsafeBinder(binder) => write!(f, "{:?}", binder),
Dynamic(p, r, repr) => match repr {
DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
@@ -964,6 +975,66 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
// FIXME: this is a distinct type because we need to define `Encode`/`Decode`
// impls in this crate for `Binder<I, I::Ty>`.
#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
fn from(value: ty::Binder<I, I::Ty>) -> Self {
UnsafeBinderInner(value)
}
}
impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
fn from(value: UnsafeBinderInner<I>) -> Self {
value.0
}
}
impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<I: Interner> Deref for UnsafeBinderInner<I> {
type Target = ty::Binder<I, I::Ty>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg(feature = "nightly")]
impl<I: Interner, E: crate::TyEncoder<I = I>> rustc_serialize::Encodable<E> for UnsafeBinderInner<I>
where
I::Ty: rustc_serialize::Encodable<E>,
I::BoundVarKinds: rustc_serialize::Encodable<E>,
{
fn encode(&self, e: &mut E) {
self.bound_vars().encode(e);
self.as_ref().skip_binder().encode(e);
}
}
#[cfg(feature = "nightly")]
impl<I: Interner, D: crate::TyDecoder<I = I>> rustc_serialize::Decodable<D> for UnsafeBinderInner<I>
where
I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
I::BoundVarKinds: rustc_serialize::Decodable<D>,
{
fn decode(decoder: &mut D) -> Self {
let bound_vars = rustc_serialize::Decodable::decode(decoder);
UnsafeBinderInner(ty::Binder::bind_with_vars(
rustc_serialize::Decodable::decode(decoder),
bound_vars,
))
}
}
// This is just a `FnSig` without the `FnHeader` fields.
#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
+2
View File
@@ -2255,12 +2255,14 @@ pub(crate) fn clean_middle_ty<'tcx>(
}
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"),
ty::Closure(..) => panic!("Closure"),
ty::CoroutineClosure(..) => panic!("CoroutineClosure"),
ty::Coroutine(..) => panic!("Coroutine"),
ty::Placeholder(..) => panic!("Placeholder"),
ty::CoroutineWitness(..) => panic!("CoroutineWitness"),
ty::Infer(..) => panic!("Infer"),
ty::Error(_) => FatalError.raise(),
}
}
@@ -559,6 +559,7 @@ fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> {
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Dynamic(..)
| ty::UnsafeBinder(_)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(_)
@@ -877,7 +877,8 @@ fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, def_site_def_id: Option<DefId>, ty: Ty<'t
| ty::CoroutineClosure(..)
| ty::Never
| ty::Tuple(_)
| ty::Alias(ty::Projection, _) => Self::Deref,
| ty::Alias(ty::Projection, _)
| ty::UnsafeBinder(_) => Self::Deref,
};
}
}
@@ -677,6 +677,9 @@ fn helper<'tcx, B>(
ExprKind::Type(e, _) => {
helper(typeck, consume, e, f)?;
},
ExprKind::UnsafeBinderCast(_, e, _) => {
helper(typeck, consume, e, f)?;
},
// Either drops temporaries, jumps out of the current expression, or has no sub expression.
ExprKind::DropTemps(_)
@@ -694,7 +697,6 @@ fn helper<'tcx, B>(
| ExprKind::Continue(_)
| ExprKind::InlineAsm(_)
| ExprKind::OffsetOf(..)
| ExprKind::UnsafeBinderCast(..)
| ExprKind::Err(_) => (),
}
ControlFlow::Continue(())
+1 -1
View File
@@ -37,7 +37,7 @@
// Const generic parameter
// gdb-command:info functions -q function_names::const_generic_fn.*
// gdb-check:[...]static fn function_names::const_generic_fn_bool<false>();
// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#a70c39591cb5f53d}>();
// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#ffa3db4ca1d52dce}>();
// gdb-check:[...]static fn function_names::const_generic_fn_signed_int<-7>();
// gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int<14>();
@@ -13,34 +13,8 @@ fn main() {
let kind = TyKind::Bool; //~ ERROR usage of `ty::TyKind::<kind>`
match kind {
TyKind::Bool => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Char => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Int(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Uint(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Float(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Adt(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Foreign(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Str => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Array(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Pat(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Slice(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::RawPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Ref(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::FnDef(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::FnPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Dynamic(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Closure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::CoroutineClosure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Coroutine(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::CoroutineWitness(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Never => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Tuple(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Alias(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Param(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Bound(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Placeholder(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Infer(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Error(_) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Bool => {}, //~ ERROR usage of `ty::TyKind::<kind>`
_ => {}
}
if let ty::Int(int_ty) = kind {}
@@ -13,179 +13,17 @@ LL | #[deny(rustc::usage_of_ty_tykind)]
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:16:9
|
LL | TyKind::Bool => (),
LL | TyKind::Bool => {},
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:17:9
|
LL | TyKind::Char => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:18:9
|
LL | TyKind::Int(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:19:9
|
LL | TyKind::Uint(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:20:9
|
LL | TyKind::Float(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:21:9
|
LL | TyKind::Adt(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:22:9
|
LL | TyKind::Foreign(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:23:9
|
LL | TyKind::Str => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:24:9
|
LL | TyKind::Array(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:25:9
|
LL | TyKind::Pat(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:26:9
|
LL | TyKind::Slice(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:27:9
|
LL | TyKind::RawPtr(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:28:9
|
LL | TyKind::Ref(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:29:9
|
LL | TyKind::FnDef(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:30:9
|
LL | TyKind::FnPtr(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:31:9
|
LL | TyKind::Dynamic(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:32:9
|
LL | TyKind::Closure(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:33:9
|
LL | TyKind::CoroutineClosure(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:34:9
|
LL | TyKind::Coroutine(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:35:9
|
LL | TyKind::CoroutineWitness(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:36:9
|
LL | TyKind::Never => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:37:9
|
LL | TyKind::Tuple(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:38:9
|
LL | TyKind::Alias(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:39:9
|
LL | TyKind::Param(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:40:9
|
LL | TyKind::Bound(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:41:9
|
LL | TyKind::Placeholder(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:42:9
|
LL | TyKind::Infer(..) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:43:9
|
LL | TyKind::Error(_) => (),
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:48:12
--> $DIR/ty_tykind_usage.rs:22:12
|
LL | if let TyKind::Int(int_ty) = kind {}
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
error: usage of `ty::TyKind`
--> $DIR/ty_tykind_usage.rs:50:24
--> $DIR/ty_tykind_usage.rs:24:24
|
LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
| ^^^^^^^^^^
@@ -193,7 +31,7 @@ LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
= help: try using `Ty` instead
error: usage of `ty::TyKind`
--> $DIR/ty_tykind_usage.rs:52:37
--> $DIR/ty_tykind_usage.rs:26:37
|
LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
| ^^^^^^^^^^^
@@ -201,7 +39,7 @@ LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
= help: try using `Ty` instead
error: usage of `ty::TyKind`
--> $DIR/ty_tykind_usage.rs:52:53
--> $DIR/ty_tykind_usage.rs:26:53
|
LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
| ^^^^^^^^^^^
@@ -209,12 +47,12 @@ LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
= help: try using `Ty` instead
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:55:9
--> $DIR/ty_tykind_usage.rs:29:9
|
LL | IrTyKind::Bool
| --------^^^^^^
| |
| help: try using `ty::<kind>` directly: `ty`
error: aborting due to 34 previous errors
error: aborting due to 7 previous errors
@@ -7,6 +7,6 @@
//~^ ERROR auto traits are experimental and possibly buggy
impl !AutoDummyTrait for DummyStruct {}
//~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
//~^ ERROR negative trait bounds are not fully implemented; use marker types for now
fn main() {}
@@ -8,7 +8,7 @@ LL | auto trait AutoDummyTrait {}
= help: add `#![feature(auto_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
error[E0658]: negative trait bounds are not fully implemented; use marker types for now
--> $DIR/feature-gate-auto-traits.rs:9:6
|
LL | impl !AutoDummyTrait for DummyStruct {}
+2 -2
View File
@@ -1,10 +1,10 @@
error: symbol-name(_ZN5basic4main17had874e876c8b1028E)
error: symbol-name(_ZN5basic4main17h144191e1523a280eE)
--> $DIR/basic.rs:8:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(basic::main::had874e876c8b1028)
error: demangling(basic::main::h144191e1523a280e)
--> $DIR/basic.rs:8:1
|
LL | #[rustc_symbol_name]
@@ -1,10 +1,10 @@
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17haf0d0ad2255e29c6E)
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h71f988fda3b6b180E)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::haf0d0ad2255e29c6)
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h71f988fda3b6b180)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]
@@ -1,3 +1,3 @@
trait MyTrait {}
impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented
impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not fully implemented
fn main() {}
@@ -1,4 +1,4 @@
error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
error[E0658]: negative trait bounds are not fully implemented; use marker types for now
--> $DIR/feature-gate-negative_impls.rs:2:6
|
LL | impl !MyTrait for u32 {}
+6 -5
View File
@@ -4,10 +4,11 @@
use std::unsafe_binder::{wrap_binder, unwrap_binder};
fn main() {
unsafe {
let x = 1;
let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
//~^ ERROR unsafe binders are not yet implemented
//~| ERROR unsafe binders are not yet implemented
let rx = *unwrap_binder!(binder);
//~^ ERROR unsafe binders are not yet implemented
let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
//~^ ERROR unsafe binder casts are not fully implemented
let rx = *unwrap_binder!(binder);
//~^ ERROR unsafe binder casts are not fully implemented
}
}
+9 -15
View File
@@ -7,23 +7,17 @@ LL | #![feature(unsafe_binders)]
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
= note: `#[warn(incomplete_features)]` on by default
error: unsafe binders are not yet implemented
--> $DIR/expr.rs:8:17
error: unsafe binder casts are not fully implemented
--> $DIR/expr.rs:9:55
|
LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
| ^^^^^^^^^^^^^^^^^^
LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
| ^^
error: unsafe binders are not yet implemented
--> $DIR/expr.rs:8:51
error: unsafe binder casts are not fully implemented
--> $DIR/expr.rs:11:34
|
LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
| ^
LL | let rx = *unwrap_binder!(binder);
| ^^^^^^
error: unsafe binders are not yet implemented
--> $DIR/expr.rs:11:30
|
LL | let rx = *unwrap_binder!(binder);
| ^^^^^^
error: aborting due to 3 previous errors; 1 warning emitted
error: aborting due to 2 previous errors; 1 warning emitted
@@ -3,16 +3,13 @@
fn foo<'a>() {
let good: unsafe<'b> &'a &'b ();
//~^ ERROR unsafe binders are not yet implemented
let missing: unsafe<> &'missing ();
//~^ ERROR unsafe binders are not yet implemented
//~| ERROR use of undeclared lifetime name `'missing`
//~^ ERROR use of undeclared lifetime name `'missing`
fn inner<'b>() {
let outer: unsafe<> &'a &'b ();
//~^ ERROR unsafe binders are not yet implemented
//~| can't use generic parameters from outer item
//~^ can't use generic parameters from outer item
}
}
@@ -1,5 +1,5 @@
error[E0261]: use of undeclared lifetime name `'missing`
--> $DIR/lifetime-resolution.rs:8:28
--> $DIR/lifetime-resolution.rs:7:28
|
LL | let missing: unsafe<> &'missing ();
| ^^^^^^^^ undeclared lifetime
@@ -15,7 +15,7 @@ LL | fn foo<'missing, 'a>() {
| +++++++++
error[E0401]: can't use generic parameters from outer item
--> $DIR/lifetime-resolution.rs:13:30
--> $DIR/lifetime-resolution.rs:11:30
|
LL | fn foo<'a>() {
| -- lifetime parameter from outer item
@@ -41,25 +41,7 @@ LL | #![feature(unsafe_binders)]
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
= note: `#[warn(incomplete_features)]` on by default
error: unsafe binders are not yet implemented
--> $DIR/lifetime-resolution.rs:5:15
|
LL | let good: unsafe<'b> &'a &'b ();
| ^^^^^^^^^^^^^^^^^^^^^
error: unsafe binders are not yet implemented
--> $DIR/lifetime-resolution.rs:8:18
|
LL | let missing: unsafe<> &'missing ();
| ^^^^^^^^^^^^^^^^^^^^^
error: unsafe binders are not yet implemented
--> $DIR/lifetime-resolution.rs:13:20
|
LL | let outer: unsafe<> &'a &'b ();
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors; 1 warning emitted
error: aborting due to 2 previous errors; 1 warning emitted
Some errors have detailed explanations: E0261, E0401.
For more information about an error, try `rustc --explain E0261`.
+43
View File
@@ -0,0 +1,43 @@
#![feature(unsafe_binders)]
//~^ WARN the feature `unsafe_binders` is incomplete
use std::unsafe_binder::{wrap_binder, unwrap_binder};
fn a() {
let _: unsafe<'a> &'a i32 = wrap_binder!(&());
//~^ ERROR unsafe binder casts are not fully implemented
//~| ERROR mismatched types
}
fn b() {
let _: i32 = wrap_binder!(&());
//~^ ERROR unsafe binder casts are not fully implemented
//~| ERROR `wrap_binder!()` can only wrap into unsafe binder
}
fn c() {
let y = 1;
unwrap_binder!(y);
//~^ ERROR unsafe binder casts are not fully implemented
//~| ERROR expected unsafe binder, found integer as input
}
fn d() {
let unknown = Default::default();
unwrap_binder!(unknown);
//~^ ERROR unsafe binder casts are not fully implemented
// FIXME(unsafe_binders): This should report ambiguity once we've removed
// the error above which taints the infcx.
}
fn e() {
let x = wrap_binder!(&42);
//~^ ERROR unsafe binder casts are not fully implemented
// Currently, type inference doesn't flow backwards for unsafe binders.
// It could, perhaps, but that may cause even more surprising corners.
// FIXME(unsafe_binders): This should report ambiguity once we've removed
// the error above which taints the infcx.
let _: unsafe<'a> &'a i32 = x;
}
fn main() {}
+68
View File
@@ -0,0 +1,68 @@
warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/mismatch.rs:1:12
|
LL | #![feature(unsafe_binders)]
| ^^^^^^^^^^^^^^
|
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
= note: `#[warn(incomplete_features)]` on by default
error: unsafe binder casts are not fully implemented
--> $DIR/mismatch.rs:7:46
|
LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&());
| ^^^
error[E0308]: mismatched types
--> $DIR/mismatch.rs:7:46
|
LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&());
| ^^^ expected `&i32`, found `&()`
|
= note: expected reference `&i32`
found reference `&()`
error: unsafe binder casts are not fully implemented
--> $DIR/mismatch.rs:13:31
|
LL | let _: i32 = wrap_binder!(&());
| ^^^
error: `wrap_binder!()` can only wrap into unsafe binder, not `i32`
--> $DIR/mismatch.rs:13:18
|
LL | let _: i32 = wrap_binder!(&());
| ^^^^^^^^^^^^^^^^^
|
= note: unsafe binders are the only valid output of wrap
= note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe binder casts are not fully implemented
--> $DIR/mismatch.rs:20:20
|
LL | unwrap_binder!(y);
| ^
error: expected unsafe binder, found integer as input of `unwrap_binder!()`
--> $DIR/mismatch.rs:20:20
|
LL | unwrap_binder!(y);
| ^
|
= note: only an unsafe binder type can be unwrapped
error: unsafe binder casts are not fully implemented
--> $DIR/mismatch.rs:27:20
|
LL | unwrap_binder!(unknown);
| ^^^^^^^
error: unsafe binder casts are not fully implemented
--> $DIR/mismatch.rs:34:26
|
LL | let x = wrap_binder!(&42);
| ^^^
error: aborting due to 8 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0308`.
+2 -1
View File
@@ -1,7 +1,8 @@
//@ check-pass
#![feature(unsafe_binders)]
//~^ WARN the feature `unsafe_binders` is incomplete
fn main() {
let x: unsafe<'a> &'a ();
//~^ ERROR unsafe binders are not yet implemented
}
+2 -8
View File
@@ -1,5 +1,5 @@
warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/simple.rs:1:12
--> $DIR/simple.rs:3:12
|
LL | #![feature(unsafe_binders)]
| ^^^^^^^^^^^^^^
@@ -7,11 +7,5 @@ LL | #![feature(unsafe_binders)]
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
= note: `#[warn(incomplete_features)]` on by default
error: unsafe binders are not yet implemented
--> $DIR/simple.rs:5:12
|
LL | let x: unsafe<'a> &'a ();
| ^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error; 1 warning emitted
warning: 1 warning emitted