trait solver: PointerSized

This commit is contained in:
Michael Goulet 2023-01-18 23:21:12 +00:00
parent f53f5b4463
commit 69890b2df4
5 changed files with 75 additions and 2 deletions

View File

@ -117,6 +117,11 @@ fn consider_builtin_copy_clone_candidate(
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 @@ fn assemble_builtin_impl_candidates<G: GoalKind<'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)
};

View File

@ -351,6 +351,13 @@ fn consider_builtin_copy_clone_candidate(
) -> 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.

View File

@ -4,13 +4,13 @@
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 @@ fn consider_builtin_copy_clone_candidate(
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> {

View File

@ -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);
}

View File

@ -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`.