Always provide previous generic arguments
This commit is contained in:
parent
063b26af6b
commit
108a1e5f4b
@ -214,10 +214,11 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
|
||||
if let Some(¶m) = 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(¶m)) => {
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ fn provided_kind(
|
||||
|
||||
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 @@ fn provided_kind(
|
||||
|
||||
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 @@ fn inferred_kind(
|
||||
|
||||
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 @@ fn inferred_kind(
|
||||
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 @@ fn inferred_kind(
|
||||
// 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 {
|
||||
|
@ -1317,7 +1317,7 @@ fn provided_kind(
|
||||
|
||||
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 @@ fn inferred_kind(
|
||||
// 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 @@ fn inferred_kind(
|
||||
} else if !infer_args {
|
||||
return tcx
|
||||
.const_param_default(param.def_id)
|
||||
.instantiate(tcx, args.unwrap())
|
||||
.instantiate(tcx, preceding_args)
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ fn provided_kind(
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
_args: Option<&[ty::GenericArg<'tcx>]>,
|
||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
||||
param: &ty::GenericParamDef,
|
||||
_infer_args: bool,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
|
Loading…
Reference in New Issue
Block a user