about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-21 17:05:40 +0000
committerMichael Goulet <michael@errs.io>2024-12-22 21:57:57 +0000
commit9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3 (patch)
tree02737d1b8386b3d999cbd1778e315b539f2f6826 /compiler/rustc_trait_selection
parentb22856d192567a55a1d2788fbc3084e3f9cb220f (diff)
downloadrust-9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3.tar.gz
rust-9a1c5eb5b385adb3cd04af0049cbf5c225cefdc3.zip
Begin to implement type system layer of unsafe binders
Diffstat (limited to 'compiler/rustc_trait_selection')
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs3
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