Actually create ranged int types in the type system.

This commit is contained in:
Oli Scherer 2023-02-02 13:57:36 +00:00
parent 6b24a9cf70
commit 84acfe86de
97 changed files with 1208 additions and 77 deletions

View file

@ -363,6 +363,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
@ -596,6 +597,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
@ -684,6 +686,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)

View file

@ -50,7 +50,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
Ok(vec![ty::Binder::dummy(element_ty)])
}
ty::Array(element_ty, _) | ty::Slice(element_ty) => Ok(vec![ty::Binder::dummy(element_ty)]),
ty::Pat(element_ty, _) | ty::Array(element_ty, _) | ty::Slice(element_ty) => {
Ok(vec![ty::Binder::dummy(element_ty)])
}
ty::Tuple(tys) => {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
@ -114,6 +116,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Array(..)
| ty::Pat(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Never
@ -177,6 +180,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
| ty::Ref(_, _, Mutability::Not)
| ty::Array(..) => Err(NoSolution),
// Cannot implement in core, as we can't be generic over patterns yet,
// so we'd have to list all patterns and type combinations.
ty::Pat(ty, ..) => Ok(vec![ty::Binder::dummy(ty)]),
ty::Dynamic(..)
| ty::Str
| ty::Slice(_)
@ -347,6 +354,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::Pat(_, _)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Placeholder(..)
@ -526,6 +534,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)

View file

@ -533,6 +533,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
| ty::Uint(..)
| ty::Float(..)
| ty::Array(..)
| ty::Pat(..)
| ty::RawPtr(..)
| ty::Ref(..)
| ty::FnDef(..)
@ -768,6 +769,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
| ty::Uint(..)
| ty::Float(..)
| ty::Array(..)
| ty::Pat(..)
| ty::RawPtr(..)
| ty::Ref(..)
| ty::FnDef(..)

View file

@ -1051,6 +1051,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Float(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)

View file

@ -883,6 +883,7 @@ where
| ty::Float(..)
| ty::Str
| ty::FnDef(..)
| ty::Pat(..)
| ty::FnPtr(_)
| ty::Array(..)
| ty::Slice(..)

View file

@ -1804,6 +1804,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ty::Foreign(..) => Some(19),
ty::CoroutineWitness(..) => Some(20),
ty::CoroutineClosure(..) => Some(21),
ty::Pat(..) => Some(22),
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
}
}

View file

@ -1048,6 +1048,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Foreign(_)
| ty::Str
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::RawPtr(..)
| ty::Ref(..)
@ -1099,6 +1100,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Float(_)
| ty::Str
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::RawPtr(..)
| ty::Ref(..)

View file

@ -42,8 +42,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
| ty::Foreign(..)
| ty::Error(_) => true,
// [T; N] and [T] have same properties as T.
ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, *ty),
// `T is PAT`, `[T; N]`, and `[T]` have same properties as T.
ty::Pat(ty, _) | ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, *ty),
// (T1..Tn) and closures have same properties as T1..Tn --
// check if *all* of them are trivial.
@ -222,7 +222,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
// these types never have a destructor
}
ty::Array(ety, _) | ty::Slice(ety) => {
ty::Pat(ety, _) | ty::Array(ety, _) | ty::Slice(ety) => {
// single-element containers, behave like their element
rustc_data_structures::stack::ensure_sufficient_stack(|| {
dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, *ety, constraints)

View file

@ -670,6 +670,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
@ -803,6 +804,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Float(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::Adt(..)
| ty::RawPtr(_, _)
@ -1193,6 +1195,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Never
| ty::Foreign(_)
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@ -1270,6 +1273,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::Pat(_, _)
| ty::FnPtr(_)
| ty::Dynamic(_, _, _)
| ty::Closure(..)
@ -1329,6 +1333,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Foreign(..)
| ty::Str
| ty::Array(..)
| ty::Pat(..)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(..)

View file

@ -1417,7 +1417,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// These types are built-in, so we can fast-track by registering
// nested predicates for their constituent type(s)
ty::Array(ty, _) | ty::Slice(ty) => {
ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => {
stack.push(ty);
}
ty::Tuple(tys) => {
@ -1469,7 +1469,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If we have any other type (e.g. an ADT), just register a nested obligation
// since it's either not `const Drop` (and we raise an error during selection),
// or it's an ADT (and we need to check for a custom impl during selection)
_ => {
ty::Error(_)
| ty::Dynamic(..)
| ty::CoroutineClosure(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Adt(..)
| ty::Alias(ty::Opaque | ty::Weak, _)
| ty::Infer(_)
| ty::Placeholder(_) => {
let predicate = self_ty.rebind(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
self.tcx(),

View file

@ -2142,6 +2142,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
),
ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])),
ty::Adt(def, args) => {
if let Some(sized_crit) = def.sized_constraint(self.tcx()) {
// (*) binder moved here
@ -2202,6 +2204,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
Where(obligation.predicate.rebind(tys.iter().collect()))
}
ty::Pat(ty, _) => {
// (*) binder moved here
Where(obligation.predicate.rebind(vec![ty]))
}
ty::Coroutine(coroutine_def_id, args) => {
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => None,
@ -2340,7 +2347,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
ty::RawPtr(element_ty, _) | ty::Ref(_, element_ty, _) => t.rebind(vec![element_ty]),
ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]),
ty::Pat(ty, _) | ty::Array(ty, _) | ty::Slice(ty) => t.rebind(vec![ty]),
ty::Tuple(tys) => {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet

View file

@ -126,7 +126,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
return ControlFlow::Continue(());
}
ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
ty::Pat(..) | ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
// First check all contained types and then tell the caller to continue searching.
return ty.super_visit_with(self);
}

View file

@ -681,6 +681,10 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
// Note that we handle the len is implicitly checked while walking `arg`.
}
ty::Pat(subty, _) => {
self.require_sized(subty, traits::MiscObligation);
}
ty::Tuple(tys) => {
if let Some((_last, rest)) = tys.split_last() {
for &elem in rest {