Always provide previous generic arguments

This commit is contained in:
Oli Scherer 2024-06-03 13:45:36 +00:00
parent 063b26af6b
commit 108a1e5f4b
4 changed files with 24 additions and 34 deletions

View File

@ -214,10 +214,11 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
if let Some(&param) = params.peek() {
if param.index == 0 {
if let GenericParamDefKind::Type { .. } = param.kind {
assert_eq!(&args[..], &[]);
args.push(
self_ty
.map(|ty| ty.into())
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
.unwrap_or_else(|| ctx.inferred_kind(&args, param, true)),
);
params.next();
}
@ -267,7 +268,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
// Since this is a const impl, we need to insert a host arg at the end of
// `PartialEq`'s generics, but this errors since `Rhs` isn't specified.
// To work around this, we infer all arguments until we reach the host param.
args.push(ctx.inferred_kind(Some(&args), param, infer_args));
args.push(ctx.inferred_kind(&args, param, infer_args));
params.next();
}
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
@ -292,7 +293,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
) => {
// We expected a lifetime argument, but got a type or const
// argument. That means we're inferring the lifetimes.
args.push(ctx.inferred_kind(None, param, infer_args));
args.push(ctx.inferred_kind(&args, param, infer_args));
force_infer_lt = Some((arg, param));
params.next();
}
@ -388,7 +389,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
(None, Some(&param)) => {
// If there are fewer arguments than parameters, it means
// we're inferring the remaining arguments.
args.push(ctx.inferred_kind(Some(&args), param, infer_args));
args.push(ctx.inferred_kind(&args, param, infer_args));
params.next();
}

View File

@ -245,7 +245,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
fn inferred_kind(
&mut self,
args: Option<&[ty::GenericArg<'tcx>]>,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef,
infer_args: bool,
) -> ty::GenericArg<'tcx>;
@ -525,7 +525,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn inferred_kind(
&mut self,
args: Option<&[ty::GenericArg<'tcx>]>,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef,
infer_args: bool,
) -> ty::GenericArg<'tcx> {
@ -533,22 +533,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if let Err(incorrect) = self.incorrect_args {
if incorrect.invalid_args.contains(&(param.index as usize)) {
// FIXME: use `param.to_error` once `inferred_kind` is supplied a list of
// all previous generic args.
return match param.kind {
GenericParamDefKind::Lifetime => {
ty::Region::new_error(tcx, incorrect.reported).into()
}
GenericParamDefKind::Type { .. } => {
Ty::new_error(tcx, incorrect.reported).into()
}
GenericParamDefKind::Const { .. } => ty::Const::new_error(
tcx,
incorrect.reported,
Ty::new_error(tcx, incorrect.reported),
)
.into(),
};
return param.to_error(tcx, preceding_args);
}
}
match param.kind {
@ -569,15 +554,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default {
// No type parameter provided, but a default exists.
let args = args.unwrap();
if args.iter().any(|arg| match arg.unpack() {
GenericArgKind::Type(ty) => ty.references_error(),
_ => false,
}) {
if let Some(prev) =
preceding_args.iter().find_map(|arg| match arg.unpack() {
GenericArgKind::Type(ty) => ty.error_reported().err(),
_ => None,
})
{
// Avoid ICE #86756 when type error recovery goes awry.
return Ty::new_misc_error(tcx).into();
return Ty::new_error(tcx, prev).into();
}
tcx.at(self.span).type_of(param.def_id).instantiate(tcx, args).into()
tcx.at(self.span)
.type_of(param.def_id)
.instantiate(tcx, preceding_args)
.into()
} else if infer_args {
self.lowerer.ty_infer(Some(param), self.span).into()
} else {
@ -597,7 +586,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// FIXME(effects) see if we should special case effect params here
if !infer_args && has_default {
tcx.const_param_default(param.def_id)
.instantiate(tcx, args.unwrap())
.instantiate(tcx, preceding_args)
.into()
} else {
if infer_args {

View File

@ -1317,7 +1317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn inferred_kind(
&mut self,
args: Option<&[ty::GenericArg<'tcx>]>,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef,
infer_args: bool,
) -> ty::GenericArg<'tcx> {
@ -1331,7 +1331,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If we have a default, then it doesn't matter that we're not
// inferring the type arguments: we provide the default where any
// is missing.
tcx.type_of(param.def_id).instantiate(tcx, args.unwrap()).into()
tcx.type_of(param.def_id).instantiate(tcx, preceding_args).into()
} else {
// If no type arguments were provided, we have to infer them.
// This case also occurs as a result of some malformed input, e.g.
@ -1356,7 +1356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else if !infer_args {
return tcx
.const_param_default(param.def_id)
.instantiate(tcx, args.unwrap())
.instantiate(tcx, preceding_args)
.into();
}
}

View File

@ -419,7 +419,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
fn inferred_kind(
&mut self,
_args: Option<&[ty::GenericArg<'tcx>]>,
_preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef,
_infer_args: bool,
) -> ty::GenericArg<'tcx> {