mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Introduce AssocTag::descr & refactor in the vicinity
This commit is contained in:
@@ -1960,7 +1960,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||
trait_item: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
assert_eq!(impl_item.as_tag(), trait_item.as_tag());
|
||||
assert_eq!(impl_item.tag(), trait_item.tag());
|
||||
|
||||
let ty_const_params_of = |def_id| {
|
||||
tcx.generics_of(def_id).own_params.iter().filter(|param| {
|
||||
|
||||
@@ -171,7 +171,7 @@ pub(super) fn report_unresolved_assoc_item<I>(
|
||||
let all_candidate_names: Vec<_> = all_candidates()
|
||||
.flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
|
||||
.filter_map(|item| {
|
||||
if !item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag {
|
||||
if !item.is_impl_trait_in_trait() && item.tag() == assoc_tag {
|
||||
item.opt_name()
|
||||
} else {
|
||||
None
|
||||
@@ -207,7 +207,7 @@ pub(super) fn report_unresolved_assoc_item<I>(
|
||||
.iter()
|
||||
.flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
|
||||
.filter_map(|item| {
|
||||
(!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then(|| item.name())
|
||||
(!item.is_impl_trait_in_trait() && item.tag() == assoc_tag).then(|| item.name())
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -220,7 +220,7 @@ pub(super) fn report_unresolved_assoc_item<I>(
|
||||
.filter(|trait_def_id| {
|
||||
tcx.associated_items(trait_def_id)
|
||||
.filter_by_name_unhygienic(suggested_name)
|
||||
.any(|item| item.as_tag() == assoc_tag)
|
||||
.any(|item| item.tag() == assoc_tag)
|
||||
})
|
||||
.collect::<Vec<_>>()[..]
|
||||
{
|
||||
@@ -383,9 +383,9 @@ fn report_assoc_kind_mismatch(
|
||||
hir::Term::Ty(ty) => ty.span,
|
||||
hir::Term::Const(ct) => ct.span,
|
||||
};
|
||||
(span, Some(ident.span), assoc_item.as_tag(), assoc_tag)
|
||||
(span, Some(ident.span), assoc_item.tag(), assoc_tag)
|
||||
} else {
|
||||
(ident.span, None, assoc_tag, assoc_item.as_tag())
|
||||
(ident.span, None, assoc_tag, assoc_item.tag())
|
||||
};
|
||||
|
||||
self.dcx().emit_err(errors::AssocKindMismatch {
|
||||
@@ -393,7 +393,7 @@ fn report_assoc_kind_mismatch(
|
||||
expected: assoc_tag_str(expected),
|
||||
got: assoc_tag_str(got),
|
||||
expected_because_label,
|
||||
assoc_kind: assoc_tag_str(assoc_item.as_tag()),
|
||||
assoc_kind: assoc_tag_str(assoc_item.tag()),
|
||||
def_span: tcx.def_span(assoc_item.def_id),
|
||||
bound_on_assoc_const_label,
|
||||
wrap_in_braces_sugg,
|
||||
@@ -965,8 +965,8 @@ enum Descr {
|
||||
names_len += 1;
|
||||
|
||||
descr = match descr {
|
||||
None => Some(Descr::Tag(assoc_item.as_tag())),
|
||||
Some(Descr::Tag(tag)) if tag != assoc_item.as_tag() => Some(Descr::Item),
|
||||
None => Some(Descr::Tag(assoc_item.tag())),
|
||||
Some(Descr::Tag(tag)) if tag != assoc_item.tag() => Some(Descr::Item),
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
@@ -1030,10 +1030,8 @@ enum Descr {
|
||||
let names = names.join(", ");
|
||||
|
||||
let descr = match descr.unwrap() {
|
||||
// FIXME(fmease): Create `ty::AssocTag::descr`.
|
||||
Descr::Tag(ty::AssocTag::Type) => "associated type",
|
||||
Descr::Tag(ty::AssocTag::Const) => "associated constant",
|
||||
_ => "associated item",
|
||||
Descr::Item => "associated item",
|
||||
Descr::Tag(tag) => tag.descr(),
|
||||
};
|
||||
let mut err = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
@@ -1050,13 +1048,13 @@ enum Descr {
|
||||
let mut names: UnordMap<_, usize> = Default::default();
|
||||
for (item, _) in &missing_assoc_items {
|
||||
items_count += 1;
|
||||
*names.entry((item.name(), item.as_tag())).or_insert(0) += 1;
|
||||
*names.entry((item.name(), item.tag())).or_insert(0) += 1;
|
||||
}
|
||||
let mut dupes = false;
|
||||
let mut shadows = false;
|
||||
for (item, trait_ref) in &missing_assoc_items {
|
||||
let name = item.name();
|
||||
let key = (name, item.as_tag());
|
||||
let key = (name, item.tag());
|
||||
|
||||
if names[&key] > 1 {
|
||||
dupes = true;
|
||||
|
||||
@@ -1768,7 +1768,7 @@ fn probe_assoc_item_unchecked(
|
||||
let item = tcx
|
||||
.associated_items(scope)
|
||||
.filter_by_name_unhygienic(ident.name)
|
||||
.find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
|
||||
.find(|i| i.tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
|
||||
|
||||
Some((*item, def_scope))
|
||||
}
|
||||
|
||||
@@ -126,27 +126,15 @@ pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
|
||||
}
|
||||
|
||||
pub fn descr(&self) -> &'static str {
|
||||
match self.kind {
|
||||
ty::AssocKind::Const { .. } => "associated const",
|
||||
ty::AssocKind::Fn { has_self: true, .. } => "method",
|
||||
ty::AssocKind::Fn { has_self: false, .. } => "associated function",
|
||||
ty::AssocKind::Type { .. } => "associated type",
|
||||
}
|
||||
self.kind.descr()
|
||||
}
|
||||
|
||||
pub fn namespace(&self) -> Namespace {
|
||||
match self.kind {
|
||||
ty::AssocKind::Type { .. } => Namespace::TypeNS,
|
||||
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
|
||||
}
|
||||
self.kind.namespace()
|
||||
}
|
||||
|
||||
pub fn as_def_kind(&self) -> DefKind {
|
||||
match self.kind {
|
||||
AssocKind::Const { .. } => DefKind::AssocConst,
|
||||
AssocKind::Fn { .. } => DefKind::AssocFn,
|
||||
AssocKind::Type { .. } => DefKind::AssocTy,
|
||||
}
|
||||
self.kind.as_def_kind()
|
||||
}
|
||||
|
||||
pub fn is_const(&self) -> bool {
|
||||
@@ -165,12 +153,8 @@ pub fn is_type(&self) -> bool {
|
||||
matches!(self.kind, ty::AssocKind::Type { .. })
|
||||
}
|
||||
|
||||
pub fn as_tag(&self) -> AssocTag {
|
||||
match self.kind {
|
||||
AssocKind::Const { .. } => AssocTag::Const,
|
||||
AssocKind::Fn { .. } => AssocTag::Fn,
|
||||
AssocKind::Type { .. } => AssocTag::Type,
|
||||
}
|
||||
pub fn tag(&self) -> AssocTag {
|
||||
self.kind.tag()
|
||||
}
|
||||
|
||||
pub fn is_impl_trait_in_trait(&self) -> bool {
|
||||
@@ -196,33 +180,43 @@ pub enum AssocKind {
|
||||
|
||||
impl AssocKind {
|
||||
pub fn namespace(&self) -> Namespace {
|
||||
match *self {
|
||||
ty::AssocKind::Type { .. } => Namespace::TypeNS,
|
||||
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
|
||||
match self {
|
||||
Self::Type { .. } => Namespace::TypeNS,
|
||||
Self::Const { .. } | Self::Fn { .. } => Namespace::ValueNS,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tag(&self) -> AssocTag {
|
||||
match self {
|
||||
Self::Const { .. } => AssocTag::Const,
|
||||
Self::Fn { .. } => AssocTag::Fn,
|
||||
Self::Type { .. } => AssocTag::Type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_def_kind(&self) -> DefKind {
|
||||
match self {
|
||||
AssocKind::Const { .. } => DefKind::AssocConst,
|
||||
AssocKind::Fn { .. } => DefKind::AssocFn,
|
||||
AssocKind::Type { .. } => DefKind::AssocTy,
|
||||
Self::Const { .. } => DefKind::AssocConst,
|
||||
Self::Fn { .. } => DefKind::AssocFn,
|
||||
Self::Type { .. } => DefKind::AssocTy,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn descr(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Fn { has_self: true, .. } => "method",
|
||||
_ => self.tag().descr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AssocKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AssocKind::Fn { has_self: true, .. } => write!(f, "method"),
|
||||
AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"),
|
||||
AssocKind::Const { .. } => write!(f, "associated const"),
|
||||
AssocKind::Type { .. } => write!(f, "associated type"),
|
||||
}
|
||||
f.write_str(self.descr())
|
||||
}
|
||||
}
|
||||
|
||||
// Like `AssocKind`, but just the tag, no fields. Used in various kinds of matching.
|
||||
/// Like [`AssocKind`], but just the tag, no fields. Used in various kinds of matching.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum AssocTag {
|
||||
Const,
|
||||
@@ -230,6 +224,17 @@ pub enum AssocTag {
|
||||
Type,
|
||||
}
|
||||
|
||||
impl AssocTag {
|
||||
pub fn descr(self) -> &'static str {
|
||||
// This should match `DefKind::descr`.
|
||||
match self {
|
||||
Self::Const => "associated constant",
|
||||
Self::Fn => "associated function",
|
||||
Self::Type => "associated type",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
|
||||
///
|
||||
/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
|
||||
@@ -277,7 +282,7 @@ pub fn filter_by_name_unhygienic_and_kind(
|
||||
name: Symbol,
|
||||
assoc_tag: AssocTag,
|
||||
) -> impl '_ + Iterator<Item = &ty::AssocItem> {
|
||||
self.filter_by_name_unhygienic(name).filter(move |item| item.as_tag() == assoc_tag)
|
||||
self.filter_by_name_unhygienic(name).filter(move |item| item.tag() == assoc_tag)
|
||||
}
|
||||
|
||||
/// Returns the associated item with the given identifier and `AssocKind`, if one exists.
|
||||
@@ -290,7 +295,7 @@ pub fn find_by_ident_and_kind(
|
||||
parent_def_id: DefId,
|
||||
) -> Option<&ty::AssocItem> {
|
||||
self.filter_by_name_unhygienic(ident.name)
|
||||
.filter(|item| item.as_tag() == assoc_tag)
|
||||
.filter(|item| item.tag() == assoc_tag)
|
||||
.find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
|
||||
}
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ pub(crate) fn build_impl(
|
||||
.find_by_ident_and_kind(
|
||||
tcx,
|
||||
item.ident(tcx),
|
||||
item.as_tag(),
|
||||
item.tag(),
|
||||
associated_trait.def_id,
|
||||
)
|
||||
.unwrap(); // corresponding associated item has to exist
|
||||
|
||||
@@ -1226,7 +1226,7 @@ pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_n
|
||||
.associated_items(did)
|
||||
.filter_by_name_unhygienic(method_name)
|
||||
.next()
|
||||
.filter(|item| item.as_tag() == AssocTag::Fn)
|
||||
.filter(|item| item.tag() == AssocTag::Fn)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -16,7 +16,7 @@ impl Bar for Foo<'_> {
|
||||
const STATIC: &str = "";
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
//~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
|
||||
//~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -39,14 +39,14 @@ help: use the `'static` lifetime
|
||||
LL | const STATIC: &'static str = "";
|
||||
| +++++++
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
|
||||
error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration
|
||||
--> $DIR/elided-lifetime.rs:16:17
|
||||
|
|
||||
LL | const STATIC: &str;
|
||||
| - lifetimes in impl do not match this associated const in trait
|
||||
| - lifetimes in impl do not match this associated constant in trait
|
||||
...
|
||||
LL | const STATIC: &str = "";
|
||||
| ^ lifetimes do not match associated const in trait
|
||||
| ^ lifetimes do not match associated constant in trait
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ impl Bar<'_> for A {
|
||||
const STATIC: &str = "";
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
//~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
|
||||
//~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration
|
||||
}
|
||||
|
||||
struct B;
|
||||
|
||||
@@ -21,14 +21,14 @@ help: use the `'static` lifetime
|
||||
LL | const STATIC: &'static str = "";
|
||||
| +++++++
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
|
||||
error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration
|
||||
--> $DIR/static-trait-impl.rs:9:17
|
||||
|
|
||||
LL | const STATIC: &'a str;
|
||||
| - lifetimes in impl do not match this associated const in trait
|
||||
| - lifetimes in impl do not match this associated constant in trait
|
||||
...
|
||||
LL | const STATIC: &str = "";
|
||||
| ^ lifetimes do not match associated const in trait
|
||||
| ^ lifetimes do not match associated constant in trait
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ impl Trait for () {
|
||||
//~| ERROR mismatched types
|
||||
const Q = "";
|
||||
//~^ ERROR missing type for `const` item
|
||||
//~| ERROR lifetime parameters or bounds on associated const `Q` do not match the trait declaration
|
||||
//~| ERROR lifetime parameters or bounds on associated constant `Q` do not match the trait declaration
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -15,14 +15,14 @@ error: missing type for `const` item
|
||||
LL | const K<T> = ();
|
||||
| ^ help: provide a type for the associated constant: `()`
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on associated const `Q` do not match the trait declaration
|
||||
error[E0195]: lifetime parameters or bounds on associated constant `Q` do not match the trait declaration
|
||||
--> $DIR/assoc-const-missing-type.rs:15:12
|
||||
|
|
||||
LL | const Q<'a>: &'a str;
|
||||
| ---- lifetimes in impl do not match this associated const in trait
|
||||
| ---- lifetimes in impl do not match this associated constant in trait
|
||||
...
|
||||
LL | const Q = "";
|
||||
| ^ lifetimes do not match associated const in trait
|
||||
| ^ lifetimes do not match associated constant in trait
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/assoc-const-missing-type.rs:15:12
|
||||
|
||||
@@ -14,15 +14,15 @@ trait Trait<P> {
|
||||
|
||||
impl<P> Trait<P> for () {
|
||||
const A<T>: () = ();
|
||||
//~^ ERROR const `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
//~^ ERROR constant `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
const B<const K: u64>: u64 = 0;
|
||||
//~^ ERROR const `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
//~^ ERROR constant `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
const C<'a>: &'a str = "";
|
||||
//~^ ERROR const `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
//~^ ERROR constant `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
const D<const N: u16>: u16 = N;
|
||||
//~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
|
||||
//~^ ERROR constant `D` has an incompatible generic parameter for trait `Trait`
|
||||
const E: &'static () = &();
|
||||
//~^ ERROR lifetime parameters or bounds on associated const `E` do not match the trait declaration
|
||||
//~^ ERROR lifetime parameters or bounds on associated constant `E` do not match the trait declaration
|
||||
|
||||
const F: usize = 1024
|
||||
where
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
error[E0049]: associated const `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
error[E0049]: associated constant `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/compare-impl-item.rs:16:13
|
||||
|
|
||||
LL | const A: ();
|
||||
@@ -7,7 +7,7 @@ LL | const A: ();
|
||||
LL | const A<T>: () = ();
|
||||
| ^ found 1 type parameter
|
||||
|
||||
error[E0049]: associated const `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
error[E0049]: associated constant `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
--> $DIR/compare-impl-item.rs:18:13
|
||||
|
|
||||
LL | const B<const K: u64, const Q: u64>: u64;
|
||||
@@ -18,7 +18,7 @@ LL | const B<const K: u64, const Q: u64>: u64;
|
||||
LL | const B<const K: u64>: u64 = 0;
|
||||
| ^^^^^^^^^^^^ found 1 const parameter
|
||||
|
||||
error[E0049]: associated const `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
error[E0049]: associated constant `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
--> $DIR/compare-impl-item.rs:20:13
|
||||
|
|
||||
LL | const C<T>: T;
|
||||
@@ -27,7 +27,7 @@ LL | const C<T>: T;
|
||||
LL | const C<'a>: &'a str = "";
|
||||
| ^^ found 0 type parameters
|
||||
|
||||
error[E0053]: associated const `D` has an incompatible generic parameter for trait `Trait`
|
||||
error[E0053]: associated constant `D` has an incompatible generic parameter for trait `Trait`
|
||||
--> $DIR/compare-impl-item.rs:22:13
|
||||
|
|
||||
LL | trait Trait<P> {
|
||||
@@ -42,14 +42,14 @@ LL | impl<P> Trait<P> for () {
|
||||
LL | const D<const N: u16>: u16 = N;
|
||||
| ^^^^^^^^^^^^ found const parameter of type `u16`
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on associated const `E` do not match the trait declaration
|
||||
error[E0195]: lifetime parameters or bounds on associated constant `E` do not match the trait declaration
|
||||
--> $DIR/compare-impl-item.rs:24:12
|
||||
|
|
||||
LL | const E<'a>: &'a ();
|
||||
| ---- lifetimes in impl do not match this associated const in trait
|
||||
| ---- lifetimes in impl do not match this associated constant in trait
|
||||
...
|
||||
LL | const E: &'static () = &();
|
||||
| ^ lifetimes do not match associated const in trait
|
||||
| ^ lifetimes do not match associated constant in trait
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/compare-impl-item.rs:29:12
|
||||
|
||||
Reference in New Issue
Block a user