about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-18 23:21:12 +0000
committerMichael Goulet <michael@errs.io>2023-01-19 16:15:28 +0000
commit69890b2df447e7d3febff1a0f8974f3fcf694128 (patch)
treecabafd2f5e65c53043f0ab1dfab0fdd00007a625
parentf53f5b4463a28b44d036342f0a849390495f6a9b (diff)
downloadrust-69890b2df447e7d3febff1a0f8974f3fcf694128.tar.gz
rust-69890b2df447e7d3febff1a0f8974f3fcf694128.zip
trait solver: PointerSized
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs27
-rw-r--r--tests/ui/traits/new-solver/pointer-sized.rs12
-rw-r--r--tests/ui/traits/new-solver/pointer-sized.stderr24
5 files changed, 75 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index 45bce34b1ed..52155aa0f18 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -117,6 +117,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx>;
+
+    fn consider_builtin_pointer_sized_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx>;
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -237,6 +242,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             || lang_items.clone_trait() == Some(trait_def_id)
         {
             G::consider_builtin_copy_clone_candidate(self, goal)
+        } else if lang_items.pointer_sized() == Some(trait_def_id) {
+            G::consider_builtin_pointer_sized_candidate(self, goal)
         } else {
             Err(NoSolution)
         };
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index ffc1c70e0cb..3f3d32efe7f 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -351,6 +351,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
     ) -> QueryResult<'tcx> {
         bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
     }
+
+    fn consider_builtin_pointer_sized_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        bug!("`PointerSized` does not have an associated type: {:?}", goal);
+    }
 }
 
 /// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 1ebcfd03c14..f68a296922a 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -4,13 +4,13 @@ use std::iter;
 
 use super::assembly::{self, Candidate, CandidateSource};
 use super::infcx_ext::InferCtxtExt;
-use super::{EvalCtxt, Goal, QueryResult};
+use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
-use rustc_middle::ty::TraitPredicate;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{TraitPredicate, TypeVisitable};
 use rustc_span::DUMMY_SP;
 
 mod structural_traits;
@@ -127,6 +127,29 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
         )
     }
+
+    fn consider_builtin_pointer_sized_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        if goal.predicate.self_ty().has_non_region_infer() {
+            return ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
+        }
+
+        let tcx = ecx.tcx();
+        let self_ty = tcx.erase_regions(goal.predicate.self_ty());
+
+        if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
+            &&  let usize_layout = tcx.layout_of(ty::ParamEnv::empty().and(tcx.types.usize)).unwrap().layout
+            && layout.layout.size() == usize_layout.size()
+            && layout.layout.align().abi == usize_layout.align().abi
+        {
+            // FIXME: We could make this faster by making a no-constraints response
+            ecx.make_canonical_response(Certainty::Yes)
+        } else {
+            Err(NoSolution)
+        }
+    }
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
diff --git a/tests/ui/traits/new-solver/pointer-sized.rs b/tests/ui/traits/new-solver/pointer-sized.rs
new file mode 100644
index 00000000000..15681cd132e
--- /dev/null
+++ b/tests/ui/traits/new-solver/pointer-sized.rs
@@ -0,0 +1,12 @@
+#![feature(pointer_sized_trait)]
+
+use std::marker::PointerSized;
+
+fn require_pointer_sized(_: impl PointerSized) {}
+
+fn main() {
+    require_pointer_sized(1usize);
+    require_pointer_sized(1u16);
+    //~^ ERROR `u16` needs to be a pointer-sized type
+    require_pointer_sized(&1i16);
+}
diff --git a/tests/ui/traits/new-solver/pointer-sized.stderr b/tests/ui/traits/new-solver/pointer-sized.stderr
new file mode 100644
index 00000000000..b250b1331bb
--- /dev/null
+++ b/tests/ui/traits/new-solver/pointer-sized.stderr
@@ -0,0 +1,24 @@
+error[E0277]: `u16` needs to be a pointer-sized type
+  --> $DIR/pointer-sized.rs:9:27
+   |
+LL |     require_pointer_sized(1u16);
+   |     --------------------- ^^^^ the trait `PointerSized` is not implemented for `u16`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: the trait bound `u16: PointerSized` is not satisfied
+note: required by a bound in `require_pointer_sized`
+  --> $DIR/pointer-sized.rs:5:34
+   |
+LL | fn require_pointer_sized(_: impl PointerSized) {}
+   |                                  ^^^^^^^^^^^^ required by this bound in `require_pointer_sized`
+help: consider borrowing here
+   |
+LL |     require_pointer_sized(&1u16);
+   |                           +
+LL |     require_pointer_sized(&mut 1u16);
+   |                           ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.