Skip to content

Commit 69890b2

Browse files
trait solver: PointerSized
1 parent f53f5b4 commit 69890b2

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

compiler/rustc_trait_selection/src/solve/assembly.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
117117
ecx: &mut EvalCtxt<'_, 'tcx>,
118118
goal: Goal<'tcx, Self>,
119119
) -> QueryResult<'tcx>;
120+
121+
fn consider_builtin_pointer_sized_candidate(
122+
ecx: &mut EvalCtxt<'_, 'tcx>,
123+
goal: Goal<'tcx, Self>,
124+
) -> QueryResult<'tcx>;
120125
}
121126

122127
impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -237,6 +242,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
237242
|| lang_items.clone_trait() == Some(trait_def_id)
238243
{
239244
G::consider_builtin_copy_clone_candidate(self, goal)
245+
} else if lang_items.pointer_sized() == Some(trait_def_id) {
246+
G::consider_builtin_pointer_sized_candidate(self, goal)
240247
} else {
241248
Err(NoSolution)
242249
};

compiler/rustc_trait_selection/src/solve/project_goals.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
351351
) -> QueryResult<'tcx> {
352352
bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
353353
}
354+
355+
fn consider_builtin_pointer_sized_candidate(
356+
ecx: &mut EvalCtxt<'_, 'tcx>,
357+
goal: Goal<'tcx, Self>,
358+
) -> QueryResult<'tcx> {
359+
bug!("`PointerSized` does not have an associated type: {:?}", goal);
360+
}
354361
}
355362

356363
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.

compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ use std::iter;
44

55
use super::assembly::{self, Candidate, CandidateSource};
66
use super::infcx_ext::InferCtxtExt;
7-
use super::{EvalCtxt, Goal, QueryResult};
7+
use super::{Certainty, EvalCtxt, Goal, QueryResult};
88
use rustc_hir::def_id::DefId;
99
use rustc_infer::infer::InferCtxt;
1010
use rustc_infer::traits::query::NoSolution;
1111
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
12-
use rustc_middle::ty::TraitPredicate;
1312
use rustc_middle::ty::{self, Ty, TyCtxt};
13+
use rustc_middle::ty::{TraitPredicate, TypeVisitable};
1414
use rustc_span::DUMMY_SP;
1515

1616
mod structural_traits;
@@ -127,6 +127,29 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
127127
structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
128128
)
129129
}
130+
131+
fn consider_builtin_pointer_sized_candidate(
132+
ecx: &mut EvalCtxt<'_, 'tcx>,
133+
goal: Goal<'tcx, Self>,
134+
) -> QueryResult<'tcx> {
135+
if goal.predicate.self_ty().has_non_region_infer() {
136+
return ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
137+
}
138+
139+
let tcx = ecx.tcx();
140+
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
141+
142+
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
143+
&& let usize_layout = tcx.layout_of(ty::ParamEnv::empty().and(tcx.types.usize)).unwrap().layout
144+
&& layout.layout.size() == usize_layout.size()
145+
&& layout.layout.align().abi == usize_layout.align().abi
146+
{
147+
// FIXME: We could make this faster by making a no-constraints response
148+
ecx.make_canonical_response(Certainty::Yes)
149+
} else {
150+
Err(NoSolution)
151+
}
152+
}
130153
}
131154

132155
impl<'tcx> EvalCtxt<'_, 'tcx> {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(pointer_sized_trait)]
2+
3+
use std::marker::PointerSized;
4+
5+
fn require_pointer_sized(_: impl PointerSized) {}
6+
7+
fn main() {
8+
require_pointer_sized(1usize);
9+
require_pointer_sized(1u16);
10+
//~^ ERROR `u16` needs to be a pointer-sized type
11+
require_pointer_sized(&1i16);
12+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0277]: `u16` needs to be a pointer-sized type
2+
--> $DIR/pointer-sized.rs:9:27
3+
|
4+
LL | require_pointer_sized(1u16);
5+
| --------------------- ^^^^ the trait `PointerSized` is not implemented for `u16`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= note: the trait bound `u16: PointerSized` is not satisfied
10+
note: required by a bound in `require_pointer_sized`
11+
--> $DIR/pointer-sized.rs:5:34
12+
|
13+
LL | fn require_pointer_sized(_: impl PointerSized) {}
14+
| ^^^^^^^^^^^^ required by this bound in `require_pointer_sized`
15+
help: consider borrowing here
16+
|
17+
LL | require_pointer_sized(&1u16);
18+
| +
19+
LL | require_pointer_sized(&mut 1u16);
20+
| ++++
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)