Rollup merge of #150962 - rm/feed_const_ty, r=BoxyUwU
Remove `FeedConstTy` and provide ty when lowering const arg r? @BoxyUwU edit: BoxyUwU `FeedConstTy` currently only provides the expected type of a const argument *sometimes* (e.g. previously array lengths did not do this). This causes problems with mGCA's directly represented const arguments which always need to know their expected type.
This commit is contained in:
commit
27e6ef9f6d
11 changed files with 163 additions and 118 deletions
|
|
@ -47,9 +47,7 @@ use rustc_trait_selection::traits::{
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::errors;
|
||||
use crate::hir_ty_lowering::{
|
||||
FeedConstTy, HirTyLowerer, InherentAssocCandidate, RegionInferReason,
|
||||
};
|
||||
use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason};
|
||||
|
||||
pub(crate) mod dump;
|
||||
mod generics_of;
|
||||
|
|
@ -1499,7 +1497,7 @@ fn const_param_default<'tcx>(
|
|||
|
||||
let ct = icx
|
||||
.lowerer()
|
||||
.lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args));
|
||||
.lower_const_arg(default_ct, tcx.type_of(def_id).instantiate(tcx, identity_args));
|
||||
ty::EarlyBinder::bind(ct)
|
||||
}
|
||||
|
||||
|
|
@ -1557,7 +1555,7 @@ fn const_of_item<'tcx>(
|
|||
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
let ct = icx
|
||||
.lowerer()
|
||||
.lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args));
|
||||
.lower_const_arg(ct_arg, tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args));
|
||||
if let Err(e) = icx.check_tainted_by_errors()
|
||||
&& !ct.references_error()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use tracing::{debug, instrument};
|
|||
|
||||
use crate::errors;
|
||||
use crate::hir_ty_lowering::{
|
||||
AssocItemQSelf, FeedConstTy, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext,
|
||||
AssocItemQSelf, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext,
|
||||
OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
|
||||
};
|
||||
|
||||
|
|
@ -510,7 +510,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// Create the generic arguments for the associated type or constant by joining the
|
||||
// parent arguments (the arguments of the trait) and the own arguments (the ones of
|
||||
// the associated item itself) and construct an alias type using them.
|
||||
let alias_term = candidate.map_bound(|trait_ref| {
|
||||
candidate.map_bound(|trait_ref| {
|
||||
let item_segment = hir::PathSegment {
|
||||
ident: constraint.ident,
|
||||
hir_id: constraint.hir_id,
|
||||
|
|
@ -528,20 +528,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
debug!(?alias_args);
|
||||
|
||||
ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args)
|
||||
});
|
||||
|
||||
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
|
||||
if let Some(const_arg) = constraint.ct()
|
||||
&& let hir::ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
{
|
||||
let ty = alias_term
|
||||
.map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
|
||||
let ty =
|
||||
check_assoc_const_binding_type(self, constraint.ident, ty, constraint.hir_id);
|
||||
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
|
||||
}
|
||||
|
||||
alias_term
|
||||
})
|
||||
};
|
||||
|
||||
match constraint.kind {
|
||||
|
|
@ -555,7 +542,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::AssocItemConstraintKind::Equality { term } => {
|
||||
let term = match term {
|
||||
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||
hir::Term::Const(ct) => self.lower_const_arg(ct, FeedConstTy::No).into(),
|
||||
hir::Term::Const(ct) => {
|
||||
let ty = projection_term.map_bound(|alias| {
|
||||
tcx.type_of(alias.def_id).instantiate(tcx, alias.args)
|
||||
});
|
||||
let ty = check_assoc_const_binding_type(
|
||||
self,
|
||||
constraint.ident,
|
||||
ty,
|
||||
constraint.hir_id,
|
||||
);
|
||||
|
||||
self.lower_const_arg(ct, ty).into()
|
||||
}
|
||||
};
|
||||
|
||||
// Find any late-bound regions declared in `ty` that are not
|
||||
|
|
@ -871,7 +870,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
/// probably gate this behind another feature flag.
|
||||
///
|
||||
/// [^1]: <https://github.com/rust-lang/project-const-generics/issues/28>.
|
||||
fn check_assoc_const_binding_type<'tcx>(
|
||||
pub(crate) fn check_assoc_const_binding_type<'tcx>(
|
||||
cx: &dyn HirTyLowerer<'tcx>,
|
||||
assoc_const: Ident,
|
||||
ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
|
|
|
|||
|
|
@ -253,35 +253,6 @@ impl AssocItemQSelf {
|
|||
}
|
||||
}
|
||||
|
||||
/// In some cases, [`hir::ConstArg`]s that are being used in the type system
|
||||
/// through const generics need to have their type "fed" to them
|
||||
/// using the query system.
|
||||
///
|
||||
/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
|
||||
/// desired behavior.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FeedConstTy<'tcx> {
|
||||
/// Feed the type to the (anno) const arg.
|
||||
WithTy(Ty<'tcx>),
|
||||
/// Don't feed the type.
|
||||
No,
|
||||
}
|
||||
|
||||
impl<'tcx> FeedConstTy<'tcx> {
|
||||
/// The `DefId` belongs to the const param that we are supplying
|
||||
/// this (anon) const arg to.
|
||||
///
|
||||
/// The list of generic args is used to instantiate the parameters
|
||||
/// used by the type of the const param specified by `DefId`.
|
||||
pub fn with_type_of(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
generic_args: &[ty::GenericArg<'tcx>],
|
||||
) -> Self {
|
||||
Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum LowerTypeRelativePathMode {
|
||||
Type(PermitVariants),
|
||||
|
|
@ -733,7 +704,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// Ambig portions of `ConstArg` are handled in the match arm below
|
||||
.lower_const_arg(
|
||||
ct.as_unambig_ct(),
|
||||
FeedConstTy::with_type_of(tcx, param.def_id, preceding_args),
|
||||
tcx.type_of(param.def_id).instantiate(tcx, preceding_args),
|
||||
)
|
||||
.into(),
|
||||
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
|
||||
|
|
@ -1269,10 +1240,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let mut where_bounds = vec![];
|
||||
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
||||
let bound_id = bound.def_id();
|
||||
let bound_span = tcx
|
||||
.associated_items(bound_id)
|
||||
.find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
|
||||
.and_then(|item| tcx.hir_span_if_local(item.def_id));
|
||||
let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind(
|
||||
tcx,
|
||||
assoc_ident,
|
||||
assoc_tag,
|
||||
bound_id,
|
||||
);
|
||||
let bound_span = assoc_item.and_then(|item| tcx.hir_span_if_local(item.def_id));
|
||||
|
||||
if let Some(bound_span) = bound_span {
|
||||
err.span_label(
|
||||
|
|
@ -1285,7 +1259,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let term: ty::Term<'_> = match term {
|
||||
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||
hir::Term::Const(ct) => {
|
||||
self.lower_const_arg(ct, FeedConstTy::No).into()
|
||||
let assoc_item =
|
||||
assoc_item.expect("assoc_item should be present");
|
||||
let projection_term = bound.map_bound(|trait_ref| {
|
||||
let item_segment = hir::PathSegment {
|
||||
ident: constraint.ident,
|
||||
hir_id: constraint.hir_id,
|
||||
res: Res::Err,
|
||||
args: Some(constraint.gen_args),
|
||||
infer_args: false,
|
||||
};
|
||||
|
||||
let alias_args = self.lower_generic_args_of_assoc_item(
|
||||
constraint.ident.span,
|
||||
assoc_item.def_id,
|
||||
&item_segment,
|
||||
trait_ref.args,
|
||||
);
|
||||
ty::AliasTerm::new_from_args(
|
||||
tcx,
|
||||
assoc_item.def_id,
|
||||
alias_args,
|
||||
)
|
||||
});
|
||||
|
||||
// FIXME(mgca): code duplication with other places we lower
|
||||
// the rhs' of associated const bindings
|
||||
let ty = projection_term.map_bound(|alias| {
|
||||
tcx.type_of(alias.def_id).instantiate(tcx, alias.args)
|
||||
});
|
||||
let ty = bounds::check_assoc_const_binding_type(
|
||||
self,
|
||||
constraint.ident,
|
||||
ty,
|
||||
constraint.hir_id,
|
||||
);
|
||||
|
||||
self.lower_const_arg(ct, ty).into()
|
||||
}
|
||||
};
|
||||
if term.references_error() {
|
||||
|
|
@ -2310,16 +2320,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
/// Lower a [`hir::ConstArg`] to a (type-level) [`ty::Const`](Const).
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn lower_const_arg(
|
||||
&self,
|
||||
const_arg: &hir::ConstArg<'tcx>,
|
||||
feed: FeedConstTy<'tcx>,
|
||||
) -> Const<'tcx> {
|
||||
pub fn lower_const_arg(&self, const_arg: &hir::ConstArg<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
if let FeedConstTy::WithTy(anon_const_type) = feed
|
||||
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind
|
||||
{
|
||||
if let hir::ConstArgKind::Anon(anon) = &const_arg.kind {
|
||||
// FIXME(generic_const_parameter_types): Ideally we remove these errors below when
|
||||
// we have the ability to intermix typeck of anon const const args with the parent
|
||||
// bodies typeck.
|
||||
|
|
@ -2329,7 +2333,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// hir typeck was using equality but mir borrowck wound up using subtyping as that could
|
||||
// result in a non-infer in hir typeck but a region variable in borrowck.
|
||||
if tcx.features().generic_const_parameter_types()
|
||||
&& (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
|
||||
&& (ty.has_free_regions() || ty.has_erased_regions())
|
||||
{
|
||||
let e = self.dcx().span_err(
|
||||
const_arg.span,
|
||||
|
|
@ -2341,7 +2345,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// We must error if the instantiated type has any inference variables as we will
|
||||
// use this type to feed the `type_of` and query results must not contain inference
|
||||
// variables otherwise we will ICE.
|
||||
if anon_const_type.has_non_region_infer() {
|
||||
if ty.has_non_region_infer() {
|
||||
let e = self.dcx().span_err(
|
||||
const_arg.span,
|
||||
"anonymous constants with inferred types are not yet supported",
|
||||
|
|
@ -2351,7 +2355,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
// We error when the type contains unsubstituted generics since we do not currently
|
||||
// give the anon const any of the generics from the parent.
|
||||
if anon_const_type.has_non_region_param() {
|
||||
if ty.has_non_region_param() {
|
||||
let e = self.dcx().span_err(
|
||||
const_arg.span,
|
||||
"anonymous constants referencing generics are not yet supported",
|
||||
|
|
@ -2360,12 +2364,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
return ty::Const::new_error(tcx, e);
|
||||
}
|
||||
|
||||
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type));
|
||||
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(ty));
|
||||
}
|
||||
|
||||
let hir_id = const_arg.hir_id;
|
||||
match const_arg.kind {
|
||||
hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span),
|
||||
hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, ty, const_arg.span),
|
||||
hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||
debug!(?maybe_qself, ?path);
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
|
||||
|
|
@ -2389,16 +2393,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::ConstArgKind::TupleCall(qpath, args) => {
|
||||
self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span)
|
||||
}
|
||||
hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed),
|
||||
hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, ty),
|
||||
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
|
||||
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
|
||||
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
|
||||
hir::ConstArgKind::Literal(kind) if let FeedConstTy::WithTy(anon_const_type) = feed => {
|
||||
self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span)
|
||||
}
|
||||
hir::ConstArgKind::Literal(..) => {
|
||||
let e = self.dcx().span_err(const_arg.span, "literal of unknown type");
|
||||
ty::Const::new_error(tcx, e)
|
||||
hir::ConstArgKind::Literal(kind) => {
|
||||
self.lower_const_arg_literal(&kind, ty, const_arg.span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2406,14 +2406,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn lower_const_arg_array(
|
||||
&self,
|
||||
array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>,
|
||||
feed: FeedConstTy<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let FeedConstTy::WithTy(ty) = feed else {
|
||||
return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array");
|
||||
};
|
||||
|
||||
let ty::Array(elem_ty, _) = ty.kind() else {
|
||||
let e = tcx
|
||||
.dcx()
|
||||
|
|
@ -2424,7 +2420,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let elems = array_expr
|
||||
.elems
|
||||
.iter()
|
||||
.map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty)))
|
||||
.map(|elem| self.lower_const_arg(elem, *elem_ty))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let valtree = ty::ValTree::from_branches(tcx, elems);
|
||||
|
|
@ -2507,7 +2503,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.iter()
|
||||
.zip(args)
|
||||
.map(|(field_def, arg)| {
|
||||
self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args))
|
||||
self.lower_const_arg(arg, tcx.type_of(field_def.did).instantiate(tcx, adt_args))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
@ -2526,15 +2522,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn lower_const_arg_tup(
|
||||
&self,
|
||||
exprs: &'tcx [&'tcx hir::ConstArg<'tcx>],
|
||||
feed: FeedConstTy<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let FeedConstTy::WithTy(ty) = feed else {
|
||||
return Const::new_error_with_message(tcx, span, "const tuple lack type information");
|
||||
};
|
||||
|
||||
let ty::Tuple(tys) = ty.kind() else {
|
||||
let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty));
|
||||
return Const::new_error(tcx, e);
|
||||
|
|
@ -2543,7 +2535,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let exprs = exprs
|
||||
.iter()
|
||||
.zip(tys.iter())
|
||||
.map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty)))
|
||||
.map(|(expr, ty)| self.lower_const_arg(expr, ty))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let valtree = ty::ValTree::from_branches(tcx, exprs);
|
||||
|
|
@ -2630,7 +2622,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
self.lower_const_arg(
|
||||
expr.expr,
|
||||
FeedConstTy::with_type_of(tcx, field_def.did, adt_args),
|
||||
tcx.type_of(field_def.did).instantiate(tcx, adt_args),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
|
|
@ -2992,7 +2984,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
|
||||
}
|
||||
hir::TyKind::Array(ty, length) => {
|
||||
let length = self.lower_const_arg(length, FeedConstTy::No);
|
||||
let length = self.lower_const_arg(length, tcx.types.usize);
|
||||
Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
|
||||
}
|
||||
hir::TyKind::Infer(()) => {
|
||||
|
|
@ -3032,8 +3024,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// Keep this list of types in sync with the list of types that
|
||||
// the `RangePattern` trait is implemented for.
|
||||
ty::Int(_) | ty::Uint(_) | ty::Char => {
|
||||
let start = self.lower_const_arg(start, FeedConstTy::No);
|
||||
let end = self.lower_const_arg(end, FeedConstTy::No);
|
||||
let start = self.lower_const_arg(start, ty);
|
||||
let end = self.lower_const_arg(end, ty);
|
||||
Ok(ty::PatternKind::Range { start, end })
|
||||
}
|
||||
_ => Err(self
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ use rustc_span::{ErrorGuaranteed, Span};
|
|||
use rustc_trait_selection::traits;
|
||||
|
||||
pub use crate::collect::suggest_impl_trait;
|
||||
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
|
||||
use crate::hir_ty_lowering::HirTyLowerer;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
|
|
@ -301,8 +301,8 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
|||
pub fn lower_const_arg_for_rustdoc<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
hir_ct: &hir::ConstArg<'tcx>,
|
||||
feed: FeedConstTy<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Const<'tcx> {
|
||||
let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{ExprKind, HirId, QPath, find_attr, is_range_literal};
|
||||
use rustc_hir_analysis::NoVariantNamed;
|
||||
use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
|
||||
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
|
||||
|
|
@ -1749,7 +1749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let count_span = count.span;
|
||||
let count = self.try_structurally_resolve_const(
|
||||
count_span,
|
||||
self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)),
|
||||
self.normalize(count_span, self.lower_const_arg(count, tcx.types.usize)),
|
||||
);
|
||||
|
||||
if let Some(count) = count.try_to_target_usize(tcx) {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
|
|||
check_generic_arg_count_for_call, lower_generic_args,
|
||||
};
|
||||
use rustc_hir_analysis::hir_ty_lowering::{
|
||||
ExplicitLateBound, FeedConstTy, GenericArgCountMismatch, GenericArgCountResult,
|
||||
GenericArgsLowerer, GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
|
||||
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
|
||||
GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
|
||||
};
|
||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
|
||||
|
|
@ -525,9 +525,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pub(crate) fn lower_const_arg(
|
||||
&self,
|
||||
const_arg: &'tcx hir::ConstArg<'tcx>,
|
||||
feed: FeedConstTy<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> ty::Const<'tcx> {
|
||||
let ct = self.lowerer().lower_const_arg(const_arg, feed);
|
||||
let ct = self.lowerer().lower_const_arg(const_arg, ty);
|
||||
self.register_wf_obligation(
|
||||
ct.into(),
|
||||
self.tcx.hir_span(const_arg.hir_id),
|
||||
|
|
@ -1228,7 +1228,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Ambiguous parts of `ConstArg` are handled in the match arms below
|
||||
.lower_const_arg(
|
||||
ct.as_unambig_ct(),
|
||||
FeedConstTy::with_type_of(self.fcx.tcx, param.def_id, preceding_args),
|
||||
self.fcx
|
||||
.tcx
|
||||
.type_of(param.def_id)
|
||||
.instantiate(self.fcx.tcx, preceding_args),
|
||||
)
|
||||
.into(),
|
||||
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
|
|||
check_generic_arg_count_for_call, lower_generic_args,
|
||||
};
|
||||
use rustc_hir_analysis::hir_ty_lowering::{
|
||||
FeedConstTy, GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
|
||||
GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
|
||||
};
|
||||
use rustc_infer::infer::{
|
||||
BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin,
|
||||
|
|
@ -447,7 +447,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
// We handle the ambig portions of `ConstArg` in the match arms below
|
||||
.lower_const_arg(
|
||||
ct.as_unambig_ct(),
|
||||
FeedConstTy::with_type_of(self.cfcx.tcx, param.def_id, preceding_args),
|
||||
self.cfcx
|
||||
.tcx
|
||||
.type_of(param.def_id)
|
||||
.instantiate(self.cfcx.tcx, preceding_args),
|
||||
)
|
||||
.into(),
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ use rustc_hir::attrs::{AttributeKind, DocAttribute, DocInline};
|
|||
use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::{LangItem, PredicateOrigin, find_attr};
|
||||
use rustc_hir_analysis::hir_ty_lowering::FeedConstTy;
|
||||
use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty};
|
||||
use rustc_middle::metadata::Reexport;
|
||||
use rustc_middle::middle::resolve_bound_vars as rbv;
|
||||
|
|
@ -469,11 +468,17 @@ fn clean_middle_term<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
|
||||
fn clean_hir_term<'tcx>(
|
||||
assoc_item: Option<DefId>,
|
||||
term: &hir::Term<'tcx>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> Term {
|
||||
match term {
|
||||
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
|
||||
hir::Term::Const(c) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, c, FeedConstTy::No);
|
||||
// FIXME(generic_const_items): this should instantiate with the alias item's args
|
||||
let ty = cx.tcx.type_of(assoc_item.unwrap()).instantiate_identity();
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty);
|
||||
Term::Constant(clean_middle_const(ty::Binder::dummy(ct), cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -650,7 +655,9 @@ fn clean_generic_param<'tcx>(
|
|||
GenericParamDefKind::Const {
|
||||
ty: Box::new(clean_ty(ty, cx)),
|
||||
default: default.map(|ct| {
|
||||
Box::new(lower_const_arg_for_rustdoc(cx.tcx, ct, FeedConstTy::No).to_string())
|
||||
Box::new(
|
||||
lower_const_arg_for_rustdoc(cx.tcx, ct, lower_ty(cx.tcx, ty)).to_string(),
|
||||
)
|
||||
}),
|
||||
},
|
||||
),
|
||||
|
|
@ -1531,7 +1538,7 @@ fn first_non_private_clean_path<'tcx>(
|
|||
&& path_last.args.is_some()
|
||||
{
|
||||
assert!(new_path_last.args.is_empty());
|
||||
new_path_last.args = clean_generic_args(path_last_args, cx);
|
||||
new_path_last.args = clean_generic_args(None, path_last_args, cx);
|
||||
}
|
||||
new_clean_path
|
||||
}
|
||||
|
|
@ -1812,7 +1819,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
let length = match const_arg.kind {
|
||||
hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => "_".to_string(),
|
||||
hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize);
|
||||
let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id);
|
||||
let ct = cx.tcx.normalize_erasing_regions(typing_env, ct);
|
||||
print_const(cx, ct)
|
||||
|
|
@ -1823,7 +1830,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
| hir::ConstArgKind::Tup(..)
|
||||
| hir::ConstArgKind::Array(..)
|
||||
| hir::ConstArgKind::Literal(..) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize);
|
||||
print_const(cx, ct)
|
||||
}
|
||||
};
|
||||
|
|
@ -2516,6 +2523,7 @@ fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
|
|||
}
|
||||
|
||||
fn clean_generic_args<'tcx>(
|
||||
trait_did: Option<DefId>,
|
||||
generic_args: &hir::GenericArgs<'tcx>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> GenericArgs {
|
||||
|
|
@ -2539,7 +2547,13 @@ fn clean_generic_args<'tcx>(
|
|||
let constraints = generic_args
|
||||
.constraints
|
||||
.iter()
|
||||
.map(|c| clean_assoc_item_constraint(c, cx))
|
||||
.map(|c| {
|
||||
clean_assoc_item_constraint(
|
||||
trait_did.expect("only trait ref has constraints"),
|
||||
c,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.collect::<ThinVec<_>>();
|
||||
GenericArgs::AngleBracketed { args, constraints }
|
||||
}
|
||||
|
|
@ -2562,7 +2576,11 @@ fn clean_path_segment<'tcx>(
|
|||
path: &hir::PathSegment<'tcx>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> PathSegment {
|
||||
PathSegment { name: path.ident.name, args: clean_generic_args(path.args(), cx) }
|
||||
let trait_did = match path.res {
|
||||
hir::def::Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
|
||||
_ => None,
|
||||
};
|
||||
PathSegment { name: path.ident.name, args: clean_generic_args(trait_did, path.args(), cx) }
|
||||
}
|
||||
|
||||
fn clean_bare_fn_ty<'tcx>(
|
||||
|
|
@ -3126,17 +3144,27 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
|||
}
|
||||
|
||||
fn clean_assoc_item_constraint<'tcx>(
|
||||
trait_did: DefId,
|
||||
constraint: &hir::AssocItemConstraint<'tcx>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> AssocItemConstraint {
|
||||
AssocItemConstraint {
|
||||
assoc: PathSegment {
|
||||
name: constraint.ident.name,
|
||||
args: clean_generic_args(constraint.gen_args, cx),
|
||||
args: clean_generic_args(None, constraint.gen_args, cx),
|
||||
},
|
||||
kind: match constraint.kind {
|
||||
hir::AssocItemConstraintKind::Equality { ref term } => {
|
||||
AssocItemConstraintKind::Equality { term: clean_hir_term(term, cx) }
|
||||
let assoc_tag = match term {
|
||||
hir::Term::Ty(_) => ty::AssocTag::Type,
|
||||
hir::Term::Const(_) => ty::AssocTag::Const,
|
||||
};
|
||||
let assoc_item = cx
|
||||
.tcx
|
||||
.associated_items(trait_did)
|
||||
.find_by_ident_and_kind(cx.tcx, constraint.ident, assoc_tag, trait_did)
|
||||
.map(|item| item.def_id);
|
||||
AssocItemConstraintKind::Equality { term: clean_hir_term(assoc_item, term, cx) }
|
||||
}
|
||||
hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound {
|
||||
bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ LL | const C: &'static str;
|
|||
...
|
||||
LL | fn take1(_: impl Trait1<C = "?">) {}
|
||||
| ^^^^^^^ ambiguous associated constant `C`
|
||||
|
|
||||
= help: consider introducing a new type parameter `T` and adding `where` constraints:
|
||||
where
|
||||
T: Trait1,
|
||||
T: Parent2::C = "?",
|
||||
T: Parent1::C = "?"
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
struct Y {
|
||||
stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found const tuple
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error: expected `usize`, found const tuple
|
||||
--> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19
|
||||
|
|
||||
LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }],
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue