Rollup merge of #125608 - oli-obk:subsequent_lifetime_errors, r=BoxyUwU
Avoid follow-up errors if the number of generic parameters already doesn't match fixes #125604 best reviewed commit-by-commit
This commit is contained in:
commit
0dc65501cb
21 changed files with 226 additions and 194 deletions
|
@ -702,7 +702,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
pub(crate) fn complain_about_missing_assoc_tys(
|
||||
&self,
|
||||
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
|
||||
potential_assoc_types: Vec<Span>,
|
||||
potential_assoc_types: Vec<usize>,
|
||||
trait_bounds: &[hir::PolyTraitRef<'_>],
|
||||
) {
|
||||
if associated_types.values().all(|v| v.is_empty()) {
|
||||
|
|
|
@ -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, _)
|
||||
|
@ -281,7 +282,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
|
|||
GenericParamDefKind::Const { .. },
|
||||
_,
|
||||
) => {
|
||||
args.push(ctx.provided_kind(param, arg));
|
||||
args.push(ctx.provided_kind(&args, param, arg));
|
||||
args_iter.next();
|
||||
params.next();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -474,16 +475,9 @@ pub(crate) fn check_generic_arg_count(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if provided_args > max_expected_args {
|
||||
invalid_args.extend(
|
||||
gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()),
|
||||
);
|
||||
};
|
||||
invalid_args.extend(min_expected_args..provided_args);
|
||||
|
||||
let gen_args_info = if provided_args > min_expected_args {
|
||||
invalid_args.extend(
|
||||
gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()),
|
||||
);
|
||||
let num_redundant_args = provided_args - min_expected_args;
|
||||
GenericArgsInfo::ExcessLifetimes { num_redundant_args }
|
||||
} else {
|
||||
|
@ -538,11 +532,7 @@ pub(crate) fn check_generic_arg_count(
|
|||
let num_default_params = expected_max - expected_min;
|
||||
|
||||
let gen_args_info = if provided > expected_max {
|
||||
invalid_args.extend(
|
||||
gen_args.args[args_offset + expected_max..args_offset + provided]
|
||||
.iter()
|
||||
.map(|arg| arg.span()),
|
||||
);
|
||||
invalid_args.extend((expected_max..provided).map(|i| i + args_offset));
|
||||
let num_redundant_args = provided - expected_max;
|
||||
|
||||
// Provide extra note if synthetic arguments like `impl Trait` are specified.
|
||||
|
@ -610,7 +600,7 @@ pub(crate) fn check_generic_arg_count(
|
|||
explicit_late_bound,
|
||||
correct: lifetimes_correct
|
||||
.and(args_correct)
|
||||
.map_err(|reported| GenericArgCountMismatch { reported: Some(reported), invalid_args }),
|
||||
.map_err(|reported| GenericArgCountMismatch { reported, invalid_args }),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,12 +215,11 @@ pub(crate) enum GenericArgPosition {
|
|||
|
||||
/// A marker denoting that the generic arguments that were
|
||||
/// provided did not match the respective generic parameters.
|
||||
#[derive(Clone, Default, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericArgCountMismatch {
|
||||
/// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
|
||||
pub reported: Option<ErrorGuaranteed>,
|
||||
/// A list of spans of arguments provided that were not valid.
|
||||
pub invalid_args: Vec<Span>,
|
||||
pub reported: ErrorGuaranteed,
|
||||
/// A list of indices of arguments provided that were not valid.
|
||||
pub invalid_args: Vec<usize>,
|
||||
}
|
||||
|
||||
/// Decorates the result of a generic argument count mismatch
|
||||
|
@ -240,13 +239,14 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
|
|||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
preceding_args: &[ty::GenericArg<'tcx>],
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'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>;
|
||||
|
@ -404,10 +404,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self_ty.is_some(),
|
||||
);
|
||||
|
||||
if let Err(err) = &arg_count.correct
|
||||
&& let Some(reported) = err.reported
|
||||
{
|
||||
self.set_tainted_by_errors(reported);
|
||||
if let Err(err) = &arg_count.correct {
|
||||
self.set_tainted_by_errors(err.reported);
|
||||
}
|
||||
|
||||
// Skip processing if type has no generic parameters.
|
||||
|
@ -425,6 +423,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
span: Span,
|
||||
inferred_params: Vec<Span>,
|
||||
infer_args: bool,
|
||||
incorrect_args: &'a Result<(), GenericArgCountMismatch>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
|
||||
|
@ -439,11 +438,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
preceding_args: &[ty::GenericArg<'tcx>],
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
let tcx = self.lowerer.tcx();
|
||||
|
||||
if let Err(incorrect) = self.incorrect_args {
|
||||
if incorrect.invalid_args.contains(&(param.index as usize)) {
|
||||
return param.to_error(tcx, preceding_args);
|
||||
}
|
||||
}
|
||||
|
||||
let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
|
||||
if has_default {
|
||||
tcx.check_optional_stability(
|
||||
|
@ -506,11 +512,17 @@ 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> {
|
||||
let tcx = self.lowerer.tcx();
|
||||
|
||||
if let Err(incorrect) = self.incorrect_args {
|
||||
if incorrect.invalid_args.contains(&(param.index as usize)) {
|
||||
return param.to_error(tcx, preceding_args);
|
||||
}
|
||||
}
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => self
|
||||
.lowerer
|
||||
|
@ -529,15 +541,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 {
|
||||
|
@ -557,7 +573,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 {
|
||||
|
@ -571,6 +587,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
}
|
||||
}
|
||||
if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness
|
||||
&& generics.has_self
|
||||
&& !tcx.has_attr(def_id, sym::const_trait)
|
||||
{
|
||||
let reported = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
|
||||
span,
|
||||
modifier: constness.as_str(),
|
||||
});
|
||||
self.set_tainted_by_errors(reported);
|
||||
arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] });
|
||||
}
|
||||
|
||||
let mut args_ctx = GenericArgsCtxt {
|
||||
lowerer: self,
|
||||
|
@ -579,19 +606,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
generic_args: segment.args(),
|
||||
inferred_params: vec![],
|
||||
infer_args: segment.infer_args,
|
||||
incorrect_args: &arg_count.correct,
|
||||
};
|
||||
if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness
|
||||
&& generics.has_self
|
||||
&& !tcx.has_attr(def_id, sym::const_trait)
|
||||
{
|
||||
let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
|
||||
span,
|
||||
modifier: constness.as_str(),
|
||||
});
|
||||
self.set_tainted_by_errors(e);
|
||||
arg_count.correct =
|
||||
Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] });
|
||||
}
|
||||
let args = lower_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
|
|
|
@ -86,6 +86,8 @@ fn enforce_impl_params_are_constrained(
|
|||
let impl_predicates = tcx.predicates_of(impl_def_id);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
|
||||
|
||||
impl_trait_ref.error_reported()?;
|
||||
|
||||
let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref);
|
||||
cgp::identify_constrained_generic_params(
|
||||
tcx,
|
||||
|
|
|
@ -1118,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// to add defaults. If the user provided *too many* types, that's
|
||||
// a problem.
|
||||
|
||||
let mut infer_args_for_err = FxHashSet::default();
|
||||
let mut infer_args_for_err = None;
|
||||
|
||||
let mut explicit_late_bound = ExplicitLateBound::No;
|
||||
for &GenericPathSegment(def_id, index) in &generic_segments {
|
||||
|
@ -1136,9 +1136,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
explicit_late_bound = ExplicitLateBound::Yes;
|
||||
}
|
||||
|
||||
if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
|
||||
infer_args_for_err.insert(index);
|
||||
self.set_tainted_by_errors(e); // See issue #53251.
|
||||
if let Err(GenericArgCountMismatch { reported, .. }) = arg_count.correct {
|
||||
infer_args_for_err
|
||||
.get_or_insert_with(|| (reported, FxHashSet::default()))
|
||||
.1
|
||||
.insert(index);
|
||||
self.set_tainted_by_errors(reported); // See issue #53251.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1232,15 +1235,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
let def_id = res.def_id();
|
||||
|
||||
let arg_count = GenericArgCountResult {
|
||||
explicit_late_bound,
|
||||
correct: if infer_args_for_err.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(GenericArgCountMismatch::default())
|
||||
},
|
||||
let (correct, infer_args_for_err) = match infer_args_for_err {
|
||||
Some((reported, args)) => {
|
||||
(Err(GenericArgCountMismatch { reported, invalid_args: vec![] }), args)
|
||||
}
|
||||
None => (Ok(()), Default::default()),
|
||||
};
|
||||
|
||||
let arg_count = GenericArgCountResult { explicit_late_bound, correct };
|
||||
|
||||
struct CtorGenericArgsCtxt<'a, 'tcx> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
|
@ -1272,6 +1275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
|
@ -1314,7 +1318,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> {
|
||||
|
@ -1328,7 +1332,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.
|
||||
|
@ -1353,7 +1357,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,6 +383,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
|
@ -419,7 +420,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> {
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
//@ known-bug: #121134
|
||||
trait Output<'a> {
|
||||
type Type;
|
||||
}
|
||||
|
||||
struct Wrapper;
|
||||
|
||||
impl Wrapper {
|
||||
fn do_something_wrapper<O, F>(&mut self, do_something_wrapper: F)
|
||||
where
|
||||
FnOnce:,
|
||||
F: for<'a> FnOnce(<F as Output<i32, _>>::Type),
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut wrapper = Wrapper;
|
||||
wrapper.do_something_wrapper::<i32, _>(|value| ());
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//@ known-bug: #123917
|
||||
//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct Id<'id>();
|
||||
|
||||
pub struct Item<'life, T> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
pub struct Token<'life, 'borrow, 'compact, 'reborrow, T>
|
||||
where
|
||||
'life: 'reborrow,
|
||||
T: Tokenize,
|
||||
{
|
||||
ptr: *mut <T as Tokenize>::Tokenized,
|
||||
ptr: core::ptr::NonNull<T::Tokenized>,
|
||||
_phantom: PhantomData<Id<'life>>,
|
||||
}
|
||||
|
||||
impl<'life> Arena<'life> {
|
||||
pub fn tokenize<'before, 'compact, 'borrow, 'reborrow, T, U>(
|
||||
item: Item<'life, &'before mut T>,
|
||||
) -> Token<'life, 'borrow, 'compact, 'reborrow, U>
|
||||
where
|
||||
T: Tokenize<'life, 'borrow, 'compact, 'reborrow, Untokenized = U>,
|
||||
T::Untokenized: Tokenize<'life, 'borrow, 'compact, 'reborrow>,
|
||||
{
|
||||
let dst = item.data as *mut T as *mut T::Tokenized;
|
||||
Token {
|
||||
ptr: core::ptr::NonNull::new(dst as *mut _).unwrap(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Tokenize {
|
||||
type Tokenized;
|
||||
type Untokenized;
|
||||
}
|
|
@ -24,7 +24,6 @@ fn via_associated_const() {
|
|||
trait Trait {
|
||||
const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR `Src` cannot be safely transmuted into `Dst`
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,28 +12,13 @@ error[E0308]: mismatched types
|
|||
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
|
||||
| ^^ expected `Assume`, found `()`
|
||||
|
||||
error[E0277]: `Src` cannot be safely transmuted into `Dst`
|
||||
--> $DIR/transmutable-ice-110969.rs:25:60
|
||||
|
|
||||
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
|
||||
| ^^^ `Dst` may carry safety invariants
|
||||
|
|
||||
note: required by a bound in `is_transmutable`
|
||||
--> $DIR/transmutable-ice-110969.rs:11:14
|
||||
|
|
||||
LL | pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
|
||||
| --------------- required by a bound in this function
|
||||
LL | where
|
||||
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/transmutable-ice-110969.rs:25:29
|
||||
|
|
||||
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0277, E0308.
|
||||
Some errors have detailed explanations: E0107, E0308.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
23
tests/ui/lifetimes/noisy-follow-up-erro.rs
Normal file
23
tests/ui/lifetimes/noisy-follow-up-erro.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
struct Foo<'c, 'd>(&'c (), &'d ());
|
||||
|
||||
impl<'c, 'd> Foo<'c, 'd> {
|
||||
fn acc(&mut self, _bar: &Bar) -> &'d () {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl<'a> Bar {
|
||||
fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
|
||||
//~^ ERROR: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
|
||||
self.bar().map_err(|()| foo.acc(self))?;
|
||||
//~^ ERROR: explicit lifetime required in the type of `foo`
|
||||
Ok(())
|
||||
}
|
||||
fn bar(&self) -> Result<(), &'a ()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
27
tests/ui/lifetimes/noisy-follow-up-erro.stderr
Normal file
27
tests/ui/lifetimes/noisy-follow-up-erro.stderr
Normal file
|
@ -0,0 +1,27 @@
|
|||
error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
|
||||
--> $DIR/noisy-follow-up-erro.rs:12:30
|
||||
|
|
||||
LL | fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
|
||||
| ^^^ -- help: remove this lifetime argument
|
||||
| |
|
||||
| expected 2 lifetime arguments
|
||||
|
|
||||
note: struct defined here, with 2 lifetime parameters: `'c`, `'d`
|
||||
--> $DIR/noisy-follow-up-erro.rs:1:8
|
||||
|
|
||||
LL | struct Foo<'c, 'd>(&'c (), &'d ());
|
||||
| ^^^ -- --
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `foo`
|
||||
--> $DIR/noisy-follow-up-erro.rs:14:9
|
||||
|
|
||||
LL | fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
|
||||
| -------------------- help: add explicit lifetime `'a` to the type of `foo`: `&mut Foo<'_, 'a>`
|
||||
LL |
|
||||
LL | self.bar().map_err(|()| foo.acc(self))?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0621.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
20
tests/ui/polymorphization/abi_mismatch.rs
Normal file
20
tests/ui/polymorphization/abi_mismatch.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
//! This test used to ICE: #123917
|
||||
//! The reason was that while the AST knows about two fields
|
||||
//! named `ptr`, only one exists at the layout level, so accessing
|
||||
//! `_extra_field` would use an oob index
|
||||
//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on
|
||||
|
||||
struct NonNull<T>(*mut T);
|
||||
|
||||
struct Token<T> {
|
||||
ptr: *mut T,
|
||||
ptr: NonNull<T>,
|
||||
//~^ ERROR: `ptr` is already declared
|
||||
_extra_field: (),
|
||||
}
|
||||
|
||||
fn tokenize<T>(item: *mut T) -> Token<T> {
|
||||
Token { ptr: NonNull(item), _extra_field: () }
|
||||
}
|
||||
|
||||
fn main() {}
|
11
tests/ui/polymorphization/abi_mismatch.stderr
Normal file
11
tests/ui/polymorphization/abi_mismatch.stderr
Normal file
|
@ -0,0 +1,11 @@
|
|||
error[E0124]: field `ptr` is already declared
|
||||
--> $DIR/abi_mismatch.rs:11:5
|
||||
|
|
||||
LL | ptr: *mut T,
|
||||
| ----------- `ptr` first declared here
|
||||
LL | ptr: NonNull<T>,
|
||||
| ^^^^^^^^^^^^^^^ field already declared
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0124`.
|
|
@ -14,14 +14,12 @@ impl<T, S> Trait<T> for i32 {
|
|||
// Should not not trigger suggestion here...
|
||||
impl<T, S> Trait<T, S> for () {}
|
||||
//~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
//~| ERROR `S` is not constrained
|
||||
|
||||
//... but should do so in all of the below cases except the last one
|
||||
fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
|
||||
//~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
//~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
//~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
//~| ERROR type annotations needed
|
||||
3
|
||||
}
|
||||
|
||||
|
|
|
@ -16,14 +16,8 @@ note: trait defined here, with 1 generic parameter: `T`
|
|||
LL | pub trait Trait<T> {
|
||||
| ^^^^^ -
|
||||
|
||||
error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:9
|
||||
|
|
||||
LL | impl<T, S> Trait<T, S> for () {}
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:12
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:12
|
||||
|
|
||||
LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -39,7 +33,7 @@ LL | fn func<T: Trait<u32, Assoc = String>>(t: T) -> impl Trait<(), i32> {
|
|||
| +++++++
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
|
||||
|
|
||||
LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -55,7 +49,7 @@ LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
|
|||
| +++++++
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
|
||||
|
|
||||
LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -71,14 +65,8 @@ help: replace the generic bound with the associated type
|
|||
LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
|
||||
| +++++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41
|
||||
|
|
||||
LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:18
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18
|
||||
|
|
||||
LL | struct Struct<T: Trait<u32, String>> {
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -94,7 +82,7 @@ LL | struct Struct<T: Trait<u32, Assoc = String>> {
|
|||
| +++++++
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:33:23
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:31:23
|
||||
|
|
||||
LL | trait AnotherTrait<T: Trait<T, i32>> {}
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -110,7 +98,7 @@ LL | trait AnotherTrait<T: Trait<T, Assoc = i32>> {}
|
|||
| +++++++
|
||||
|
||||
error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:36:9
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:34:9
|
||||
|
|
||||
LL | impl<T: Trait<u32, String>> Struct<T> {}
|
||||
| ^^^^^ expected 1 generic argument
|
||||
|
@ -126,7 +114,7 @@ LL | impl<T: Trait<u32, Assoc = String>> Struct<T> {}
|
|||
| +++++++
|
||||
|
||||
error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:42:58
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:40:58
|
||||
|
|
||||
LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
|
||||
| ^^^^^^ - help: remove this generic argument
|
||||
|
@ -134,12 +122,12 @@ LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
|
|||
| expected 1 generic argument
|
||||
|
|
||||
note: struct defined here, with 1 generic parameter: `T`
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:8
|
||||
--> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:8
|
||||
|
|
||||
LL | struct Struct<T: Trait<u32, String>> {
|
||||
| ^^^^^^ -
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0207, E0282.
|
||||
Some errors have detailed explanations: E0107, E0207.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
//! This test used to ICE: #121134
|
||||
//! The issue is that we're trying to prove a projection, but there's
|
||||
//! no bound for the projection's trait, and the projection has the wrong
|
||||
//! kind of generic parameter (lifetime vs type).
|
||||
//! When actually calling the function with those broken bounds, trying to
|
||||
//! instantiate the bounds with inference vars would ICE.
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
trait Output<'a> {
|
||||
type Type;
|
||||
}
|
||||
|
||||
struct Wrapper;
|
||||
|
||||
impl Wrapper {
|
||||
fn do_something_wrapper<O, F>(&mut self, _: F)
|
||||
where
|
||||
F: for<'a> FnOnce(<F as Output<i32>>::Type),
|
||||
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut wrapper = Wrapper;
|
||||
wrapper.do_something_wrapper(|value| ());
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:18:33
|
||||
|
|
||||
LL | F: for<'a> FnOnce(<F as Output<i32>>::Type),
|
||||
| ^^^^^^ expected 0 generic arguments
|
||||
|
|
||||
note: trait defined here, with 0 generic parameters
|
||||
--> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:9:7
|
||||
|
|
||||
LL | trait Output<'a> {
|
||||
| ^^^^^^
|
||||
help: replace the generic bound with the associated type
|
||||
|
|
||||
LL | F: for<'a> FnOnce(<F as Output<Type = i32>>::Type),
|
||||
| ++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
|
@ -55,12 +55,6 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
|||
= help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
||||
--> $DIR/issue-78372.rs:3:1
|
||||
|
|
||||
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/issue-78372.rs:12:17
|
||||
|
|
||||
|
@ -88,6 +82,12 @@ LL | fn foo(self: Smaht<Self, T>);
|
|||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
||||
--> $DIR/issue-78372.rs:3:1
|
||||
|
|
||||
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658.
|
||||
|
|
|
@ -15,7 +15,6 @@ mod assert {
|
|||
>()
|
||||
where
|
||||
Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
|
||||
//~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
||||
Src,
|
||||
ASSUME_ALIGNMENT, //~ ERROR: mismatched types
|
||||
ASSUME_LIFETIMES,
|
||||
|
|
|
@ -9,29 +9,13 @@ LL | | ASSUME_VALIDITY,
|
|||
LL | | ASSUME_VISIBILITY,
|
||||
| |_____________________________- help: remove these generic arguments
|
||||
|
||||
error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
||||
--> $DIR/issue-101739-2.rs:17:14
|
||||
|
|
||||
LL | Dst: BikeshedIntrinsicFrom<
|
||||
| ______________^
|
||||
LL | |
|
||||
LL | | Src,
|
||||
LL | | ASSUME_ALIGNMENT,
|
||||
... |
|
||||
LL | | ASSUME_VISIBILITY,
|
||||
LL | | >,
|
||||
| |_________^ expected `Assume`, found `bool`
|
||||
|
|
||||
note: required by a bound in `BikeshedIntrinsicFrom`
|
||||
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-101739-2.rs:20:13
|
||||
--> $DIR/issue-101739-2.rs:19:13
|
||||
|
|
||||
LL | ASSUME_ALIGNMENT,
|
||||
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0308.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue