1
Fork 0

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 let Some(&param) = params.peek() {
if param.index == 0 { if param.index == 0 {
if let GenericParamDefKind::Type { .. } = param.kind { if let GenericParamDefKind::Type { .. } = param.kind {
assert_eq!(&args[..], &[]);
args.push( args.push(
self_ty self_ty
.map(|ty| ty.into()) .map(|ty| ty.into())
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)), .unwrap_or_else(|| ctx.inferred_kind(&args, param, true)),
); );
params.next(); 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 // 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. // `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. // 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(); params.next();
} }
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) (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 // We expected a lifetime argument, but got a type or const
// argument. That means we're inferring the lifetimes. // 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)); force_infer_lt = Some((arg, param));
params.next(); params.next();
} }
@ -388,7 +389,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
(None, Some(&param)) => { (None, Some(&param)) => {
// If there are fewer arguments than parameters, it means // If there are fewer arguments than parameters, it means
// we're inferring the remaining arguments. // 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(); params.next();
} }

View file

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

View file

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

View file

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