Rollup merge of #114314 - compiler-errors:sized-crit, r=lcnr
Tweaks to `adt_sized_constraint` fixes a comment, but also some other nits. r? lcnr
This commit is contained in:
commit
3d29ce7484
7 changed files with 27 additions and 25 deletions
|
@ -1462,7 +1462,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let traits: Vec<_> =
|
let traits: Vec<_> =
|
||||||
self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
|
self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
|
||||||
|
|
||||||
// Don't print `TyErr` to the user.
|
// Don't print `ty::Error` to the user.
|
||||||
self.report_ambiguous_associated_type(
|
self.report_ambiguous_associated_type(
|
||||||
span,
|
span,
|
||||||
&[qself_ty.to_string()],
|
&[qself_ty.to_string()],
|
||||||
|
|
|
@ -795,7 +795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
/// Converts the types that the user supplied, in case that doing
|
/// Converts the types that the user supplied, in case that doing
|
||||||
/// so should yield an error, but returns back a signature where
|
/// so should yield an error, but returns back a signature where
|
||||||
/// all parameters are of type `TyErr`.
|
/// all parameters are of type `ty::Error`.
|
||||||
fn error_sig_of_closure(
|
fn error_sig_of_closure(
|
||||||
&self,
|
&self,
|
||||||
decl: &hir::FnDecl<'_>,
|
decl: &hir::FnDecl<'_>,
|
||||||
|
|
|
@ -706,7 +706,7 @@ rustc_queries! {
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
query adt_sized_constraint(key: DefId) -> &'tcx [Ty<'tcx>] {
|
query adt_sized_constraint(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
|
||||||
desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,18 +562,10 @@ impl<'tcx> AdtDef<'tcx> {
|
||||||
tcx.adt_destructor(self.did())
|
tcx.adt_destructor(self.did())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of types such that `Self: Sized` if and only
|
/// Returns a list of types such that `Self: Sized` if and only if that
|
||||||
/// if that type is `Sized`, or `TyErr` if this type is recursive.
|
/// type is `Sized`, or `ty::Error` if this type has a recursive layout.
|
||||||
///
|
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
|
||||||
/// Oddly enough, checking that the sized-constraint is `Sized` is
|
tcx.adt_sized_constraint(self.did())
|
||||||
/// actually more expressive than checking all members:
|
|
||||||
/// the `Sized` trait is inductive, so an associated type that references
|
|
||||||
/// `Self` would prevent its containing ADT from being `Sized`.
|
|
||||||
///
|
|
||||||
/// Due to normalization being eager, this applies even if
|
|
||||||
/// the associated type is behind a pointer (e.g., issue #31299).
|
|
||||||
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
|
|
||||||
ty::EarlyBinder::bind(tcx.adt_sized_constraint(self.did()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
||||||
|
|
||||||
ty::Adt(def, args) => {
|
ty::Adt(def, args) => {
|
||||||
let sized_crit = def.sized_constraint(ecx.tcx());
|
let sized_crit = def.sized_constraint(ecx.tcx());
|
||||||
Ok(sized_crit.iter_instantiated_copied(ecx.tcx(), args).collect())
|
Ok(sized_crit.iter_instantiated(ecx.tcx(), args).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2099,7 +2099,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
Where(
|
Where(
|
||||||
obligation
|
obligation
|
||||||
.predicate
|
.predicate
|
||||||
.rebind(sized_crit.iter_instantiated_copied(self.tcx(), args).collect()),
|
.rebind(sized_crit.iter_instantiated(self.tcx(), args).collect()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ fn sized_constraint_for_ty<'tcx>(
|
||||||
let adt_tys = adt.sized_constraint(tcx);
|
let adt_tys = adt.sized_constraint(tcx);
|
||||||
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys);
|
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys);
|
||||||
adt_tys
|
adt_tys
|
||||||
.iter_instantiated_copied(tcx, args)
|
.iter_instantiated(tcx, args)
|
||||||
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
|
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,18 @@ fn sized_constraint_for_ty<'tcx>(
|
||||||
// we know that `T` is Sized and do not need to check
|
// we know that `T` is Sized and do not need to check
|
||||||
// it on the impl.
|
// it on the impl.
|
||||||
|
|
||||||
let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
|
let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() else { return vec![ty] };
|
||||||
let sized_predicate =
|
|
||||||
ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx);
|
|
||||||
let predicates = tcx.predicates_of(adtdef.did()).predicates;
|
let predicates = tcx.predicates_of(adtdef.did()).predicates;
|
||||||
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
|
if predicates.iter().any(|(p, _)| {
|
||||||
|
p.as_trait_clause().is_some_and(|trait_pred| {
|
||||||
|
trait_pred.def_id() == sized_trait_def_id
|
||||||
|
&& trait_pred.self_ty().skip_binder() == ty
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
vec![]
|
||||||
|
} else {
|
||||||
|
vec![ty]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Placeholder(..) | Bound(..) | Infer(..) => {
|
Placeholder(..) | Bound(..) | Infer(..) => {
|
||||||
|
@ -92,10 +99,13 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
|
||||||
/// - a tuple of type parameters or projections, if there are multiple
|
/// - a tuple of type parameters or projections, if there are multiple
|
||||||
/// such.
|
/// such.
|
||||||
/// - an Error, if a type is infinitely sized
|
/// - an Error, if a type is infinitely sized
|
||||||
fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
|
fn adt_sized_constraint<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
|
if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
|
||||||
return tcx.mk_type_list(&[Ty::new_misc_error(tcx)]);
|
return ty::EarlyBinder::bind(tcx.mk_type_list(&[Ty::new_misc_error(tcx)]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
|
@ -107,7 +117,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
|
||||||
|
|
||||||
debug!("adt_sized_constraint: {:?} => {:?}", def, result);
|
debug!("adt_sized_constraint: {:?} => {:?}", def, result);
|
||||||
|
|
||||||
result
|
ty::EarlyBinder::bind(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `ParamEnv` struct definition for details.
|
/// See `ParamEnv` struct definition for details.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue