Auto merge of #116688 - compiler-errors:rustfmt-up, r=WaffleLapkin,Nilstrieb
Format all the let-chains in compiler crates
Since rust-lang/rustfmt#5910 has landed, soon we will have support for formatting let-chains (as soon as rustfmt syncs and beta gets bumped).
This PR applies the changes [from master rustfmt to rust-lang/rust eagerly](374997516
), so that the next beta bump does not have to deal with a 200+ file diff and can remain concerned with other things like `cfg(bootstrap)` -- #113637 was a pain to land, for example, because of let-else.
I will also add this commit to the ignore list after it has landed.
The commands that were run -- I'm not great at bash-foo, but this applies rustfmt to every compiler crate, and then reverts the two crates that should probably be formatted out-of-tree.
```
~/rustfmt $ ls -1d ~/rust/compiler/* | xargs -I@ cargo run --bin rustfmt -- `@/src/lib.rs` --config-path ~/rust --edition=2021 # format all of the compiler crates
~/rust $ git checkout HEAD -- compiler/rustc_codegen_{gcc,cranelift} # revert changes to cg-gcc and cg-clif
```
cc `@rust-lang/rustfmt`
r? `@WaffleLapkin` or `@Nilstrieb` who said they may be able to review this purely mechanical PR :>
cc `@Mark-Simulacrum` and `@petrochenkov,` who had some thoughts on the order of operations with big formatting changes in https://github.com/rust-lang/rust/pull/95262#issue-1178993801. I think the situation has changed since then, given that let-chains support exists on master rustfmt now, and I'm fairly confident that this formatting PR should land even if *bootstrap* rustfmt doesn't yet format let-chains in order to lessen the burden of the next beta bump.
This commit is contained in:
commit
a48396984a
207 changed files with 3121 additions and 2229 deletions
|
@ -517,8 +517,10 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||
);
|
||||
|
||||
if let DefKind::AssocConst = def_kind
|
||||
&& let Some(t) = term.ty() && (t.is_enum() || t.references_error())
|
||||
&& tcx.features().associated_const_equality {
|
||||
&& let Some(t) = term.ty()
|
||||
&& (t.is_enum() || t.references_error())
|
||||
&& tcx.features().associated_const_equality
|
||||
{
|
||||
err.span_suggestion(
|
||||
binding.span,
|
||||
"if equating a const, try wrapping with braces",
|
||||
|
|
|
@ -432,9 +432,11 @@ pub(crate) fn check_generic_arg_count(
|
|||
let infer_lifetimes =
|
||||
(gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
|
||||
|
||||
if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() {
|
||||
prohibit_assoc_ty_binding(tcx, b.span, None);
|
||||
}
|
||||
if gen_pos != GenericArgPosition::Type
|
||||
&& let Some(b) = gen_args.bindings.first()
|
||||
{
|
||||
prohibit_assoc_ty_binding(tcx, b.span, None);
|
||||
}
|
||||
|
||||
let explicit_late_bound =
|
||||
prohibit_explicit_late_bound_lifetimes(tcx, gen_params, gen_args, gen_pos);
|
||||
|
|
|
@ -18,18 +18,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Impl(hir::Impl {
|
||||
self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
|
||||
self_ty: impl_self_ty,
|
||||
of_trait: Some(of_trait_ref),
|
||||
generics,
|
||||
..
|
||||
}),
|
||||
..
|
||||
}) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
|
||||
}) = tcx.hir().get_by_def_id(parent_id)
|
||||
&& self_ty.hir_id == impl_self_ty.hir_id
|
||||
{
|
||||
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
|
||||
return;
|
||||
}
|
||||
let of_trait_span = of_trait_ref.path.span;
|
||||
// make sure that we are not calling unwrap to abort during the compilation
|
||||
let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
|
||||
let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
|
||||
let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
|
||||
return;
|
||||
};
|
||||
let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else {
|
||||
return;
|
||||
};
|
||||
// check if the trait has generics, to make a correct suggestion
|
||||
let param_name = generics.params.next_type_param_name(None);
|
||||
|
||||
|
@ -39,13 +47,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
(generics.span, format!("<{param_name}: {impl_trait_name}>"))
|
||||
};
|
||||
diag.multipart_suggestion(
|
||||
format!("alternatively use a blanket \
|
||||
format!(
|
||||
"alternatively use a blanket \
|
||||
implementation to implement `{of_trait_name}` for \
|
||||
all types that also implement `{impl_trait_name}`"),
|
||||
vec![
|
||||
(self_ty.span, param_name),
|
||||
add_generic_sugg,
|
||||
],
|
||||
all types that also implement `{impl_trait_name}`"
|
||||
),
|
||||
vec![(self_ty.span, param_name), add_generic_sugg],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -567,9 +567,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
);
|
||||
|
||||
if let ty::BoundConstness::ConstIfConst = constness
|
||||
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
|
||||
&& generics.has_self
|
||||
&& !tcx.has_attr(def_id, sym::const_trait)
|
||||
{
|
||||
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
|
||||
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span });
|
||||
}
|
||||
|
||||
(args, arg_count)
|
||||
|
@ -1919,9 +1920,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
} else {
|
||||
Some((
|
||||
match segment.res {
|
||||
Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()),
|
||||
Res::PrimTy(ty) => {
|
||||
format!("{} `{}`", segment.res.descr(), ty.name())
|
||||
}
|
||||
Res::Def(_, def_id)
|
||||
if let Some(name) = self.tcx().opt_item_name(def_id) => {
|
||||
if let Some(name) = self.tcx().opt_item_name(def_id) =>
|
||||
{
|
||||
format!("{} `{name}`", segment.res.descr())
|
||||
}
|
||||
Res::Err => "this type".to_string(),
|
||||
|
@ -2251,7 +2255,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
err.note(msg);
|
||||
}
|
||||
for segment in path.segments {
|
||||
if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper {
|
||||
if let Some(args) = segment.args
|
||||
&& segment.ident.name == kw::SelfUpper
|
||||
{
|
||||
if generics == 0 {
|
||||
// FIXME(estebank): we could also verify that the arguments being
|
||||
// work for the `enum`, instead of just looking if it takes *any*.
|
||||
|
@ -2633,7 +2639,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, a)| {
|
||||
if let hir::TyKind::Infer = a.kind && !self.allow_ty_infer() {
|
||||
if let hir::TyKind::Infer = a.kind
|
||||
&& !self.allow_ty_infer()
|
||||
{
|
||||
if let Some(suggested_ty) =
|
||||
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
|
||||
{
|
||||
|
@ -2662,7 +2670,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.ast_ty_to_ty(output)
|
||||
}
|
||||
}
|
||||
hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx,),
|
||||
hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx),
|
||||
};
|
||||
|
||||
debug!(?output_ty);
|
||||
|
|
|
@ -481,8 +481,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
|
||||
}
|
||||
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
|
||||
let trait_args =
|
||||
GenericArgs::identity_for_item(tcx, id.owner_id);
|
||||
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
|
||||
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
|
||||
tcx,
|
||||
assoc_item,
|
||||
|
@ -502,7 +501,8 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
}
|
||||
DefKind::OpaqueTy => {
|
||||
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
|
||||
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
|
||||
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
|
||||
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
|
||||
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
|
||||
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
|
||||
{
|
||||
|
@ -589,7 +589,9 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
}
|
||||
DefKind::GlobalAsm => {
|
||||
let it = tcx.hir().item(id);
|
||||
let hir::ItemKind::GlobalAsm(asm) = it.kind else { span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) };
|
||||
let hir::ItemKind::GlobalAsm(asm) = it.kind else {
|
||||
span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
|
||||
};
|
||||
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -873,10 +875,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
|||
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
|
||||
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
|
||||
ty::Array(t, _clen)
|
||||
if matches!(
|
||||
t.kind(),
|
||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
|
||||
) =>
|
||||
if matches!(t.kind(), ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)) =>
|
||||
{ /* struct([f32; 4]) is ok */ }
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
|
@ -899,17 +898,17 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
|||
for attr in tcx.get_attrs(def.did(), sym::repr) {
|
||||
for r in attr::parse_repr_attr(&tcx.sess, attr) {
|
||||
if let attr::ReprPacked(pack) = r
|
||||
&& let Some(repr_pack) = repr.pack
|
||||
&& pack as u64 != repr_pack.bytes()
|
||||
{
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0634,
|
||||
"type has conflicting packed representation hints"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
&& let Some(repr_pack) = repr.pack
|
||||
&& pack as u64 != repr_pack.bytes()
|
||||
{
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0634,
|
||||
"type has conflicting packed representation hints"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
if repr.align.is_some() {
|
||||
|
@ -1174,7 +1173,8 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
|||
let (span, display_discr) = match var.discr {
|
||||
ty::VariantDiscr::Explicit(discr_def_id) => {
|
||||
// In the case the discriminant is both a duplicate and overflowed, let the user know
|
||||
if let hir::Node::AnonConst(expr) = tcx.hir().get_by_def_id(discr_def_id.expect_local())
|
||||
if let hir::Node::AnonConst(expr) =
|
||||
tcx.hir().get_by_def_id(discr_def_id.expect_local())
|
||||
&& let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
|
||||
&& let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
|
||||
&& *lit_value != dis.val
|
||||
|
@ -1303,15 +1303,9 @@ pub(super) fn check_type_params_are_used<'tcx>(
|
|||
&& let ty::GenericParamDefKind::Type { .. } = param.kind
|
||||
{
|
||||
let span = tcx.def_span(param.def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0091,
|
||||
"type parameter `{}` is unused",
|
||||
param.name,
|
||||
)
|
||||
.span_label(span, "unused type parameter")
|
||||
.emit();
|
||||
struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name,)
|
||||
.span_label(span, "unused type parameter")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1430,7 +1424,10 @@ fn opaque_type_cycle_error(
|
|||
let mut label_match = |ty: Ty<'_>, span| {
|
||||
for arg in ty.walk() {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Alias(ty::Opaque, ty::AliasTy { def_id: captured_def_id, .. }) = *ty.kind()
|
||||
&& let ty::Alias(
|
||||
ty::Opaque,
|
||||
ty::AliasTy { def_id: captured_def_id, .. },
|
||||
) = *ty.kind()
|
||||
&& captured_def_id == opaque_def_id.to_def_id()
|
||||
{
|
||||
err.span_label(
|
||||
|
|
|
@ -1009,7 +1009,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
});
|
||||
self.types.insert(proj.def_id, (infer_ty, proj.args));
|
||||
// Recurse into bounds
|
||||
for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).iter_instantiated_copied(self.interner(), proj.args) {
|
||||
for (pred, pred_span) in self
|
||||
.interner()
|
||||
.explicit_item_bounds(proj.def_id)
|
||||
.iter_instantiated_copied(self.interner(), proj.args)
|
||||
{
|
||||
let pred = pred.fold_with(self);
|
||||
let pred = self.ocx.normalize(
|
||||
&ObligationCause::misc(self.span, self.body_id),
|
||||
|
@ -1180,7 +1184,8 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
if trait_sig.inputs().len() == *i {
|
||||
// Suggestion to change output type. We do not suggest in `async` functions
|
||||
// to avoid complex logic or incorrect output.
|
||||
if let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
|
||||
if let ImplItemKind::Fn(sig, _) =
|
||||
&tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
|
||||
&& !sig.header.asyncness.is_async()
|
||||
{
|
||||
let msg = "change the output type to match the trait";
|
||||
|
|
|
@ -550,9 +550,11 @@ fn infringing_fields_error(
|
|||
.entry((ty.clone(), predicate.clone()))
|
||||
.or_default()
|
||||
.push(origin.span());
|
||||
if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() {
|
||||
bounds.push((b.to_string(), a.to_string(), None));
|
||||
}
|
||||
if let ty::RegionKind::ReEarlyBound(ebr) = *b
|
||||
&& ebr.has_name()
|
||||
{
|
||||
bounds.push((b.to_string(), a.to_string(), None));
|
||||
}
|
||||
}
|
||||
RegionResolutionError::GenericBoundFailure(origin, a, b) => {
|
||||
let predicate = format!("{a}: {b}");
|
||||
|
|
|
@ -212,7 +212,9 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
|
|||
let mut is_fn = false;
|
||||
let mut is_const_or_static = false;
|
||||
|
||||
if let Some(hir_ty) = hir_ty && let hir::TyKind::BareFn(_) = hir_ty.kind {
|
||||
if let Some(hir_ty) = hir_ty
|
||||
&& let hir::TyKind::BareFn(_) = hir_ty.kind
|
||||
{
|
||||
is_fn = true;
|
||||
|
||||
// Check if parent is const or static
|
||||
|
@ -224,10 +226,8 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
|
|||
Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
|
||||
..
|
||||
}) | Node::TraitItem(&hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Const(..),
|
||||
..
|
||||
}) | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
||||
}) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
|
||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1004,10 +1004,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
|||
&& let Some(lit) = meta.name_value_literal()
|
||||
{
|
||||
if seen_attr {
|
||||
tcx.sess.span_err(
|
||||
meta.span,
|
||||
"duplicated `implement_via_object` meta item",
|
||||
);
|
||||
tcx.sess.span_err(meta.span, "duplicated `implement_via_object` meta item");
|
||||
}
|
||||
seen_attr = true;
|
||||
|
||||
|
@ -1021,7 +1018,10 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
|||
_ => {
|
||||
tcx.sess.span_err(
|
||||
meta.span,
|
||||
format!("unknown literal passed to `implement_via_object` attribute: {}", lit.symbol),
|
||||
format!(
|
||||
"unknown literal passed to `implement_via_object` attribute: {}",
|
||||
lit.symbol
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1115,8 +1115,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
|
|||
|
||||
ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
|
||||
// Do not try to infer the return type for a impl method coming from a trait
|
||||
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
|
||||
tcx.hir().get_parent(hir_id)
|
||||
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.hir().get_parent(hir_id)
|
||||
&& i.of_trait.is_some()
|
||||
{
|
||||
icx.astconv().ty_of_fn(
|
||||
|
@ -1343,7 +1342,13 @@ fn suggest_impl_trait<'tcx>(
|
|||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||
&& let Some(item_ty) = item_ty.make_suggestable(tcx, false)
|
||||
&& let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(args), trait_def_id, assoc_item_def_id, item_ty)
|
||||
&& let Some(sugg) = formatter(
|
||||
tcx,
|
||||
infcx.resolve_vars_if_possible(args),
|
||||
trait_def_id,
|
||||
assoc_item_def_id,
|
||||
item_ty,
|
||||
)
|
||||
{
|
||||
return Some(sugg);
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTyToOpaque<'tcx> {
|
|||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
|
||||
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. })
|
||||
= self.tcx.opt_rpitit_info(projection_ty.def_id)
|
||||
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
|
||||
self.tcx.opt_rpitit_info(projection_ty.def_id)
|
||||
&& fn_def_id == self.fn_def_id
|
||||
{
|
||||
self.tcx.type_of(projection_ty.def_id).instantiate(self.tcx, projection_ty.args)
|
||||
|
|
|
@ -389,7 +389,9 @@ fn const_evaluatable_predicates_of(
|
|||
let node = tcx.hir().get(hir_id);
|
||||
|
||||
let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
|
||||
if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(impl_) = item.kind {
|
||||
if let hir::Node::Item(item) = node
|
||||
&& let hir::ItemKind::Impl(impl_) = item.kind
|
||||
{
|
||||
if let Some(of_trait) = &impl_.of_trait {
|
||||
debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
|
||||
collector.visit_trait_ref(of_trait);
|
||||
|
|
|
@ -1190,7 +1190,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
Scope::Root { opt_parent_item } => {
|
||||
if let Some(parent_item) = opt_parent_item
|
||||
&& let parent_generics = self.tcx.generics_of(parent_item)
|
||||
&& parent_generics.param_def_id_to_index(self.tcx, region_def_id.to_def_id()).is_some()
|
||||
&& parent_generics
|
||||
.param_def_id_to_index(self.tcx, region_def_id.to_def_id())
|
||||
.is_some()
|
||||
{
|
||||
break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id()));
|
||||
}
|
||||
|
@ -1209,13 +1211,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
// regular fns.
|
||||
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
|
||||
&& let hir::LifetimeName::Param(param_id) = lifetime_ref.res
|
||||
&& let Some(generics) = self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
|
||||
&& let Some(generics) =
|
||||
self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
|
||||
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
|
||||
&& param.is_elided_lifetime()
|
||||
&& !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
|
||||
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
|
||||
{
|
||||
let mut diag = rustc_session::parse::feature_err(
|
||||
let mut diag = rustc_session::parse::feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::anonymous_lifetime_in_impl_trait,
|
||||
lifetime_ref.ident.span,
|
||||
|
@ -1225,25 +1228,31 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
if let Some(generics) =
|
||||
self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id)
|
||||
{
|
||||
let new_param_sugg = if let Some(span) =
|
||||
generics.span_for_lifetime_suggestion()
|
||||
{
|
||||
(span, "'a, ".to_owned())
|
||||
} else {
|
||||
(generics.span, "<'a>".to_owned())
|
||||
};
|
||||
let new_param_sugg =
|
||||
if let Some(span) = generics.span_for_lifetime_suggestion() {
|
||||
(span, "'a, ".to_owned())
|
||||
} else {
|
||||
(generics.span, "<'a>".to_owned())
|
||||
};
|
||||
|
||||
let lifetime_sugg = match lifetime_ref.suggestion_position() {
|
||||
(hir::LifetimeSuggestionPosition::Normal, span) => (span, "'a".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::Ampersand, span) => (span, "'a ".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ElidedPath, span) => (span, "<'a>".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => (span, "'a, ".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ObjectDefault, span) => (span, "+ 'a".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::Normal, span) => {
|
||||
(span, "'a".to_owned())
|
||||
}
|
||||
(hir::LifetimeSuggestionPosition::Ampersand, span) => {
|
||||
(span, "'a ".to_owned())
|
||||
}
|
||||
(hir::LifetimeSuggestionPosition::ElidedPath, span) => {
|
||||
(span, "<'a>".to_owned())
|
||||
}
|
||||
(hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => {
|
||||
(span, "'a, ".to_owned())
|
||||
}
|
||||
(hir::LifetimeSuggestionPosition::ObjectDefault, span) => {
|
||||
(span, "+ 'a".to_owned())
|
||||
}
|
||||
};
|
||||
let suggestions = vec![
|
||||
lifetime_sugg,
|
||||
new_param_sugg,
|
||||
];
|
||||
let suggestions = vec![lifetime_sugg, new_param_sugg];
|
||||
|
||||
diag.span_label(
|
||||
lifetime_ref.ident.span,
|
||||
|
@ -1378,7 +1387,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
Scope::Root { opt_parent_item } => {
|
||||
if let Some(parent_item) = opt_parent_item
|
||||
&& let parent_generics = self.tcx.generics_of(parent_item)
|
||||
&& parent_generics.param_def_id_to_index(self.tcx, param_def_id.to_def_id()).is_some()
|
||||
&& parent_generics
|
||||
.param_def_id_to_index(self.tcx, param_def_id.to_def_id())
|
||||
.is_some()
|
||||
{
|
||||
break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id()));
|
||||
}
|
||||
|
@ -1689,14 +1700,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
|
||||
let bound_vars = if let Some(type_def_id) = type_def_id
|
||||
&& self.tcx.def_kind(type_def_id) == DefKind::Trait
|
||||
&& let Some((mut bound_vars, assoc_fn)) =
|
||||
BoundVarContext::supertrait_hrtb_vars(
|
||||
self.tcx,
|
||||
type_def_id,
|
||||
binding.ident,
|
||||
ty::AssocKind::Fn,
|
||||
)
|
||||
{
|
||||
&& let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars(
|
||||
self.tcx,
|
||||
type_def_id,
|
||||
binding.ident,
|
||||
ty::AssocKind::Fn,
|
||||
) {
|
||||
bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).params.iter().map(
|
||||
|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region(
|
||||
|
@ -1708,14 +1717,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const,
|
||||
},
|
||||
));
|
||||
bound_vars
|
||||
.extend(self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars());
|
||||
bound_vars.extend(
|
||||
self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars(),
|
||||
);
|
||||
bound_vars
|
||||
} else {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
binding.ident.span,
|
||||
"bad return type notation here",
|
||||
);
|
||||
self.tcx
|
||||
.sess
|
||||
.delay_span_bug(binding.ident.span, "bad return type notation here");
|
||||
vec![]
|
||||
};
|
||||
self.with(scope, |this| {
|
||||
|
|
|
@ -30,10 +30,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
if constant.hir_id() == hir_id =>
|
||||
{
|
||||
return tcx.types.usize
|
||||
return tcx.types.usize;
|
||||
}
|
||||
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
|
||||
return tcx.typeck(def_id).node_type(e.hir_id)
|
||||
return tcx.typeck(def_id).node_type(e.hir_id);
|
||||
}
|
||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
|
||||
|
@ -43,36 +43,38 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
_ => false,
|
||||
}) =>
|
||||
{
|
||||
return tcx.typeck(def_id).node_type(hir_id)
|
||||
return tcx.typeck(def_id).node_type(hir_id);
|
||||
}
|
||||
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
|
||||
return tcx
|
||||
.adt_def(tcx.hir().get_parent_item(hir_id))
|
||||
.repr()
|
||||
.discr_type()
|
||||
.to_ty(tcx)
|
||||
return tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx);
|
||||
}
|
||||
Node::GenericParam(&GenericParam {
|
||||
def_id: param_def_id,
|
||||
kind: GenericParamKind::Const { default: Some(ct), .. },
|
||||
..
|
||||
}) if ct.hir_id == hir_id => {
|
||||
return tcx.type_of(param_def_id)
|
||||
return tcx
|
||||
.type_of(param_def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic")
|
||||
.expect("const parameter types cannot be generic");
|
||||
}
|
||||
|
||||
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
|
||||
if let Node::TraitRef(trait_ref) = tcx.hir().get(
|
||||
tcx.hir().parent_id(binding_id)
|
||||
) =>
|
||||
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
|
||||
if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) =>
|
||||
{
|
||||
let Some(trait_def_id) = trait_ref.trait_def_id() else {
|
||||
return Ty::new_error_with_message(tcx,tcx.def_span(def_id), "Could not find trait");
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
"Could not find trait",
|
||||
);
|
||||
};
|
||||
let assoc_items = tcx.associated_items(trait_def_id);
|
||||
let assoc_item = assoc_items.find_by_name_and_kind(
|
||||
tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
|
||||
tcx,
|
||||
binding.ident,
|
||||
ty::AssocKind::Const,
|
||||
def_id.to_def_id(),
|
||||
);
|
||||
return if let Some(assoc_item) = assoc_item {
|
||||
tcx.type_of(assoc_item.def_id)
|
||||
|
@ -80,8 +82,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
.expect("const parameter types cannot be generic")
|
||||
} else {
|
||||
// FIXME(associated_const_equality): add a useful error message here.
|
||||
Ty::new_error_with_message(tcx,tcx.def_span(def_id), "Could not find associated const on trait")
|
||||
}
|
||||
Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
"Could not find associated const on trait",
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// This match arm is for when the def_id appears in a GAT whose
|
||||
|
@ -138,7 +144,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
(generics, arg_index)
|
||||
} else {
|
||||
// I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
"unexpected non-GAT usage of an anon const",
|
||||
);
|
||||
|
@ -155,7 +162,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
// As there is no relevant param for `def_id`, we simply return
|
||||
// `None` here.
|
||||
let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else {
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unable to find type-dependent def for {parent_node_id:?}"),
|
||||
);
|
||||
|
@ -196,14 +204,16 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
|
||||
path
|
||||
} else {
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unable to find const parent for {hir_id} in pat {pat:?}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unexpected const parent path {parent_node:?}"),
|
||||
);
|
||||
|
@ -216,16 +226,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| {
|
||||
let args = seg.args?;
|
||||
args.args
|
||||
.iter()
|
||||
.filter(|arg| arg.is_ty_or_const())
|
||||
.position(|arg| arg.hir_id() == hir_id)
|
||||
.map(|index| (index, seg)).or_else(|| args.bindings
|
||||
.iter()
|
||||
.filter_map(TypeBinding::opt_const)
|
||||
.position(|ct| ct.hir_id == hir_id)
|
||||
.map(|idx| (idx, seg)))
|
||||
.filter(|arg| arg.is_ty_or_const())
|
||||
.position(|arg| arg.hir_id() == hir_id)
|
||||
.map(|index| (index, seg))
|
||||
.or_else(|| {
|
||||
args.bindings
|
||||
.iter()
|
||||
.filter_map(TypeBinding::opt_const)
|
||||
.position(|ct| ct.hir_id == hir_id)
|
||||
.map(|idx| (idx, seg))
|
||||
})
|
||||
}) else {
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
"no arg matching AnonConst in path",
|
||||
);
|
||||
|
@ -234,7 +248,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
let generics = match tcx.res_generics_def_id(segment.res) {
|
||||
Some(def_id) => tcx.generics_of(def_id),
|
||||
None => {
|
||||
return Ty::new_error_with_message(tcx,
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
|
||||
);
|
||||
|
@ -244,10 +259,13 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
(generics, arg_index)
|
||||
}
|
||||
|
||||
_ => return Ty::new_error_with_message(tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unexpected const parent in type_of(): {parent_node:?}"),
|
||||
),
|
||||
_ => {
|
||||
return Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(def_id),
|
||||
format!("unexpected const parent in type_of(): {parent_node:?}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
debug!(?parent_node);
|
||||
|
|
|
@ -226,7 +226,9 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
|
|||
let mut suggested = false;
|
||||
// Don't suggest setting the type params if there are some already: the order is
|
||||
// tricky to get right and the user will already know what the syntax is.
|
||||
if let Some(snippet) = self.span_snippet && self.empty_generic_args {
|
||||
if let Some(snippet) = self.span_snippet
|
||||
&& self.empty_generic_args
|
||||
{
|
||||
if snippet.ends_with('>') {
|
||||
// The user wrote `Trait<'a, T>` or similar. To provide an accurate suggestion
|
||||
// we would have to preserve the right order. For now, as clearly the user is
|
||||
|
|
|
@ -131,7 +131,9 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
|
|||
}
|
||||
|
||||
fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
|
||||
if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() {
|
||||
if let Node::Impl(impl2_id) = impl2_node
|
||||
&& tcx.associated_item_def_ids(impl1_def_id).is_empty()
|
||||
{
|
||||
let base_impl_span = tcx.def_span(impl2_id);
|
||||
tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span });
|
||||
}
|
||||
|
|
|
@ -316,12 +316,18 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Suggest `'_` when in function parameter or elided function return.
|
||||
if let Some(fn_decl) = node.fn_decl() && let Some(ty_id) = ty_id {
|
||||
if let Some(fn_decl) = node.fn_decl()
|
||||
&& let Some(ty_id) = ty_id
|
||||
{
|
||||
let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id);
|
||||
let in_ret = matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);
|
||||
let in_ret =
|
||||
matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);
|
||||
|
||||
if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) {
|
||||
return std::iter::repeat("'_".to_owned()).take(num_params_to_take).collect::<Vec<_>>().join(", ");
|
||||
return std::iter::repeat("'_".to_owned())
|
||||
.take(num_params_to_take)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,28 +736,27 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
);
|
||||
|
||||
if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
|
||||
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
|
||||
&& let hir::Node::Expr(expr) = parent_node {
|
||||
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
|
||||
&& let hir::Node::Expr(expr) = parent_node
|
||||
{
|
||||
match &expr.kind {
|
||||
hir::ExprKind::Path(qpath) => {
|
||||
self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||
hir::ExprKind::Path(qpath) => self
|
||||
.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||
err,
|
||||
qpath,
|
||||
msg,
|
||||
num_assoc_fn_excess_args,
|
||||
num_trait_generics_except_self
|
||||
)
|
||||
},
|
||||
hir::ExprKind::MethodCall(..) => {
|
||||
self.suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||
num_trait_generics_except_self,
|
||||
),
|
||||
hir::ExprKind::MethodCall(..) => self
|
||||
.suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||
err,
|
||||
trait_,
|
||||
expr,
|
||||
msg,
|
||||
num_assoc_fn_excess_args,
|
||||
num_trait_generics_except_self
|
||||
)
|
||||
},
|
||||
num_trait_generics_except_self,
|
||||
),
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
|
@ -766,23 +771,25 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
num_trait_generics_except_self: usize,
|
||||
) {
|
||||
if let hir::QPath::Resolved(_, path) = qpath
|
||||
&& let Some(trait_path_segment) = path.segments.get(0) {
|
||||
&& let Some(trait_path_segment) = path.segments.get(0)
|
||||
{
|
||||
let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
|
||||
|
||||
if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self
|
||||
if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args
|
||||
== num_trait_generics_except_self
|
||||
{
|
||||
if let Some(span) = self.gen_args.span_ext()
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
let sugg = vec![
|
||||
(self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)),
|
||||
(span.with_lo(self.path_segment.ident.span.hi()), "".to_owned())
|
||||
(
|
||||
self.path_segment.ident.span,
|
||||
format!("{}::{}", snippet, self.path_segment.ident),
|
||||
),
|
||||
(span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
|
||||
];
|
||||
|
||||
err.multipart_suggestion(
|
||||
msg,
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect
|
||||
);
|
||||
err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue