Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(&f) => self.pointer_kind(f, span)?,
},

ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// Pointer kind follows the inner type once binder regions are erased,
// matching `discriminant_ty` / other ty queries on unsafe binders.
ty::UnsafeBinder(bound_ty) => {
let inner = self.tcx.instantiate_bound_regions_with_erased((*bound_ty).into());
self.pointer_kind(inner, span)?
}

// Pointers to foreign types are thin, despite being unsized
ty::Foreign(..) => Some(PointerKind::Thin),
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1790,7 +1790,12 @@ impl<'tcx> Ty<'tcx> {
// metadata of `tail`.
ty::Param(_) | ty::Alias(..) => Err(tail),

ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// Metadata of an unsafe binder is the metadata of its inner type
// (regions erased), same as other queries on `UnsafeBinder`.
ty::UnsafeBinder(bound_ty) => {
tcx.instantiate_bound_regions_with_erased((*bound_ty).into())
.ptr_metadata_ty_or_tail(tcx, normalize)
}

ty::Infer(ty::TyVar(_))
| ty::Pat(..)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,8 +1268,8 @@ impl<'tcx> Ty<'tcx> {
| ty::FnDef(..)
| ty::Error(_)
| ty::FnPtr(..) => true,
// FIXME(unsafe_binders):
ty::UnsafeBinder(_) => todo!(),
// Without `TyCtxt` we cannot erase binder regions; be conservative.
ty::UnsafeBinder(_) => false,
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_not_async_drop),
ty::Pat(elem_ty, _) | ty::Slice(elem_ty) | ty::Array(elem_ty, _) => {
elem_ty.is_trivially_not_async_drop()
Expand Down
77 changes: 75 additions & 2 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,40 @@ 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)"),
// DiscriminantKind on unsafe binders follows the inner type (see `discriminant_ty`).
ty::UnsafeBinder(bound_ty) => {
let inner = selcx
.tcx()
.instantiate_bound_regions_with_erased((*bound_ty).into());
match inner.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Adt(..)
| ty::Foreign(_)
| ty::Str
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::RawPtr(..)
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Dynamic(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(..)
| ty::Infer(
ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..),
) => true,
_ => false,
}
}

// type parameters, opaques, and unnormalized projections don't have
// a known discriminant and may need to be normalized further or rely
Expand Down Expand Up @@ -1169,7 +1202,47 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
true
}

ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
// Pointee/metadata of an unsafe binder is that of the inner type.
ty::UnsafeBinder(bound_ty) => {
let inner = selcx
.tcx()
.instantiate_bound_regions_with_erased((*bound_ty).into());
match *inner.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::RawPtr(..)
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Dynamic(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Never
| ty::Foreign(_)
| ty::Adt(..)
| ty::Tuple(..)
| ty::Infer(
ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..),
)
| ty::Error(..) => true,
ty::Param(_) | ty::Alias(..) if self_ty != tail => true,
_ => {
if tail.has_infer_types() {
candidate_set.mark_ambiguous();
}
false
}
}
}

// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
ty::Param(_)
Expand Down