-
Notifications
You must be signed in to change notification settings - Fork 13.8k
clean up Sized
checking
#122493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clean up Sized
checking
#122493
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,7 +128,7 @@ pub(super) trait GoalKind<'tcx>: | |
goal: Goal<'tcx, Self>, | ||
) -> QueryResult<'tcx>; | ||
|
||
/// A type is `Copy` or `Clone` if its components are `Sized`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😊 |
||
/// A type is `Sized` if its tail component is `Sized`. | ||
/// | ||
/// These components are given by built-in rules from | ||
/// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -154,13 +154,24 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( | |||||
bug!("unexpected type `{ty}`") | ||||||
} | ||||||
|
||||||
// impl Sized for (T1, T2, .., Tn) where T1: Sized, T2: Sized, .. Tn: Sized | ||||||
ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()), | ||||||
|
||||||
// impl Sized for Adt where T: Sized forall T in field types | ||||||
// impl Sized for () | ||||||
// impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 | ||||||
ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |&ty| vec![ty::Binder::dummy(ty)])), | ||||||
|
||||||
// impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized | ||||||
// `sized_constraint(Adt)` is the deepest struct trail that can be determined | ||||||
// by the definition of `Adt`, independent of the generic args. | ||||||
// impl Sized for Adt<Args...> if sized_constraint(Adt) == None | ||||||
// As a performance optimization, `sized_constraint(Adt)` can return `None` | ||||||
// if the ADTs definition implies that it is sized by for all possible args. | ||||||
// In this case, the builtin impl will have no nested subgoals. This is a | ||||||
// "best effort" optimization and `sized_constraint` may return `Some`, even | ||||||
// if the ADT is sized for all possible args. | ||||||
ty::Adt(def, args) => { | ||||||
let sized_crit = def.sized_constraint(ecx.tcx()); | ||||||
|
let sized_crit = def.sized_constraint(ecx.tcx()); | |
if let Some(ty) = def.sized_constraint(ecx.tcx()) { |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2120,11 +2120,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | |
ty::Adt(def, args) => { | ||
let sized_crit = def.sized_constraint(self.tcx()); | ||
|
||
// (*) binder moved here | ||
Where( | ||
obligation | ||
.predicate | ||
.rebind(sized_crit.iter_instantiated(self.tcx(), args).collect()), | ||
) | ||
Where(obligation.predicate.rebind( | ||
sized_crit.map_or_else(Vec::new, |ty| vec![ty.instantiate(self.tcx(), args)]), | ||
)) | ||
} | ||
|
||
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -1,78 +1,59 @@ | ||||||||
use rustc_data_structures::fx::FxHashSet; | ||||||||
use rustc_hir as hir; | ||||||||
use rustc_hir::def::DefKind; | ||||||||
use rustc_hir::LangItem; | ||||||||
use rustc_index::bit_set::BitSet; | ||||||||
use rustc_middle::query::Providers; | ||||||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor}; | ||||||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt, TypeVisitor}; | ||||||||
use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable}; | ||||||||
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; | ||||||||
use rustc_span::DUMMY_SP; | ||||||||
use rustc_trait_selection::traits; | ||||||||
|
||||||||
fn sized_constraint_for_ty<'tcx>( | ||||||||
tcx: TyCtxt<'tcx>, | ||||||||
adtdef: ty::AdtDef<'tcx>, | ||||||||
ty: Ty<'tcx>, | ||||||||
) -> Vec<Ty<'tcx>> { | ||||||||
#[instrument(level = "debug", skip(tcx), ret)] | ||||||||
fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { | ||||||||
use rustc_type_ir::TyKind::*; | ||||||||
|
||||||||
let result = match ty.kind() { | ||||||||
Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) | ||||||||
| FnPtr(_) | Array(..) | Closure(..) | CoroutineClosure(..) | Coroutine(..) | Never => { | ||||||||
vec![] | ||||||||
} | ||||||||
|
||||||||
Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | CoroutineWitness(..) => { | ||||||||
// these are never sized - return the target type | ||||||||
vec![ty] | ||||||||
} | ||||||||
|
||||||||
Tuple(tys) => match tys.last() { | ||||||||
None => vec![], | ||||||||
Some(&ty) => sized_constraint_for_ty(tcx, adtdef, ty), | ||||||||
}, | ||||||||
|
||||||||
match ty.kind() { | ||||||||
// these are always sized | ||||||||
Bool | ||||||||
| Char | ||||||||
| Int(..) | ||||||||
| Uint(..) | ||||||||
| Float(..) | ||||||||
| RawPtr(..) | ||||||||
| Ref(..) | ||||||||
| FnDef(..) | ||||||||
| FnPtr(..) | ||||||||
| Array(..) | ||||||||
| Closure(..) | ||||||||
| CoroutineClosure(..) | ||||||||
| Coroutine(..) | ||||||||
| CoroutineWitness(..) | ||||||||
| Never | ||||||||
| Dynamic(_, _, ty::DynStar) => None, | ||||||||
|
||||||||
// these are never sized | ||||||||
Str | Slice(..) | Dynamic(_, _, ty::Dyn) | Foreign(..) => Some(ty), | ||||||||
|
||||||||
Tuple(tys) => tys.last().and_then(|&ty| sized_constraint_for_ty(tcx, ty)), | ||||||||
|
||||||||
// recursive case | ||||||||
Adt(adt, args) => { | ||||||||
// recursive case | ||||||||
let adt_tys = adt.sized_constraint(tcx); | ||||||||
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); | ||||||||
adt_tys | ||||||||
.iter_instantiated(tcx, args) | ||||||||
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) | ||||||||
.collect() | ||||||||
let intermediate = adt.sized_constraint(tcx); | ||||||||
intermediate.and_then(|intermediate| { | ||||||||
|
let intermediate = adt.sized_constraint(tcx); | |
intermediate.and_then(|intermediate| { | |
adt.sized_constraint(tcx).and_then(|intermediate| { |
very much a nit 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 🤷