diff options
| author | Michael Goulet <michael@errs.io> | 2024-12-21 17:05:40 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-12-22 21:57:57 +0000 |
| commit | 9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3 (patch) | |
| tree | 02737d1b8386b3d999cbd1778e315b539f2f6826 /compiler/rustc_trait_selection | |
| parent | b22856d192567a55a1d2788fbc3084e3f9cb220f (diff) | |
| download | rust-9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3.tar.gz rust-9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3.zip | |
Begin to implement type system layer of unsafe binders
Diffstat (limited to 'compiler/rustc_trait_selection')
6 files changed, 33 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d41f8f46c17..885b606326c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1532,6 +1532,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { 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, } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4bccd3450bc..54407d17dcf 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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(..) diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 1d3e8d43af7..4004e354dc1 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -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. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 5e27fd43789..d6ac4baf8ad 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -619,7 +619,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(_, _) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) | ty::Error(_) => return true, @@ -794,7 +796,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::FnDef(_, _) | ty::Pat(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(_, _, _) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -1220,6 +1224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(..) | ty::Alias(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0462b1d9ee7..7857ed95cc7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2095,6 +2095,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } + // 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 @@ impl<'tcx> SelectionContext<'_, 'tcx> { 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 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | 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)]), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index c95b1641d1f..9d32eb05386 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -828,6 +828,9 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> { // 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 |
