Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
tcx.ensure_ok().type_of(def_id);
tcx.ensure_ok().clauses_of(def_id);
let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id);
let span = match tcx.hir_node_by_def_id(def_id).alias_ty() {
Some(ty) => ty.span,
_ => tcx.def_span(def_id),
};

if tcx.type_alias_is_checked(def_id) {
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
let item_ty = wfcx.deeply_normalize(span, WellFormedLoc::Ty(def_id), ty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ use GenericArgsInfo::*;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, Diagnostic, MultiSpan, pluralize};
use rustc_hir as hir;
use rustc_middle::ty::{self as ty, AssocItem, AssocItems, TyCtxt};
use rustc_hir::def::DefKind;
use rustc_middle::ty::{self as ty, AssocItem, AssocItems, Ty, TyCtxt};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{Symbol, kw};
use tracing::debug;

/// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
Expand Down Expand Up @@ -442,6 +444,17 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
&self,
num_params_to_take: usize,
) -> String {
self.get_type_or_const_arg_names(num_params_to_take)
.map(|(n, _)| n.to_string())
.intersperse(", ".to_string())
.collect()
}

// Lists type or constant names from the provided parameter names
fn get_type_or_const_arg_names(
&self,
num_params_to_take: usize,
) -> impl Iterator<Item = (Symbol, Option<Ty<'tcx>>)> {
let is_in_a_method_call = self
.tcx
.hir_parent_iter(self.path_segment.hir_id)
Expand All @@ -458,7 +471,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
});

let fn_sig = self.tcx.hir_get_if_local(self.def_id).and_then(hir::Node::fn_sig);
let is_used_in_input = |def_id| {
let is_used_in_input = move |def_id| {
fn_sig.is_some_and(|fn_sig| {
fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(
Expand All @@ -474,18 +487,21 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
.iter()
.skip(self.params_offset + self.num_provided_type_or_const_args())
.take(num_params_to_take)
.map(|param| match param.kind {
.map(move |param| match param.kind {
// If it's in method call (turbofish), it might be inferred from the expression (e.g. `.collect::<Vec<_>>()`)
// If it is being inferred from the item's inputs, no need to set it.
ty::GenericParamDefKind::Type { .. }
if is_in_a_method_call || is_used_in_input(param.def_id) =>
{
"_"
(kw::Underscore, None)
}
_ => param.name.as_str(),
// FIXME: tcx.type_of(param.def_id) for consts
ty::GenericParamDefKind::Const { .. } => (
param.name,
Some(self.tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip()),
),
_ => (param.name, None),
})
.intersperse(", ")
.collect()
}

fn get_unbound_associated_item(&self) -> Vec<&AssocItem> {
Expand Down Expand Up @@ -715,22 +731,39 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {

let suggested_args =
self.get_type_or_const_args_suggestions_from_param_names(num_missing_args);
let arg_names: Vec<_> = self.get_type_or_const_arg_names(num_missing_args).collect();
debug!("suggested_args: {:?}", suggested_args);
let mut impl_sugg = None;
if let DefKind::Impl { .. } = self.tcx.def_kind(self.cx_def_id) {
let mut impl_args = vec![];
let i = self.tcx.hir_node_by_def_id(self.cx_def_id).expect_item().expect_impl();
for (arg, const_ty) in arg_names {
if i.generics.get_named(arg).is_none() {
impl_args.push(match const_ty {
Some(ty) => format!("const {arg}: {ty}"),
None => arg.to_string(),
})
}
}
if !impl_args.is_empty() {
impl_sugg = Some(match i.generics.span_for_param_suggestion() {
Some(span) => (span, format!(", {}", impl_args.join(", "))),
None => (i.generics.span, format!("<{}>", impl_args.join(", "))),
});
}
}

match self.angle_brackets {
AngleBrackets::Missing | AngleBrackets::Implied => {
let span = self.path_segment.ident.span;

// insert a suggestion of the form "Y<T, U>"
let sugg = format!("<{suggested_args}>");
debug!("sugg: {:?}", sugg);

err.span_suggestion_verbose(
span.shrink_to_hi(),
msg,
sugg,
Applicability::HasPlaceholders,
);
let mut sugg = vec![(span.shrink_to_hi(), format!("<{suggested_args}>"))];
if let Some(impl_sugg) = impl_sugg {
sugg.insert(0, impl_sugg);
}
debug!(?sugg);
err.multipart_suggestion(msg, sugg, Applicability::HasPlaceholders);
}
AngleBrackets::Available => {
let gen_args_span = self.gen_args.span().unwrap();
Expand All @@ -755,10 +788,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
let sugg_suffix =
if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" };

let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
debug!("sugg: {:?}", sugg);

err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
let mut sugg =
vec![(sugg_span, format!("{sugg_prefix}{suggested_args}{sugg_suffix}"))];
if let Some(impl_sugg) = impl_sugg {
sugg.insert(0, impl_sugg);
}
debug!(?sugg);
err.multipart_suggestion(msg, sugg, Applicability::HasPlaceholders);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ use rustc_middle::ty::print::{
};
use rustc_middle::ty::transmute::{Answer, Reason};
use rustc_middle::ty::{
self, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast,
self, ConstKind, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast,
};
use rustc_span::def_id::CrateNum;
use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, bug, span_bug, sym};
Expand Down Expand Up @@ -872,6 +872,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
format!("the constant `{ct_str}` is not of type `{expected_ty_str}`"),
);
diag.long_ty_path = long_ty_file;
if let ConstKind::Param(param_const) = ct.kind() {
for param in self
.tcx
.generics_of(obligation.cause.body_def_id.to_def_id())
.own_params
.iter()
{
if let GenericParamDefKind::Const { .. } = param.kind
&& param.index == param_const.index
&& param.name == param_const.name
{
let span = self.tcx.def_span(param.def_id);
diag.span_label(span, format!("`{}` defined here", param.name));
}
}
}

self.note_type_err(
&mut diag,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-inherent-types/issue-109768.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ LL | struct Local<T, U>(T, U);
| ^^^^^ - -
help: add missing generic arguments
|
LL | impl<T> Local<T, U> {
| ++++++
LL | impl<T, U> Local<T, U> {
| +++ ++++++

error[E0658]: inherent associated types are unstable
--> $DIR/issue-109768.rs:8:5
Expand Down
28 changes: 14 additions & 14 deletions tests/ui/associated-types/associated-types-eq-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ LL | trait Tr2<T1, T2, T3> {
| ^^^ -- -- --
help: add missing generic arguments
|
LL | impl Tr2<i32, T2, T3, T2 = Qux, T3 = usize> for Bar {
| ++++++++
LL | impl<T2, T3> Tr2<i32, T2, T3, T2 = Qux, T3 = usize> for Bar {
| ++++++++ ++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:40:15
Expand Down Expand Up @@ -119,8 +119,8 @@ LL | trait Tr2<T1, T2, T3> {
| ^^^ -- -- --
help: add missing generic arguments
|
LL | impl Tr2<i32, T2, T3, t2 = Qux, T3 = usize> for Qux {
| ++++++++
LL | impl<T2, T3> Tr2<i32, T2, T3, t2 = Qux, T3 = usize> for Qux {
| ++++++++ ++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:47:15
Expand Down Expand Up @@ -149,8 +149,8 @@ LL | trait Tr2<T1, T2, T3> {
| ^^^ -- -- --
help: add missing generic arguments
|
LL | impl Tr2<i32, T2, T3, X = Qux, Y = usize> for Bar {
| ++++++++
LL | impl<T2, T3> Tr2<i32, T2, T3, X = Qux, Y = usize> for Bar {
| ++++++++ ++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:54:15
Expand Down Expand Up @@ -179,8 +179,8 @@ LL | trait Tr2<T1, T2, T3> {
| ^^^ -- -- --
help: add missing generic argument
|
LL | impl Tr2<i32, Qux, T3, T3 = GenericTerm<i32>> for Bar {
| ++++
LL | impl<T3> Tr2<i32, Qux, T3, T3 = GenericTerm<i32>> for Bar {
| ++++ ++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:61:20
Expand Down Expand Up @@ -225,8 +225,8 @@ LL | trait Tr3<const N: i32, T2, T3> {
| ^^^ ------------ -- --
help: add missing generic arguments
|
LL | impl Tr3<N, T2, T3, n = 42, T2 = Qux, T3 = usize> for Qux {
| ++++++++++
LL | impl<const N: i32, T2, T3> Tr3<N, T2, T3, n = 42, T2 = Qux, T3 = usize> for Qux {
| ++++++++++++++++++++++ ++++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:84:10
Expand Down Expand Up @@ -267,8 +267,8 @@ LL | trait Tr3<const N: i32, T2, T3> {
| ^^^ ------------ -- --
help: add missing generic arguments
|
LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar {
| ++++++++
LL | impl<T2, T3> Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar {
| ++++++++ ++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:98:14
Expand All @@ -295,8 +295,8 @@ LL | trait Tr3<const N: i32, T2, T3> {
| ^^^ ------------ -- --
help: add missing generic arguments
|
LL | impl Tr3<N, T2, T3, X = 42, Y = Qux, Z = usize> for Bar {
| ++++++++++
LL | impl<const N: i32, T2, T3> Tr3<N, T2, T3, X = 42, Y = Qux, Z = usize> for Bar {
| ++++++++++++++++++++++ ++++++++++

error[E0229]: associated item constraints are not allowed here
--> $DIR/associated-types-eq-2.rs:106:10
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/checked-type-aliases/def-site-body-wf.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ note: required by an implicit `Sized` bound in `Vec`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL

error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
--> $DIR/def-site-body-wf.rs:11:1
--> $DIR/def-site-body-wf.rs:11:15
|
LL | type _C<'a> = &'static &'a ();
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
|
= note: the pointer is valid for the static lifetime
note: but the referenced data is only valid for the lifetime `'a` as defined here
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0275]: overflow normalizing the type alias `Loop`
--> $DIR/inherent-impls-overflow.rs:8:1
--> $DIR/inherent-impls-overflow.rs:8:13
|
LL | type Loop = Loop;
| ^^^^^^^^^
| ^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

Expand All @@ -15,18 +15,18 @@ LL | impl Loop {}
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow normalizing the type alias `Poly0<(((((((_,),),),),),),)>`
--> $DIR/inherent-impls-overflow.rs:17:1
--> $DIR/inherent-impls-overflow.rs:17:17
|
LL | type Poly0<T> = Poly1<(T,)>;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>`
--> $DIR/inherent-impls-overflow.rs:20:1
--> $DIR/inherent-impls-overflow.rs:20:17
|
LL | type Poly1<T> = Poly0<(T,)>;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0275]: overflow evaluating the requirement `Loop == _`
--> $DIR/inherent-impls-overflow.rs:8:1
--> $DIR/inherent-impls-overflow.rs:8:13
|
LL | type Loop = Loop;
| ^^^^^^^^^
| ^^^^

error[E0275]: overflow evaluating the requirement `Loop == _`
--> $DIR/inherent-impls-overflow.rs:12:1
Expand All @@ -17,18 +17,18 @@ LL | impl Loop {}
| ^^^^

error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:17:1
--> $DIR/inherent-impls-overflow.rs:17:17
|
LL | type Poly0<T> = Poly1<(T,)>;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)

error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:20:1
--> $DIR/inherent-impls-overflow.rs:20:17
|
LL | type Poly1<T> = Poly0<(T,)>;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0275]: overflow normalizing the type alias `Recur`
--> $DIR/opaq-ty-collection-infinite-recur.rs:16:20
--> $DIR/opaq-ty-collection-infinite-recur.rs:16:33
|
LL | struct Hold([(); { type Recur = Recur; 0 }]);
| ^^^^^^^^^^
| ^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0275]: overflow normalizing the type alias `Arr2`
--> $DIR/recursive-type-alias-in-const-projection.rs:12:1
--> $DIR/recursive-type-alias-in-const-projection.rs:12:13
|
LL | type Arr2 = [usize; <Arr2 as Trait>::ASSOC];
| ^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | impl<T> Loop<T> {}
| ^ unconstrained type parameter

error[E0275]: overflow normalizing the type alias `Loop<T>`
--> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:1
--> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:16
|
LL | type Loop<T> = Loop<T>;
| ^^^^^^^^^^^^
| ^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

Expand Down
Loading
Loading