Auto merge of #97694 - Dylan-DPC:rollup-2yxo7ce, r=Dylan-DPC

Rollup of 3 pull requests

Successful merges:

 - #97415 (Compute `is_late_bound_map` query separately from lifetime resolution)
 - #97471 (Provide more context when denying invalid type params )
 - #97681 (Add more eslint checks)

Failed merges:

 - #97446 (Make hir().get_generics and generics_of consistent.)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-06-03 15:26:06 +00:00
commit 9a74608543
48 changed files with 1224 additions and 594 deletions

View File

@ -672,9 +672,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
LifetimeRes::Param { .. } => {
(hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
}
LifetimeRes::Fresh { param, .. } => {
(hir::ParamName::Fresh(param), hir::LifetimeParamKind::Elided)
}
LifetimeRes::Fresh { .. } => (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided),
LifetimeRes::Static | LifetimeRes::Error => return None,
res => panic!(
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
@ -1576,10 +1574,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id })
}
// Input lifetime like `'1`:
LifetimeRes::Fresh { param, .. } => (
hir::ParamName::Fresh(outer_def_id),
LifetimeRes::Fresh { param, binder: fn_node_id },
),
LifetimeRes::Fresh { param, .. } => {
(hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id })
}
LifetimeRes::Static | LifetimeRes::Error => continue,
res => {
panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span)
@ -1749,7 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::Lifetime {
debug!(?self.captured_lifetimes);
let name = match res {
LifetimeRes::Param { param, binder } => {
LifetimeRes::Param { mut param, binder } => {
debug_assert_ne!(ident.name, kw::UnderscoreLifetime);
let p_name = ParamName::Plain(ident);
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
@ -1757,10 +1754,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&& !binders_to_ignore.contains(&binder)
{
match captures.entry(param) {
Entry::Occupied(_) => {}
Entry::Occupied(o) => param = self.resolver.local_def_id(o.get().1),
Entry::Vacant(v) => {
let p_id = self.resolver.next_node_id();
self.resolver.create_def(
let p_def_id = self.resolver.create_def(
*parent_def_id,
p_id,
DefPathData::LifetimeNs(p_name.ident().name),
@ -1769,10 +1766,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
v.insert((span, p_id, p_name, res));
param = p_def_id;
}
}
}
hir::LifetimeName::Param(p_name)
hir::LifetimeName::Param(param, p_name)
}
LifetimeRes::Fresh { mut param, binder } => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
@ -1792,21 +1790,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span.with_parent(None),
);
let p_name = ParamName::Fresh(param);
v.insert((span, p_id, p_name, res));
v.insert((span, p_id, ParamName::Fresh, res));
param = p_def_id;
}
}
}
let p_name = ParamName::Fresh(param);
hir::LifetimeName::Param(p_name)
hir::LifetimeName::Param(param, ParamName::Fresh)
}
LifetimeRes::Anonymous { binder, elided } => {
let l_name = if elided {
hir::LifetimeName::Implicit
} else {
hir::LifetimeName::Underscore
};
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
&mut self.captured_lifetimes
&& !binders_to_ignore.contains(&binder)
@ -1819,11 +1810,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExpnId::root(),
span.with_parent(None),
);
let p_name = ParamName::Fresh(p_def_id);
captures.insert(p_def_id, (span, p_id, p_name, res));
hir::LifetimeName::Param(p_name)
captures.insert(p_def_id, (span, p_id, ParamName::Fresh, res));
hir::LifetimeName::Param(p_def_id, ParamName::Fresh)
} else if elided {
hir::LifetimeName::Implicit
} else {
l_name
hir::LifetimeName::Underscore
}
}
LifetimeRes::Static => hir::LifetimeName::Static,
@ -1831,6 +1823,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
};
debug!(?self.captured_lifetimes);
debug!(?name);
hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
}

View File

@ -567,14 +567,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
match lifetime.name {
hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error)
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
| hir::LifetimeName::Error
| hir::LifetimeName::Static => {
let lifetime_span = lifetime.span;
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
}
hir::LifetimeName::Param(hir::ParamName::Fresh(_))
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
| hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Implicit
| hir::LifetimeName::Underscore => {

View File

@ -830,11 +830,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
fn_def_id: DefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id());
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: owner.to_def_id(),
scope: fn_def_id,
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
}));
f(liberated_region);

View File

@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
use std::fmt;
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
pub struct Lifetime {
pub hir_id: HirId,
pub span: Span,
@ -60,7 +60,7 @@ pub enum ParamName {
/// ```
/// where `'f` is something like `Fresh(0)`. The indices are
/// unique per impl, but not necessarily continuous.
Fresh(LocalDefId),
Fresh,
/// Indicates an illegal name was given and an error has been
/// reported (so we should squelch other derived errors). Occurs
@ -72,9 +72,7 @@ impl ParamName {
pub fn ident(&self) -> Ident {
match *self {
ParamName::Plain(ident) => ident,
ParamName::Fresh(_) | ParamName::Error => {
Ident::with_dummy_span(kw::UnderscoreLifetime)
}
ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
}
}
@ -90,7 +88,7 @@ impl ParamName {
#[derive(HashStable_Generic)]
pub enum LifetimeName {
/// User-given names or fresh (synthetic) names.
Param(ParamName),
Param(LocalDefId, ParamName),
/// User wrote nothing (e.g., the lifetime in `&u32`).
Implicit,
@ -127,7 +125,7 @@ impl LifetimeName {
| LifetimeName::Error => Ident::empty(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
LifetimeName::Param(param_name) => param_name.ident(),
LifetimeName::Param(_, param_name) => param_name.ident(),
}
}
@ -136,9 +134,9 @@ impl LifetimeName {
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit
| LifetimeName::Underscore
| LifetimeName::Param(ParamName::Fresh(_))
| LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Error => true,
LifetimeName::Static | LifetimeName::Param(_) => false,
LifetimeName::Static | LifetimeName::Param(..) => false,
}
}
@ -148,12 +146,12 @@ impl LifetimeName {
| LifetimeName::Implicit
| LifetimeName::Underscore => true,
// It might seem surprising that `Fresh(_)` counts as
// It might seem surprising that `Fresh` counts as
// *not* elided -- but this is because, as far as the code
// in the compiler is concerned -- `Fresh(_)` variants act
// in the compiler is concerned -- `Fresh` variants act
// equivalently to "some fresh name". They correspond to
// early-bound regions on an impl, in other words.
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
}
}
@ -163,8 +161,8 @@ impl LifetimeName {
pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
match *self {
LifetimeName::Param(param_name) => {
LifetimeName::Param(param_name.normalize_to_macros_2_0())
LifetimeName::Param(def_id, param_name) => {
LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0())
}
lifetime_name => lifetime_name,
}
@ -177,12 +175,6 @@ impl fmt::Display for Lifetime {
}
}
impl fmt::Debug for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "lifetime({}: {})", self.hir_id, self.name.ident())
}
}
impl Lifetime {
pub fn is_elided(&self) -> bool {
self.name.is_elided()
@ -628,6 +620,16 @@ impl<'hir> Generics<'hir> {
})
}
pub fn outlives_for_param(
&self,
param_def_id: LocalDefId,
) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
self.predicates.iter().filter_map(move |pred| match pred {
WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
_ => None,
})
}
pub fn bounds_span_for_suggestions(&self, param_def_id: LocalDefId) -> Option<Span> {
self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
|bound| {
@ -769,6 +771,16 @@ pub struct WhereRegionPredicate<'hir> {
pub bounds: GenericBounds<'hir>,
}
impl<'hir> WhereRegionPredicate<'hir> {
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
match self.lifetime.name {
LifetimeName::Param(id, _) => id == param_def_id,
_ => false,
}
}
}
/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, HashStable_Generic)]
pub struct WhereEqPredicate<'hir> {

View File

@ -510,11 +510,11 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
visitor.visit_id(lifetime.hir_id);
match lifetime.name {
LifetimeName::Param(ParamName::Plain(ident)) => {
LifetimeName::Param(_, ParamName::Plain(ident)) => {
visitor.visit_ident(ident);
}
LifetimeName::Param(ParamName::Fresh(_))
| LifetimeName::Param(ParamName::Error)
LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Param(_, ParamName::Error)
| LifetimeName::Static
| LifetimeName::Error
| LifetimeName::Implicit
@ -879,7 +879,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
visitor.visit_id(param.hir_id);
match param.name {
ParamName::Plain(ident) => visitor.visit_ident(ident),
ParamName::Error | ParamName::Fresh(_) => {}
ParamName::Error | ParamName::Fresh => {}
}
match param.kind {
GenericParamKind::Lifetime { .. } => {}

View File

@ -364,7 +364,11 @@ impl<'hir> Map<'hir> {
match node.node {
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
OwnerNode::Item(Item {
OwnerNode::ForeignItem(ForeignItem {
kind: ForeignItemKind::Fn(_, _, generics),
..
})
| OwnerNode::Item(Item {
kind:
ItemKind::Fn(_, generics, _)
| ItemKind::TyAlias(_, generics)

View File

@ -6,7 +6,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::ItemLocalId;
use rustc_macros::HashStable;
use rustc_span::symbol::Symbol;
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum Region {
@ -22,12 +21,12 @@ pub enum Region {
/// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g.
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum LifetimeScopeForPath {
// Contains all lifetime names that are in scope and could possibly be used in generics
// arguments of path.
NonElided(Vec<Symbol>),
/// Contains all lifetime names that are in scope and could possibly be used in generics
/// arguments of path.
NonElided(Vec<LocalDefId>),
// Information that allows us to suggest args of the form `<'_>` in case
// no generic arguments were provided for a path.
/// Information that allows us to suggest args of the form `<'_>` in case
/// no generic arguments were provided for a path.
Elided,
}

View File

@ -1584,7 +1584,7 @@ rustc_queries! {
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
desc { "looking up a named region" }
}
query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet<LocalDefId>> {
desc { "testing if a region is late bound" }
}
/// For a given item (like a struct), gets the default lifetimes to be used

View File

@ -2803,6 +2803,13 @@ impl<'tcx> TyCtxt<'tcx> {
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
}
pub fn is_late_bound(self, id: HirId) -> bool {
self.is_late_bound_map(id.owner).map_or(false, |set| {
let def_id = self.hir().local_def_id(id);
set.contains(&def_id)
})
}
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner)

View File

@ -13,7 +13,7 @@ use rustc_ast::{
};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_ast_pretty::pprust::path_segment_to_string;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
MultiSpan,
@ -21,7 +21,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::PrimTy;
use rustc_session::lint;
use rustc_session::parse::feature_err;
@ -2082,7 +2082,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
/// Returns whether to add `'static` lifetime to the suggested lifetime list.
pub(crate) fn report_elision_failure(
&mut self,
&self,
diag: &mut Diagnostic,
params: &[ElisionFailureInfo],
) -> bool {
@ -2187,10 +2187,27 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
&self,
err: &mut Diagnostic,
mut spans_with_counts: Vec<(Span, usize)>,
lifetime_names: &FxHashSet<Symbol>,
lifetime_spans: Vec<Span>,
params: &[ElisionFailureInfo],
in_scope_lifetimes: FxIndexSet<LocalDefId>,
params: Option<&[ElisionFailureInfo]>,
) {
let (mut lifetime_names, lifetime_spans): (FxHashSet<_>, Vec<_>) = in_scope_lifetimes
.iter()
.filter_map(|def_id| {
let name = self.tcx.item_name(def_id.to_def_id());
let span = self.tcx.def_ident_span(def_id.to_def_id())?;
Some((name, span))
})
.filter(|&(n, _)| n != kw::UnderscoreLifetime)
.unzip();
if let Some(params) = params {
// If there's no lifetime available, suggest `'static`.
if self.report_elision_failure(err, params) && lifetime_names.is_empty() {
lifetime_names.insert(kw::StaticLifetime);
}
}
let params = params.unwrap_or(&[]);
let snippets: Vec<Option<String>> = spans_with_counts
.iter()
.map(|(span, _)| self.tcx.sess.source_map().span_to_snippet(*span).ok())

View File

@ -8,19 +8,19 @@
use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
use rustc_ast::walk_list;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefIdMap, LocalDefId};
use rustc_hir::hir_id::ItemLocalId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName};
use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet};
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node};
use rustc_hir::{GenericParamKind, HirIdMap};
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_lifetime::*;
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId;
use rustc_span::symbol::{kw, sym, Ident};
@ -33,9 +33,9 @@ use std::mem::take;
use tracing::{debug, span, Level};
trait RegionExt {
fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region);
fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region);
fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region);
fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region);
fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region;
@ -51,22 +51,22 @@ trait RegionExt {
}
impl RegionExt for Region {
fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region) {
fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region) {
let i = *index;
*index += 1;
let def_id = hir_map.local_def_id(param.hir_id);
debug!("Region::early: index={} def_id={:?}", i, def_id);
(param.name.normalize_to_macros_2_0(), Region::EarlyBound(i, def_id.to_def_id()))
(def_id, Region::EarlyBound(i, def_id.to_def_id()))
}
fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) {
fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) {
let depth = ty::INNERMOST;
let def_id = hir_map.local_def_id(param.hir_id);
debug!(
"Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
idx, param, depth, def_id,
);
(param.name.normalize_to_macros_2_0(), Region::LateBound(depth, idx, def_id.to_def_id()))
(def_id, Region::LateBound(depth, idx, def_id.to_def_id()))
}
fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region {
@ -134,11 +134,6 @@ struct NamedRegionMap {
// `Region` describing how that region is bound
defs: HirIdMap<Region>,
// the set of lifetime def ids that are late-bound; a region can
// be late-bound if (a) it does NOT appear in a where-clause and
// (b) it DOES appear in the arguments.
late_bound: HirIdSet,
// Maps relevant hir items to the bound vars on them. These include:
// - function defs
// - function pointers
@ -178,7 +173,7 @@ enum Scope<'a> {
Binder {
/// We use an IndexMap here because we want these lifetimes in order
/// for diagnostics.
lifetimes: FxIndexMap<hir::ParamName, Region>,
lifetimes: FxIndexMap<LocalDefId, Region>,
/// if we extend this scope with another scope, what is the next index
/// we should use for an early-bound region?
@ -402,7 +397,7 @@ fn resolve_lifetimes_trait_definition(
tcx: TyCtxt<'_>,
local_def_id: LocalDefId,
) -> ResolveLifetimes {
convert_named_region_map(tcx, do_resolve(tcx, local_def_id, true, false))
convert_named_region_map(do_resolve(tcx, local_def_id, true, false))
}
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
@ -410,7 +405,7 @@ fn resolve_lifetimes_trait_definition(
/// `named_region_map`, `is_late_bound_map`, etc.
#[tracing::instrument(level = "debug", skip(tcx))]
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
convert_named_region_map(tcx, do_resolve(tcx, local_def_id, false, false))
convert_named_region_map(do_resolve(tcx, local_def_id, false, false))
}
fn do_resolve(
@ -422,7 +417,6 @@ fn do_resolve(
let item = tcx.hir().expect_item(local_def_id);
let mut named_region_map = NamedRegionMap {
defs: Default::default(),
late_bound: Default::default(),
late_bound_vars: Default::default(),
scope_for_path: with_scope_for_path.then(|| Default::default()),
};
@ -439,18 +433,13 @@ fn do_resolve(
named_region_map
}
fn convert_named_region_map(tcx: TyCtxt<'_>, named_region_map: NamedRegionMap) -> ResolveLifetimes {
fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes {
let mut rl = ResolveLifetimes::default();
for (hir_id, v) in named_region_map.defs {
let map = rl.defs.entry(hir_id.owner).or_default();
map.insert(hir_id.local_id, v);
}
for hir_id in named_region_map.late_bound {
let map = rl.late_bound.entry(hir_id.owner).or_default();
let def_id = tcx.hir().local_def_id(hir_id);
map.insert(def_id);
}
for (hir_id, v) in named_region_map.late_bound_vars {
let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
map.insert(hir_id.local_id, v);
@ -506,28 +495,6 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
item
}
fn is_late_bound_map<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
match tcx.def_kind(def_id) {
DefKind::AnonConst | DefKind::InlineConst => {
let mut def_id = tcx.local_parent(def_id);
// We search for the next outer anon const or fn here
// while skipping closures.
//
// Note that for `AnonConst` we still just recurse until we
// find a function body, but who cares :shrug:
while tcx.is_closure(def_id.to_def_id()) {
def_id = tcx.local_parent(def_id);
}
tcx.is_late_bound_map(def_id)
}
_ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)),
}
}
/// In traits, there is an implicit `Self` type parameter which comes before the generics.
/// We have to account for this when computing the index of the other generic parameters.
/// This function returns whether there is such an implicit parameter defined on the given item.
@ -554,10 +521,7 @@ fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath {
loop {
match scope {
Scope::Binder { lifetimes, s, .. } => {
available_lifetimes.extend(lifetimes.keys().filter_map(|p| match p {
hir::ParamName::Plain(ident) => Some(ident.name),
_ => None,
}));
available_lifetimes.extend(lifetimes.keys());
scope = s;
}
Scope::Body { s, .. } => {
@ -690,9 +654,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
_ => {}
}
match item.kind {
hir::ItemKind::Fn(ref sig, ref generics, _) => {
hir::ItemKind::Fn(_, ref generics, _) => {
self.missing_named_lifetime_spots.push(generics.into());
self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| {
self.visit_early_late(None, item.hir_id(), generics, |this| {
intravisit::walk_item(this, item);
});
self.missing_named_lifetime_spots.pop();
@ -734,13 +698,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
self.map.defs.insert(hir::HirId { owner, local_id }, *region);
});
}
for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
late_bound.iter().for_each(|&id| {
let hir_id = self.tcx.local_def_id_to_hir_id(id);
debug_assert_eq!(owner, hir_id.owner);
self.map.late_bound.insert(hir_id);
});
}
for (&owner, late_bound_vars) in
resolved_lifetimes.late_bound_vars.iter()
{
@ -810,8 +767,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
match item.kind {
hir::ForeignItemKind::Fn(ref decl, _, ref generics) => {
self.visit_early_late(None, item.hir_id(), decl, generics, |this| {
hir::ForeignItemKind::Fn(_, _, ref generics) => {
self.visit_early_late(None, item.hir_id(), generics, |this| {
intravisit::walk_foreign_item(this, item);
})
}
@ -841,7 +798,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
};
self.missing_named_lifetime_spots
.push(MissingLifetimeSpot::HigherRanked { span, span_type });
let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) = c
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c
.generic_params
.iter()
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
@ -898,7 +855,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// cc #48468
self.resolve_elided_lifetimes(&[lifetime])
}
LifetimeName::Param(_) | LifetimeName::Static => {
LifetimeName::Param(..) | LifetimeName::Static => {
// If the user wrote an explicit name, use that.
self.visit_lifetime(lifetime);
}
@ -1016,17 +973,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
for param in generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(self.tcx.hir(), &mut index, &param);
let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, &param);
if let hir::ParamName::Plain(Ident {
name: kw::UnderscoreLifetime,
..
}) = name
}) = param.name
{
// Pick the elided lifetime "definition" if one exists
// and use it to make an elision scope.
elision = Some(reg);
} else {
lifetimes.insert(name, reg);
lifetimes.insert(def_id, reg);
}
}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
@ -1088,13 +1045,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
use self::hir::TraitItemKind::*;
match trait_item.kind {
Fn(ref sig, _) => {
Fn(_, _) => {
self.missing_named_lifetime_spots.push((&trait_item.generics).into());
let tcx = self.tcx;
self.visit_early_late(
Some(tcx.hir().get_parent_item(trait_item.hir_id())),
trait_item.hir_id(),
&sig.decl,
&trait_item.generics,
|this| intravisit::walk_trait_item(this, trait_item),
);
@ -1156,13 +1112,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
use self::hir::ImplItemKind::*;
match impl_item.kind {
Fn(ref sig, _) => {
Fn(..) => {
self.missing_named_lifetime_spots.push((&impl_item.generics).into());
let tcx = self.tcx;
self.visit_early_late(
Some(tcx.hir().get_parent_item(impl_item.hir_id())),
impl_item.hir_id(),
&sig.decl,
&impl_item.generics,
|this| intravisit::walk_impl_item(this, impl_item),
);
@ -1174,7 +1129,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let mut index = self.next_early_index();
let mut non_lifetime_count = 0;
debug!("visit_ty: index = {}", index);
let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
.params
.iter()
.filter_map(|param| match param.kind {
@ -1218,15 +1173,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
#[tracing::instrument(level = "debug", skip(self))]
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
if lifetime_ref.is_elided() {
self.resolve_elided_lifetimes(&[lifetime_ref]);
return;
match lifetime_ref.name {
hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Implicit
| hir::LifetimeName::Underscore => self.resolve_elided_lifetimes(&[lifetime_ref]),
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
hir::LifetimeName::Param(param_def_id, _) => {
self.resolve_lifetime_ref(param_def_id, lifetime_ref)
}
// If we've already reported an error, just ignore `lifetime_ref`.
hir::LifetimeName::Error => {}
}
if lifetime_ref.is_static() {
self.insert_lifetime(lifetime_ref, Region::Static);
return;
}
self.resolve_lifetime_ref(lifetime_ref);
}
fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) {
@ -1311,7 +1268,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
ref bound_generic_params,
..
}) => {
let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) =
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
bound_generic_params
.iter()
.filter(|param| {
@ -1433,7 +1390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
let initial_bound_vars = binders.len() as u32;
let mut lifetimes: FxIndexMap<hir::ParamName, Region> = FxIndexMap::default();
let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default();
let binders_iter = trait_ref
.bound_generic_params
.iter()
@ -1580,14 +1537,17 @@ fn object_lifetime_defaults_for_item<'tcx>(
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
Some((param.hir_id, hir::LifetimeName::Param(param.name)))
let param_def_id = tcx.hir().local_def_id(param.hir_id);
Some((
param_def_id,
hir::LifetimeName::Param(param_def_id, param.name),
))
}
_ => None,
})
.enumerate()
.find(|&(_, (_, lt_name))| lt_name == name)
.map_or(Set1::Many, |(i, (id, _))| {
let def_id = tcx.hir().local_def_id(id);
.map_or(Set1::Many, |(i, (def_id, _))| {
Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id()))
})
}
@ -1654,14 +1614,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
&mut self,
parent_id: Option<LocalDefId>,
hir_id: hir::HirId,
decl: &'tcx hir::FnDecl<'tcx>,
generics: &'tcx hir::Generics<'tcx>,
walk: F,
) where
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
{
insert_late_bound_lifetimes(self.map, decl, generics);
// Find the start of nested early scopes, e.g., in methods.
let mut next_early_index = 0;
if let Some(parent_id) = parent_id {
@ -1680,12 +1637,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let mut non_lifetime_count = 0;
let mut named_late_bound_vars = 0;
let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
.params
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
if self.map.late_bound.contains(&param.hir_id) {
if self.tcx.is_late_bound(param.hir_id) {
let late_bound_idx = named_late_bound_vars;
named_late_bound_vars += 1;
Some(Region::late(late_bound_idx, self.tcx.hir(), param))
@ -1706,7 +1663,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
.iter()
.filter(|param| {
matches!(param.kind, GenericParamKind::Lifetime { .. })
&& self.map.late_bound.contains(&param.hir_id)
&& self.tcx.is_late_bound(param.hir_id)
})
.enumerate()
.map(|(late_bound_idx, param)| {
@ -1763,14 +1720,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.next_early_index_helper(false)
}
fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
// If we've already reported an error, just ignore `lifetime_ref`.
if let LifetimeName::Error = lifetime_ref.name {
return;
}
#[tracing::instrument(level = "debug", skip(self))]
fn resolve_lifetime_ref(
&mut self,
region_def_id: LocalDefId,
lifetime_ref: &'tcx hir::Lifetime,
) {
// Walk up the scope chain, tracking the number of fn scopes
// that we pass through, until we find a lifetime with the
// given name or we run out of scopes.
@ -1790,14 +1745,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
Scope::Binder { ref lifetimes, scope_type, s, .. } => {
match lifetime_ref.name {
LifetimeName::Param(param_name) => {
if let Some(&def) = lifetimes.get(&param_name.normalize_to_macros_2_0())
{
break Some(def.shifted(late_depth));
}
}
_ => bug!("expected LifetimeName::Param"),
if let Some(&def) = lifetimes.get(&region_def_id) {
break Some(def.shifted(late_depth));
}
match scope_type {
BinderScopeType::Normal => late_depth += 1,
@ -2473,8 +2422,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let mut late_depth = 0;
let mut scope = self.scope;
let mut lifetime_names = FxHashSet::default();
let mut lifetime_spans = vec![];
let mut in_scope_lifetimes = FxIndexSet::default();
let error = loop {
match *scope {
// Do not assign any resolution, it will be inferred.
@ -2484,12 +2432,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
Scope::Binder { s, ref lifetimes, scope_type, .. } => {
// collect named lifetimes for suggestions
for name in lifetimes.keys() {
if let hir::ParamName::Plain(name) = name {
lifetime_names.insert(name.name);
lifetime_spans.push(name.span);
}
}
in_scope_lifetimes.extend(lifetimes.keys().copied());
match scope_type {
BinderScopeType::Normal => late_depth += 1,
BinderScopeType::Concatenating => {}
@ -2524,12 +2467,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
match scope {
Scope::Binder { ref lifetimes, s, .. } => {
// Collect named lifetimes for suggestions.
for name in lifetimes.keys() {
if let hir::ParamName::Plain(name) = name {
lifetime_names.insert(name.name);
lifetime_spans.push(name.span);
}
}
in_scope_lifetimes.extend(lifetimes.keys().copied());
scope = s;
}
Scope::ObjectLifetimeDefault { ref s, .. }
@ -2574,19 +2512,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let mut err = self.report_missing_lifetime_specifiers(spans.clone(), lifetime_refs.len());
if let Some(params) = error {
// If there's no lifetime available, suggest `'static`.
if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
lifetime_names.insert(kw::StaticLifetime);
}
}
self.add_missing_lifetime_specifiers_label(
&mut err,
spans_with_counts,
&lifetime_names,
lifetime_spans,
error.unwrap_or(&[]),
in_scope_lifetimes,
error,
);
err.emit();
}
@ -2638,7 +2568,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
/// Detects late-bound lifetimes and inserts them into
/// `map.late_bound`.
/// `late_bound`.
///
/// A region declared on a fn is **late-bound** if:
/// - it is constrained by an argument type;
@ -2647,12 +2577,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// "Constrained" basically means that it appears in any type but
/// not amongst the inputs to a projection. In other words, `<&'a
/// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
#[tracing::instrument(level = "debug", skip(map))]
fn insert_late_bound_lifetimes(
map: &mut NamedRegionMap,
decl: &hir::FnDecl<'_>,
generics: &hir::Generics<'_>,
) {
fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxHashSet<LocalDefId>> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?;
let generics = tcx.hir().get_generics(def_id)?;
let mut late_bound = FxHashSet::default();
let mut constrained_by_input = ConstrainedCollector::default();
for arg_ty in decl.inputs {
constrained_by_input.visit_ty(arg_ty);
@ -2683,30 +2614,32 @@ fn insert_late_bound_lifetimes(
hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue,
}
let lt_name = hir::LifetimeName::Param(param.name.normalize_to_macros_2_0());
let param_def_id = tcx.hir().local_def_id(param.hir_id);
// appears in the where clauses? early-bound.
if appears_in_where_clause.regions.contains(&lt_name) {
if appears_in_where_clause.regions.contains(&param_def_id) {
continue;
}
// does not appear in the inputs, but appears in the return type? early-bound.
if !constrained_by_input.regions.contains(&lt_name)
&& appears_in_output.regions.contains(&lt_name)
if !constrained_by_input.regions.contains(&param_def_id)
&& appears_in_output.regions.contains(&param_def_id)
{
continue;
}
debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id);
let inserted = map.late_bound.insert(param.hir_id);
let inserted = late_bound.insert(param_def_id);
assert!(inserted, "visited lifetime {:?} twice", param.hir_id);
}
return;
debug!(?late_bound);
return Some(tcx.arena.alloc(late_bound));
#[derive(Default)]
struct ConstrainedCollector {
regions: FxHashSet<hir::LifetimeName>,
regions: FxHashSet<LocalDefId>,
}
impl<'v> Visitor<'v> for ConstrainedCollector {
@ -2738,18 +2671,22 @@ fn insert_late_bound_lifetimes(
}
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0());
if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
self.regions.insert(def_id);
}
}
}
#[derive(Default)]
struct AllCollector {
regions: FxHashSet<hir::LifetimeName>,
regions: FxHashSet<LocalDefId>,
}
impl<'v> Visitor<'v> for AllCollector {
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0());
if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
self.regions.insert(def_id);
}
}
}
}

View File

@ -16,7 +16,7 @@ use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError,
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, EarlyBinder, Ty, TyCtxt, TypeFold
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
use rustc_span::edition::Edition;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi;
use rustc_trait_selection::traits;
@ -653,7 +653,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span, item_def_id, item_segment
);
if tcx.generics_of(item_def_id).params.is_empty() {
self.prohibit_generics(slice::from_ref(item_segment));
self.prohibit_generics(slice::from_ref(item_segment).iter(), |_| {});
parent_substs
} else {
@ -681,7 +681,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_ref: &hir::TraitRef<'_>,
self_ty: Ty<'tcx>,
) -> ty::TraitRef<'tcx> {
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
self.ast_path_to_mono_trait_ref(
trait_ref.path.span,
@ -784,7 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let args = trait_segment.args();
let infer_args = trait_segment.infer_args;
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
self.instantiate_poly_trait_ref_inner(
@ -1776,12 +1776,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir_ref_id: hir::HirId,
span: Span,
qself_ty: Ty<'tcx>,
qself_res: Res,
qself: &hir::Ty<'_>,
assoc_segment: &hir::PathSegment<'_>,
permit_variants: bool,
) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
let tcx = self.tcx();
let assoc_ident = assoc_segment.ident;
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind {
path.res
} else {
Res::Err
};
debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident);
@ -1796,7 +1801,87 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(variant_def) = variant_def {
if permit_variants {
tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
self.prohibit_generics(slice::from_ref(assoc_segment));
self.prohibit_generics(slice::from_ref(assoc_segment).iter(), |err| {
err.note("enum variants can't have type parameters");
let type_name = tcx.item_name(adt_def.did());
let msg = format!(
"you might have meant to specity type parameters on enum \
`{type_name}`"
);
let Some(args) = assoc_segment.args else { return; };
// Get the span of the generics args *including* the leading `::`.
let args_span = assoc_segment.ident.span.shrink_to_hi().to(args.span_ext);
if tcx.generics_of(adt_def.did()).count() == 0 {
// FIXME(estebank): we could also verify that the arguments being
// work for the `enum`, instead of just looking if it takes *any*.
err.span_suggestion_verbose(
args_span,
&format!("{type_name} doesn't have generic parameters"),
String::new(),
Applicability::MachineApplicable,
);
return;
}
let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else {
err.note(&msg);
return;
};
let (qself_sugg_span, is_self) = if let hir::TyKind::Path(
hir::QPath::Resolved(_, ref path)
) = qself.kind {
// If the path segment already has type params, we want to overwrite
// them.
match &path.segments[..] {
// `segment` is the previous to last element on the path,
// which would normally be the `enum` itself, while the last
// `_` `PathSegment` corresponds to the variant.
[.., hir::PathSegment {
ident,
args,
res: Some(Res::Def(DefKind::Enum, _)),
..
}, _] => (
// We need to include the `::` in `Type::Variant::<Args>`
// to point the span to `::<Args>`, not just `<Args>`.
ident.span.shrink_to_hi().to(args.map_or(
ident.span.shrink_to_hi(),
|a| a.span_ext)),
false,
),
[segment] => (
// We need to include the `::` in `Type::Variant::<Args>`
// to point the span to `::<Args>`, not just `<Args>`.
segment.ident.span.shrink_to_hi().to(segment.args.map_or(
segment.ident.span.shrink_to_hi(),
|a| a.span_ext)),
kw::SelfUpper == segment.ident.name,
),
_ => {
err.note(&msg);
return;
}
}
} else {
err.note(&msg);
return;
};
let suggestion = vec![
if is_self {
// Account for people writing `Self::Variant::<Args>`, where
// `Self` is the enum, and suggest replacing `Self` with the
// appropriate type: `Type::<Args>::Variant`.
(qself.span, format!("{type_name}{snippet}"))
} else {
(qself_sugg_span, snippet)
},
(args_span, String::new()),
];
err.multipart_suggestion_verbose(
&msg,
suggestion,
Applicability::MaybeIncorrect,
);
});
return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
} else {
variant_resolution = Some(variant_def.def_id);
@ -2017,69 +2102,112 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs))
}
pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment<'a>>>(
pub fn prohibit_generics<'a>(
&self,
segments: T,
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
) -> bool {
let mut has_err = false;
for segment in segments {
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in segment.args().args {
let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt {
continue;
}
err_for_lt = true;
has_err = true;
(lt.span, "lifetime")
let args = segments.clone().flat_map(|segment| segment.args().args);
let types_and_spans: Vec<_> = segments
.clone()
.flat_map(|segment| {
segment.res.and_then(|res| {
if segment.args().args.is_empty() {
None
} else {
Some((
match res {
Res::PrimTy(ty) => format!("{} `{}`", res.descr(), ty.name()),
Res::Def(_, def_id)
if let Some(name) = self.tcx().opt_item_name(def_id) => {
format!("{} `{name}`", res.descr())
}
Res::Err => "this type".to_string(),
_ => res.descr().to_string(),
},
segment.ident.span,
))
}
hir::GenericArg::Type(ty) => {
if err_for_ty {
continue;
}
err_for_ty = true;
has_err = true;
(ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct {
continue;
}
err_for_ct = true;
has_err = true;
(ct.span, "const")
}
hir::GenericArg::Infer(inf) => {
if err_for_ty {
continue;
}
has_err = true;
err_for_ty = true;
(inf.span, "generic")
}
};
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{} arguments are not allowed for this type",
kind,
);
err.span_label(span, format!("{} argument not allowed", kind));
err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
}
}
})
})
.collect();
let this_type = match &types_and_spans[..] {
[.., _, (last, _)] => format!(
"{} and {last}",
types_and_spans[..types_and_spans.len() - 1]
.iter()
.map(|(x, _)| x.as_str())
.intersperse(&", ")
.collect::<String>()
),
[(only, _)] => only.to_string(),
[] => "this type".to_string(),
};
let (lt, ty, ct, inf) =
args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg {
hir::GenericArg::Lifetime(_) => (true, ty, ct, inf),
hir::GenericArg::Type(_) => (lt, true, ct, inf),
hir::GenericArg::Const(_) => (lt, ty, true, inf),
hir::GenericArg::Infer(_) => (lt, ty, ct, true),
});
let mut emitted = false;
if lt || ty || ct || inf {
let arg_spans: Vec<Span> = args.map(|arg| arg.span()).collect();
let mut kinds = Vec::with_capacity(4);
if lt {
kinds.push("lifetime");
}
if ty {
kinds.push("type");
}
if ct {
kinds.push("const");
}
if inf {
kinds.push("generic");
}
let (kind, s) = match kinds[..] {
[.., _, last] => (
format!(
"{} and {last}",
kinds[..kinds.len() - 1]
.iter()
.map(|&x| x)
.intersperse(", ")
.collect::<String>()
),
"s",
),
[only] => (format!("{only}"), ""),
[] => unreachable!(),
};
let last_span = *arg_spans.last().unwrap();
let span: MultiSpan = arg_spans.into();
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{kind} arguments are not allowed on {this_type}",
);
err.span_label(last_span, format!("{kind} argument{s} not allowed"));
for (_, span) in types_and_spans {
err.span_label(span, "not allowed on this");
}
extend(&mut err);
err.emit();
emitted = true;
}
for segment in segments {
// Only emit the first error to avoid overloading the user with error messages.
if let [binding, ..] = segment.args().bindings {
has_err = true;
Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
return true;
}
}
has_err
emitted
}
// FIXME(eddyb, varkor) handle type paths here too, not just value ones.
@ -2229,7 +2357,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Check for desugared `impl Trait`.
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
let item_segment = path.segments.split_last().unwrap();
self.prohibit_generics(item_segment.1);
self.prohibit_generics(item_segment.1.iter(), |err| {
err.note("`impl Trait` types can't have type parameters");
});
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
self.normalize_ty(span, tcx.mk_opaque(did, substs))
}
@ -2242,7 +2372,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
did,
) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments.split_last().unwrap().1);
self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {});
self.ast_path_to_ty(span, did, path.segments.last().unwrap())
}
Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
@ -2254,18 +2384,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.def_ids_for_value_path_segments(path.segments, None, kind, def_id);
let generic_segs: FxHashSet<_> =
path_segs.iter().map(|PathSeg(_, index)| index).collect();
self.prohibit_generics(path.segments.iter().enumerate().filter_map(
|(index, seg)| {
self.prohibit_generics(
path.segments.iter().enumerate().filter_map(|(index, seg)| {
if !generic_segs.contains(&index) { Some(seg) } else { None }
}),
|err| {
err.note("enum variants can't have type parameters");
},
));
);
let PathSeg(def_id, index) = path_segs.last().unwrap();
self.ast_path_to_ty(span, *def_id, &path.segments[*index])
}
Res::Def(DefKind::TyParam, def_id) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments);
self.prohibit_generics(path.segments.iter(), |err| {
if let Some(span) = tcx.def_ident_span(def_id) {
let name = tcx.item_name(def_id);
err.span_note(span, &format!("type parameter `{name}` defined here"));
}
});
let def_id = def_id.expect_local();
let item_def_id = tcx.hir().ty_param_owner(def_id);
@ -2276,15 +2414,81 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Res::SelfTy { trait_: Some(_), alias_to: None } => {
// `Self` in trait or type alias.
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments);
self.prohibit_generics(path.segments.iter(), |err| {
if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments[..] {
err.span_suggestion_verbose(
ident.span.shrink_to_hi().to(args.span_ext),
"the `Self` type doesn't accept type parameters",
String::new(),
Applicability::MaybeIncorrect,
);
}
});
tcx.types.self_param
}
Res::SelfTy { trait_: _, alias_to: Some((def_id, forbid_generic)) } => {
// `Self` in impl (we know the concrete type).
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments);
// Try to evaluate any array length constants.
let ty = tcx.at(span).type_of(def_id);
let span_of_impl = tcx.span_of_impl(def_id);
self.prohibit_generics(path.segments.iter(), |err| {
let def_id = match *ty.kind() {
ty::Adt(self_def, _) => self_def.did(),
_ => return,
};
let type_name = tcx.item_name(def_id);
let span_of_ty = tcx.def_ident_span(def_id);
let generics = tcx.generics_of(def_id).count();
let msg = format!("`Self` is of type `{ty}`");
if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) {
let i_sp = tcx.sess.source_map().guess_head_span(i_sp);
let mut span: MultiSpan = vec![t_sp].into();
span.push_span_label(
i_sp,
&format!("`Self` is on type `{type_name}` in this `impl`"),
);
let mut postfix = "";
if generics == 0 {
postfix = ", which doesn't have generic parameters";
}
span.push_span_label(
t_sp,
&format!("`Self` corresponds to this type{postfix}"),
);
err.span_note(span, &msg);
} else {
err.note(&msg);
}
for segment in path.segments {
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*.
err.span_suggestion_verbose(
segment.ident.span.shrink_to_hi().to(args.span_ext),
"the `Self` type doesn't accept type parameters",
String::new(),
Applicability::MachineApplicable,
);
return;
} else {
err.span_suggestion_verbose(
segment.ident.span,
format!(
"the `Self` type doesn't accept type parameters, use the \
concrete type's name `{type_name}` instead if you want to \
specify its type parameters"
),
type_name.to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
});
// HACK(min_const_generics): Forbid generic `Self` types
// here as we can't easily do that during nameres.
//
@ -2324,7 +2528,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
Res::Def(DefKind::AssocTy, def_id) => {
debug_assert!(path.segments.len() >= 2);
self.prohibit_generics(&path.segments[..path.segments.len() - 2]);
self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {});
self.qpath_to_ty(
span,
opt_self_ty,
@ -2335,7 +2539,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
Res::PrimTy(prim_ty) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments);
self.prohibit_generics(path.segments.iter(), |err| {
let name = prim_ty.name_str();
for segment in path.segments {
if let Some(args) = segment.args {
err.span_suggestion_verbose(
segment.ident.span.shrink_to_hi().to(args.span_ext),
&format!("primitive type `{name}` doesn't have generic parameters"),
String::new(),
Applicability::MaybeIncorrect,
);
}
}
});
match prim_ty {
hir::PrimTy::Bool => tcx.types.bool,
hir::PrimTy::Char => tcx.types.char,
@ -2426,13 +2642,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
debug!(?qself, ?segment);
let ty = self.ast_ty_to_ty_inner(qself, false, true);
let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = qself.kind {
path.res
} else {
Res::Err
};
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, res, segment, false)
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false)
.map(|(ty, _, _)| ty)
.unwrap_or_else(|_| tcx.ty_error())
}

View File

@ -1228,6 +1228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
}),
|_| {},
);
if let Res::Local(hid) = res {

View File

@ -1564,13 +1564,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
QPath::TypeRelative(ref qself, ref segment) => {
let ty = self.to_ty(qself);
let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
path.res
} else {
Res::Err
};
let result = <dyn AstConv<'_>>::associated_path_to_ty(
self, hir_id, path_span, ty, res, segment, true,
self, hir_id, path_span, ty, qself, segment, true,
);
let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
let result = result.map(|(_, kind, def_id)| (kind, def_id));

View File

@ -1364,7 +1364,6 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
fn has_late_bound_regions<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
generics: &'tcx hir::Generics<'tcx>,
decl: &'tcx hir::FnDecl<'tcx>,
) -> Option<Span> {
@ -1373,14 +1372,9 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
outer_index: ty::INNERMOST,
has_late_bound_regions: None,
};
let late_bound_map = tcx.is_late_bound_map(def_id);
let is_late_bound = |id| {
let id = tcx.hir().local_def_id(id);
late_bound_map.map_or(false, |(_, set)| set.contains(&id))
};
for param in generics.params {
if let GenericParamKind::Lifetime { .. } = param.kind {
if is_late_bound(param.hir_id) {
if tcx.is_late_bound(param.hir_id) {
return Some(param.span);
}
}
@ -1392,25 +1386,25 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
match node {
Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Fn(ref sig, _) => {
has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl)
has_late_bound_regions(tcx, &item.generics, sig.decl)
}
_ => None,
},
Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Fn(ref sig, _) => {
has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl)
has_late_bound_regions(tcx, &item.generics, sig.decl)
}
_ => None,
},
Node::ForeignItem(item) => match item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
has_late_bound_regions(tcx, item.def_id, generics, fn_decl)
has_late_bound_regions(tcx, generics, fn_decl)
}
_ => None,
},
Node::Item(item) => match item.kind {
hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
has_late_bound_regions(tcx, item.def_id, generics, sig.decl)
has_late_bound_regions(tcx, generics, sig.decl)
}
_ => None,
},
@ -1671,7 +1665,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
params.push(opt_self);
}
let early_lifetimes = early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics);
let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
name: param.name.ident().name,
index: own_start + i as u32,
@ -2054,23 +2048,10 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
/// `resolve_lifetime::early_bound_lifetimes`.
fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
generics: &'a hir::Generics<'a>,
) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> {
let late_bound_map = if generics.params.is_empty() {
// This function may be called on `def_id == CRATE_DEF_ID`,
// which makes `is_late_bound_map` ICE. Don't even try if there
// is no generic parameter.
None
} else {
tcx.is_late_bound_map(def_id)
};
let is_late_bound = move |hir_id| {
let id = tcx.hir().local_def_id(hir_id);
late_bound_map.map_or(false, |(_, set)| set.contains(&id))
};
generics.params.iter().filter(move |param| match param.kind {
GenericParamKind::Lifetime { .. } => !is_late_bound(param.hir_id),
GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
_ => false,
})
}
@ -2255,7 +2236,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
// have to be careful to only iterate over early-bound regions.
let mut index = parent_count
+ has_own_self as u32
+ early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics).count() as u32;
+ early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
// Collect the predicates that were written inline by the user on each
// type parameter (e.g., `<T: Foo>`).

View File

@ -514,7 +514,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
param_names
.iter()
.take(num_params_to_take)
.map(|p| p.as_str())
.map(|def_id| {
self.tcx.item_name(def_id.to_def_id()).to_ident_string()
})
.collect::<Vec<_>>()
.join(", ")
} else {

View File

@ -475,24 +475,14 @@ fn clean_generic_param<'tcx>(
generics: Option<&hir::Generics<'tcx>>,
param: &hir::GenericParam<'tcx>,
) -> GenericParamDef {
let did = cx.tcx.hir().local_def_id(param.hir_id);
let (name, kind) = match param.kind {
hir::GenericParamKind::Lifetime { .. } => {
let outlives = if let Some(generics) = generics {
generics
.predicates
.iter()
.flat_map(|pred| {
match pred {
hir::WherePredicate::RegionPredicate(rp)
if rp.lifetime.name == hir::LifetimeName::Param(param.name)
&& !rp.in_where_clause =>
{
rp.bounds
}
_ => &[],
}
.iter()
})
.outlives_for_param(did)
.filter(|bp| !bp.in_where_clause)
.flat_map(|bp| bp.bounds)
.map(|bound| match bound {
hir::GenericBound::Outlives(lt) => lt.clean(cx),
_ => panic!(),
@ -504,7 +494,6 @@ fn clean_generic_param<'tcx>(
(param.name.ident().name, GenericParamDefKind::Lifetime { outlives })
}
hir::GenericParamKind::Type { ref default, synthetic } => {
let did = cx.tcx.hir().local_def_id(param.hir_id);
let bounds = if let Some(generics) = generics {
generics
.bounds_for_param(did)
@ -528,7 +517,7 @@ fn clean_generic_param<'tcx>(
hir::GenericParamKind::Const { ty, default } => (
param.name.ident().name,
GenericParamDefKind::Const {
did: cx.tcx.hir().local_def_id(param.hir_id).to_def_id(),
did: did.to_def_id(),
ty: Box::new(ty.clean(cx)),
default: default.map(|ct| {
let def_id = cx.tcx.hir().local_def_id(ct.hir_id);
@ -1459,7 +1448,7 @@ impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> {
// Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
// there's no case where it could cause the function to fail to compile.
let elided =
l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_)));
l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
let lifetime = if elided { None } else { Some(l.clean(cx)) };
BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
}

View File

@ -70,5 +70,13 @@ module.exports = {
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-ex-assign": "error",
"no-fallthrough": "error",
"no-invalid-regexp": "error",
"no-import-assign": "error",
"no-self-compare": "error",
"no-template-curly-in-string": "error",
"block-scoped-var": "error",
"guard-for-in": "error",
"no-alert": "error",
}
};

View File

@ -1,7 +1,7 @@
use std::fmt::Debug;
#[derive(Debug)]
pub struct Irrelevant<Irrelevant> { //~ ERROR type arguments are not allowed for this type
pub struct Irrelevant<Irrelevant> { //~ ERROR type arguments are not allowed on type parameter
irrelevant: Irrelevant,
}

View File

@ -1,11 +1,19 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on type parameter `Irrelevant`
--> $DIR/issue-97343.rs:4:23
|
LL | #[derive(Debug)]
| ----- in this derive macro expansion
| -----
| |
| not allowed on this
| in this derive macro expansion
LL | pub struct Irrelevant<Irrelevant> {
| ^^^^^^^^^^ type argument not allowed
|
note: type parameter `Irrelevant` defined here
--> $DIR/issue-97343.rs:4:23
|
LL | pub struct Irrelevant<Irrelevant> {
| ^^^^^^^^^^
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error

View File

@ -1,8 +1,16 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/E0109.rs:1:14
|
LL | type X = u32<i32>;
| ^^^ type argument not allowed
| --- ^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `u32` doesn't have generic parameters
|
LL - type X = u32<i32>;
LL + type X = u32;
|
error: aborting due to previous error

View File

@ -1,8 +1,16 @@
error[E0109]: lifetime arguments are not allowed for this type
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/E0110.rs:1:14
|
LL | type X = u32<'static>;
| ^^^^^^^ lifetime argument not allowed
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `u32` doesn't have generic parameters
|
LL - type X = u32<'static>;
LL + type X = u32;
|
error: aborting due to previous error

View File

@ -1,3 +1,3 @@
fn is_copy<T: ::std::marker<i32>::Copy>() {}
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on module `marker` [E0109]
fn main() {}

View File

@ -1,8 +1,10 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on module `marker`
--> $DIR/issue-22706.rs:1:29
|
LL | fn is_copy<T: ::std::marker<i32>::Copy>() {}
| ^^^ type argument not allowed
| ------ ^^^ type argument not allowed
| |
| not allowed on this
error: aborting due to previous error

View File

@ -3,7 +3,7 @@ pub struct Gcm<E>(E);
impl<E> Gcm<E> {
pub fn crash(e: E) -> Self {
Self::<E>(e)
//~^ ERROR type arguments are not allowed for this type
//~^ ERROR type arguments are not allowed on self constructor
}
}

View File

@ -1,8 +1,10 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self constructor
--> $DIR/issue-57924.rs:5:16
|
LL | Self::<E>(e)
| ^ type argument not allowed
| ---- ^ type argument not allowed
| |
| not allowed on this
error: aborting due to previous error

View File

@ -10,9 +10,9 @@ impl From<A> for B {
fn main() {
let c1 = ();
c1::<()>;
//~^ ERROR type arguments are not allowed for this type
//~^ ERROR type arguments are not allowed on local variable
let c1 = A {};
c1::<dyn Into<B>>;
//~^ ERROR type arguments are not allowed for this type
//~^ ERROR type arguments are not allowed on local variable
}

View File

@ -1,14 +1,18 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on local variable
--> $DIR/issue-60989.rs:12:10
|
LL | c1::<()>;
| ^^ type argument not allowed
| -- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on local variable
--> $DIR/issue-60989.rs:16:10
|
LL | c1::<dyn Into<B>>;
| ^^^^^^^^^^^ type argument not allowed
| -- ^^^^^^^^^^^ type argument not allowed
| |
| not allowed on this
error: aborting due to 2 previous errors

View File

@ -5,5 +5,5 @@ mod Mod {
fn main() {
Mod::FakeVariant::<i32>(0);
Mod::<i32>::FakeVariant(0);
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on module `Mod` [E0109]
}

View File

@ -1,8 +1,10 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on module `Mod`
--> $DIR/mod-subitem-as-enum-variant.rs:7:11
|
LL | Mod::<i32>::FakeVariant(0);
| ^^^ type argument not allowed
| --- ^^^ type argument not allowed
| |
| not allowed on this
error: aborting due to previous error

View File

@ -13,7 +13,7 @@ fn f<T: Tr>() {
//~^ ERROR expected struct, variant or union type, found associated type
let z = T::A::<u8> {};
//~^ ERROR expected struct, variant or union type, found associated type
//~| ERROR type arguments are not allowed for this type
//~| ERROR type arguments are not allowed on this type
match S {
T::A {} => {}
//~^ ERROR expected struct, variant or union type, found associated type
@ -22,7 +22,7 @@ fn f<T: Tr>() {
fn g<T: Tr<A = S>>() {
let s = T::A {}; // OK
let z = T::A::<u8> {}; //~ ERROR type arguments are not allowed for this type
let z = T::A::<u8> {}; //~ ERROR type arguments are not allowed on this type
match S {
T::A {} => {} // OK
}

View File

@ -4,11 +4,13 @@ error[E0071]: expected struct, variant or union type, found associated type
LL | let s = T::A {};
| ^^^^ not a struct
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/struct-path-associated-type.rs:14:20
|
LL | let z = T::A::<u8> {};
| ^^ type argument not allowed
| - ^^ type argument not allowed
| |
| not allowed on this
error[E0071]: expected struct, variant or union type, found associated type
--> $DIR/struct-path-associated-type.rs:14:13
@ -22,11 +24,13 @@ error[E0071]: expected struct, variant or union type, found associated type
LL | T::A {} => {}
| ^^^^ not a struct
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/struct-path-associated-type.rs:25:20
|
LL | let z = T::A::<u8> {};
| ^^ type argument not allowed
| - ^^ type argument not allowed
| |
| not allowed on this
error[E0223]: ambiguous associated type
--> $DIR/struct-path-associated-type.rs:32:13

View File

@ -6,7 +6,7 @@ trait Tr {
//~^ ERROR expected struct, variant or union type, found type parameter
let z = Self::<u8> {};
//~^ ERROR expected struct, variant or union type, found type parameter
//~| ERROR type arguments are not allowed for this type
//~| ERROR type arguments are not allowed on self type
match s {
Self { .. } => {}
//~^ ERROR expected struct, variant or union type, found type parameter
@ -17,7 +17,7 @@ trait Tr {
impl Tr for S {
fn f() {
let s = Self {}; // OK
let z = Self::<u8> {}; //~ ERROR type arguments are not allowed for this type
let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on self type
match s {
Self { .. } => {} // OK
}
@ -27,7 +27,7 @@ impl Tr for S {
impl S {
fn g() {
let s = Self {}; // OK
let z = Self::<u8> {}; //~ ERROR type arguments are not allowed for this type
let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on self type
match s {
Self { .. } => {} // OK
}

View File

@ -4,11 +4,19 @@ error[E0071]: expected struct, variant or union type, found type parameter `Self
LL | let s = Self {};
| ^^^^ not a struct
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/struct-path-self.rs:7:24
|
LL | let z = Self::<u8> {};
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
help: the `Self` type doesn't accept type parameters
|
LL - let z = Self::<u8> {};
LL + let z = Self {};
|
error[E0071]: expected struct, variant or union type, found type parameter `Self`
--> $DIR/struct-path-self.rs:7:17
@ -22,17 +30,49 @@ error[E0071]: expected struct, variant or union type, found type parameter `Self
LL | Self { .. } => {}
| ^^^^ not a struct
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/struct-path-self.rs:20:24
|
LL | let z = Self::<u8> {};
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `S`
--> $DIR/struct-path-self.rs:1:8
|
LL | struct S;
| ^ `Self` corresponds to this type, which doesn't have generic parameters
...
LL | impl Tr for S {
| ------------- `Self` is on type `S` in this `impl`
help: the `Self` type doesn't accept type parameters
|
LL - let z = Self::<u8> {};
LL + let z = Self {};
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/struct-path-self.rs:30:24
|
LL | let z = Self::<u8> {};
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `S`
--> $DIR/struct-path-self.rs:1:8
|
LL | struct S;
| ^ `Self` corresponds to this type, which doesn't have generic parameters
...
LL | impl S {
| ------ `Self` is on type `S` in this `impl`
help: the `Self` type doesn't accept type parameters
|
LL - let z = Self::<u8> {};
LL + let z = Self {};
|
error: aborting due to 6 previous errors

View File

@ -13,38 +13,38 @@ impl<T> Enum<T> {
Self::TSVariant(());
//~^ ERROR mismatched types [E0308]
Self::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Self::<()>::TSVariant(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
//~| ERROR mismatched types [E0308]
Self::<()>::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~| ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
//~| ERROR type arguments are not allowed on this type [E0109]
}
fn s_variant() {
Self::SVariant { v: () };
//~^ ERROR mismatched types [E0308]
Self::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
//~| ERROR mismatched types [E0308]
Self::<()>::SVariant { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
//~| ERROR mismatched types [E0308]
Self::<()>::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~| ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
//~| ERROR type arguments are not allowed on this type [E0109]
//~| ERROR mismatched types [E0308]
}
fn u_variant() {
Self::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Self::<()>::UVariant;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
Self::<()>::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~| ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on self type [E0109]
//~| ERROR type arguments are not allowed on this type [E0109]
}
}
@ -52,54 +52,54 @@ fn main() {
// Tuple struct variant
Enum::<()>::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::<()>::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::<()>::TSVariant(());
//~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
//~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
// Struct variant
Enum::<()>::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::<()>::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::<()>::SVariant { v: () };
//~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
//~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
// Unit variant
Enum::<()>::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
Alias::<()>::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
AliasFixed::<()>::UVariant;
//~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
//~^ ERROR type arguments are not allowed on this type [E0109]
//~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
}

View File

@ -17,17 +17,34 @@ note: tuple variant defined here
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^^^^^^
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:15:27
|
LL | Self::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:17:16
|
LL | Self::<()>::TSVariant(());
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::TSVariant(());
| ~~~~
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:17:31
@ -48,17 +65,34 @@ note: tuple variant defined here
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^^^^^^
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:20:16
|
LL | Self::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::TSVariant::<()>(());
| ~~~~
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:20:33
|
LL | Self::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:26:29
@ -72,11 +106,20 @@ LL | Self::SVariant { v: () };
= note: expected type parameter `T`
found unit type `()`
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:28:26
|
LL | Self::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - Self::SVariant::<()> { v: () };
LL + Enum::<()>::SVariant { v: () };
|
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:28:35
@ -90,11 +133,26 @@ LL | Self::SVariant::<()> { v: () };
= note: expected type parameter `T`
found unit type `()`
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:31:16
|
LL | Self::<()>::SVariant { v: () };
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::SVariant { v: () };
| ~~~~
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:31:35
@ -108,17 +166,41 @@ LL | Self::<()>::SVariant { v: () };
= note: expected type parameter `T`
found unit type `()`
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:34:16
|
LL | Self::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::SVariant::<()> { v: () };
| ~~~~
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:34:32
|
LL | Self::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - Self::<()>::SVariant::<()> { v: () };
LL + Enum::<()>::SVariant { v: () };
|
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:34:41
@ -132,53 +214,95 @@ LL | Self::<()>::SVariant::<()> { v: () };
= note: expected type parameter `T`
found unit type `()`
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:41:26
|
LL | Self::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:43:16
|
LL | Self::<()>::UVariant;
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::UVariant;
| ~~~~
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on self type
--> $DIR/enum-variant-generic-args.rs:45:16
|
LL | Self::<()>::UVariant::<()>;
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
|
note: `Self` is of type `Enum<T>`
--> $DIR/enum-variant-generic-args.rs:7:6
|
LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
| ^^^^ `Self` corresponds to this type
...
LL | impl<T> Enum<T> {
| --------------- `Self` is on type `Enum` in this `impl`
help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
|
LL | Enum::<()>::UVariant::<()>;
| ~~~~
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:45:32
|
LL | Self::<()>::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:54:29
|
LL | Enum::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:57:24
|
LL | Alias::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:59:30
|
LL | Alias::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:62:29
|
LL | AliasFixed::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:64:5
@ -208,35 +332,68 @@ note: type alias defined here, with 0 generic parameters
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:66:35
|
LL | AliasFixed::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
| --------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:72:28
|
LL | Enum::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:75:23
|
LL | Alias::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - Alias::SVariant::<()> { v: () };
LL + Alias::<()>::SVariant { v: () };
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:77:29
|
LL | Alias::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - Alias::<()>::SVariant::<()> { v: () };
LL + Alias::<()>::SVariant { v: () };
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:80:28
|
LL | AliasFixed::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - AliasFixed::SVariant::<()> { v: () };
LL + AliasFixed::<()>::SVariant { v: () };
|
error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:82:5
@ -266,35 +423,52 @@ note: type alias defined here, with 0 generic parameters
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:84:34
|
LL | AliasFixed::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
|
= note: enum variants can't have type parameters
help: you might have meant to specity type parameters on enum `Enum`
|
LL - AliasFixed::<()>::SVariant::<()> { v: () };
LL + AliasFixed::<()>::SVariant { v: () };
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:90:28
|
LL | Enum::<()>::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:93:23
|
LL | Alias::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:95:29
|
LL | Alias::<()>::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:98:28
|
LL | AliasFixed::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:100:5
@ -324,11 +498,13 @@ note: type alias defined here, with 0 generic parameters
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/enum-variant-generic-args.rs:102:34
|
LL | AliasFixed::<()>::UVariant::<()>;
| ^^ type argument not allowed
| -------- ^^ type argument not allowed
| |
| not allowed on this
error: aborting due to 39 previous errors

View File

@ -10,5 +10,5 @@ fn main() {
let _ = Option::<u8>::None; // OK
let _ = Option::None::<u8>; // OK (Lint in future!)
let _ = Alias::<u8>::None; // OK
let _ = Alias::None::<u8>; //~ ERROR type arguments are not allowed for this type
let _ = Alias::None::<u8>; //~ ERROR type arguments are not allowed on this type
}

View File

@ -1,8 +1,10 @@
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27
|
LL | let _ = Alias::None::<u8>;
| ^^ type argument not allowed
| ---- ^^ type argument not allowed
| |
| not allowed on this
error: aborting due to previous error

View File

@ -1,7 +1,7 @@
// error-pattern: this file contains an unclosed delimiter
// error-pattern: cannot find type `ţ` in this scope
// error-pattern: parenthesized type parameters may only be used with a `Fn` trait
// error-pattern: type arguments are not allowed for this type
// error-pattern: type arguments are not allowed on this type
// error-pattern: mismatched types
// ignore-tidy-trailing-newlines
// `ţ` must be the last character in this file, it cannot be followed by a newline

View File

@ -30,11 +30,19 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
LL | 0: u8(ţ
| ^^^^ only `Fn` traits may use parentheses
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/issue-91268.rs:9:11
|
LL | 0: u8(ţ
| ^ type argument not allowed
| -- ^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `u8` doesn't have generic parameters
|
LL - 0: u8(ţ
LL + 0: u8
|
error[E0308]: mismatched types
--> $DIR/issue-91268.rs:9:5

View File

@ -0,0 +1,28 @@
// run-rustfix
fn main() {
let _x: isize; //~ ERROR type arguments are not allowed on this type
let _x: i8; //~ ERROR type arguments are not allowed on this type
let _x: i16; //~ ERROR type arguments are not allowed on this type
let _x: i32; //~ ERROR type arguments are not allowed on this type
let _x: i64; //~ ERROR type arguments are not allowed on this type
let _x: usize; //~ ERROR type arguments are not allowed on this type
let _x: u8; //~ ERROR type arguments are not allowed on this type
let _x: u16; //~ ERROR type arguments are not allowed on this type
let _x: u32; //~ ERROR type arguments are not allowed on this type
let _x: u64; //~ ERROR type arguments are not allowed on this type
let _x: char; //~ ERROR type arguments are not allowed on this type
let _x: isize; //~ ERROR lifetime arguments are not allowed on this type
let _x: i8; //~ ERROR lifetime arguments are not allowed on this type
let _x: i16; //~ ERROR lifetime arguments are not allowed on this type
let _x: i32; //~ ERROR lifetime arguments are not allowed on this type
let _x: i64; //~ ERROR lifetime arguments are not allowed on this type
let _x: usize; //~ ERROR lifetime arguments are not allowed on this type
let _x: u8; //~ ERROR lifetime arguments are not allowed on this type
let _x: u16; //~ ERROR lifetime arguments are not allowed on this type
let _x: u32; //~ ERROR lifetime arguments are not allowed on this type
let _x: u64; //~ ERROR lifetime arguments are not allowed on this type
let _x: char; //~ ERROR lifetime arguments are not allowed on this type
}

View File

@ -1,27 +1,28 @@
// run-rustfix
fn main() {
let x: isize<isize>; //~ ERROR type arguments are not allowed for this type
let x: i8<isize>; //~ ERROR type arguments are not allowed for this type
let x: i16<isize>; //~ ERROR type arguments are not allowed for this type
let x: i32<isize>; //~ ERROR type arguments are not allowed for this type
let x: i64<isize>; //~ ERROR type arguments are not allowed for this type
let x: usize<isize>; //~ ERROR type arguments are not allowed for this type
let x: u8<isize>; //~ ERROR type arguments are not allowed for this type
let x: u16<isize>; //~ ERROR type arguments are not allowed for this type
let x: u32<isize>; //~ ERROR type arguments are not allowed for this type
let x: u64<isize>; //~ ERROR type arguments are not allowed for this type
let x: char<isize>; //~ ERROR type arguments are not allowed for this type
let _x: isize<isize>; //~ ERROR type arguments are not allowed on this type
let _x: i8<isize>; //~ ERROR type arguments are not allowed on this type
let _x: i16<isize>; //~ ERROR type arguments are not allowed on this type
let _x: i32<isize>; //~ ERROR type arguments are not allowed on this type
let _x: i64<isize>; //~ ERROR type arguments are not allowed on this type
let _x: usize<isize>; //~ ERROR type arguments are not allowed on this type
let _x: u8<isize>; //~ ERROR type arguments are not allowed on this type
let _x: u16<isize>; //~ ERROR type arguments are not allowed on this type
let _x: u32<isize>; //~ ERROR type arguments are not allowed on this type
let _x: u64<isize>; //~ ERROR type arguments are not allowed on this type
let _x: char<isize>; //~ ERROR type arguments are not allowed on this type
let x: isize<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: i8<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: i16<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: i32<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: i64<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: usize<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: u8<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: u16<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: u32<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: u64<'static>; //~ ERROR lifetime arguments are not allowed for this type
let x: char<'static>; //~ ERROR lifetime arguments are not allowed for this type
let _x: isize<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this type
let _x: char<'static>; //~ ERROR lifetime arguments are not allowed on this type
}

View File

@ -1,134 +1,310 @@
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:3:14
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:4:15
|
LL | let x: isize<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:4:11
LL | let _x: isize<isize>;
| ----- ^^^^^ type argument not allowed
| |
| not allowed on this
|
LL | let x: i8<isize>;
| ^^^^^ type argument not allowed
help: primitive type `isize` doesn't have generic parameters
|
LL - let _x: isize<isize>;
LL + let _x: isize;
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:5:12
|
LL | let x: i16<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:6:12
LL | let _x: i8<isize>;
| -- ^^^^^ type argument not allowed
| |
| not allowed on this
|
LL | let x: i32<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:7:12
help: primitive type `i8` doesn't have generic parameters
|
LL | let x: i64<isize>;
| ^^^^^ type argument not allowed
LL - let _x: i8<isize>;
LL + let _x: i8;
|
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:8:14
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:6:13
|
LL | let x: usize<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:9:11
LL | let _x: i16<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
LL | let x: u8<isize>;
| ^^^^^ type argument not allowed
help: primitive type `i16` doesn't have generic parameters
|
LL - let _x: i16<isize>;
LL + let _x: i16;
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:7:13
|
LL | let _x: i32<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `i32` doesn't have generic parameters
|
LL - let _x: i32<isize>;
LL + let _x: i32;
|
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:8:13
|
LL | let _x: i64<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `i64` doesn't have generic parameters
|
LL - let _x: i64<isize>;
LL + let _x: i64;
|
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:9:15
|
LL | let _x: usize<isize>;
| ----- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `usize` doesn't have generic parameters
|
LL - let _x: usize<isize>;
LL + let _x: usize;
|
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:10:12
|
LL | let x: u16<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:11:12
LL | let _x: u8<isize>;
| -- ^^^^^ type argument not allowed
| |
| not allowed on this
|
LL | let x: u32<isize>;
| ^^^^^ type argument not allowed
error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:12:12
help: primitive type `u8` doesn't have generic parameters
|
LL | let x: u64<isize>;
| ^^^^^ type argument not allowed
LL - let _x: u8<isize>;
LL + let _x: u8;
|
error[E0109]: type arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:11:13
|
LL | let _x: u16<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `u16` doesn't have generic parameters
|
LL - let _x: u16<isize>;
LL + let _x: u16;
|
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:12:13
|
LL | let _x: u32<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `u32` doesn't have generic parameters
|
LL - let _x: u32<isize>;
LL + let _x: u32;
|
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:13:13
|
LL | let x: char<isize>;
| ^^^^^ type argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:15:14
LL | let _x: u64<isize>;
| --- ^^^^^ type argument not allowed
| |
| not allowed on this
|
LL | let x: isize<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:16:11
help: primitive type `u64` doesn't have generic parameters
|
LL | let x: i8<'static>;
| ^^^^^^^ lifetime argument not allowed
LL - let _x: u64<isize>;
LL + let _x: u64;
|
error[E0109]: lifetime arguments are not allowed for this type
error[E0109]: type arguments are not allowed on this type
--> $DIR/prim-with-args.rs:14:14
|
LL | let _x: char<isize>;
| ---- ^^^^^ type argument not allowed
| |
| not allowed on this
|
help: primitive type `char` doesn't have generic parameters
|
LL - let _x: char<isize>;
LL + let _x: char;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:16:15
|
LL | let _x: isize<'static>;
| ----- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `isize` doesn't have generic parameters
|
LL - let _x: isize<'static>;
LL + let _x: isize;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:17:12
|
LL | let x: i16<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:18:12
LL | let _x: i8<'static>;
| -- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
LL | let x: i32<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:19:12
help: primitive type `i8` doesn't have generic parameters
|
LL | let x: i64<'static>;
| ^^^^^^^ lifetime argument not allowed
LL - let _x: i8<'static>;
LL + let _x: i8;
|
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:20:14
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:18:13
|
LL | let x: usize<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:21:11
LL | let _x: i16<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
LL | let x: u8<'static>;
| ^^^^^^^ lifetime argument not allowed
help: primitive type `i16` doesn't have generic parameters
|
LL - let _x: i16<'static>;
LL + let _x: i16;
|
error[E0109]: lifetime arguments are not allowed for this type
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:19:13
|
LL | let _x: i32<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `i32` doesn't have generic parameters
|
LL - let _x: i32<'static>;
LL + let _x: i32;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:20:13
|
LL | let _x: i64<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `i64` doesn't have generic parameters
|
LL - let _x: i64<'static>;
LL + let _x: i64;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:21:15
|
LL | let _x: usize<'static>;
| ----- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `usize` doesn't have generic parameters
|
LL - let _x: usize<'static>;
LL + let _x: usize;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:22:12
|
LL | let x: u16<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:23:12
LL | let _x: u8<'static>;
| -- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
LL | let x: u32<'static>;
| ^^^^^^^ lifetime argument not allowed
error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:24:12
help: primitive type `u8` doesn't have generic parameters
|
LL | let x: u64<'static>;
| ^^^^^^^ lifetime argument not allowed
LL - let _x: u8<'static>;
LL + let _x: u8;
|
error[E0109]: lifetime arguments are not allowed for this type
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:23:13
|
LL | let _x: u16<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `u16` doesn't have generic parameters
|
LL - let _x: u16<'static>;
LL + let _x: u16;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:24:13
|
LL | let _x: u32<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `u32` doesn't have generic parameters
|
LL - let _x: u32<'static>;
LL + let _x: u32;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:25:13
|
LL | let x: char<'static>;
| ^^^^^^^ lifetime argument not allowed
LL | let _x: u64<'static>;
| --- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `u64` doesn't have generic parameters
|
LL - let _x: u64<'static>;
LL + let _x: u64;
|
error[E0109]: lifetime arguments are not allowed on this type
--> $DIR/prim-with-args.rs:26:14
|
LL | let _x: char<'static>;
| ---- ^^^^^^^ lifetime argument not allowed
| |
| not allowed on this
|
help: primitive type `char` doesn't have generic parameters
|
LL - let _x: char<'static>;
LL + let _x: char;
|
error: aborting due to 22 previous errors

View File

@ -1,5 +1,5 @@
fn foo() {
let x: usize<foo>; //~ ERROR const arguments are not allowed for this type
let x: usize<foo>; //~ ERROR const arguments are not allowed on this type
}
fn main() {}

View File

@ -1,8 +1,16 @@
error[E0109]: const arguments are not allowed for this type
error[E0109]: const arguments are not allowed on this type
--> $DIR/usize-generic-argument-parent.rs:2:18
|
LL | let x: usize<foo>;
| ^^^ const argument not allowed
| ----- ^^^ const argument not allowed
| |
| not allowed on this
|
help: primitive type `usize` doesn't have generic parameters
|
LL - let x: usize<foo>;
LL + let x: usize;
|
error: aborting due to previous error

View File

@ -371,7 +371,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
if let Some(ref lt) = *lifetime {
if lt.name == LifetimeName::Static {
self.lts.push(RefLt::Static);
} else if let LifetimeName::Param(ParamName::Fresh(_)) = lt.name {
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
// Fresh lifetimes generated should be ignored.
} else if lt.is_elided() {
self.lts.push(RefLt::Unnamed);

View File

@ -343,7 +343,7 @@ impl fmt::Display for RefPrefix {
use fmt::Write;
f.write_char('&')?;
match self.lt {
LifetimeName::Param(ParamName::Plain(name)) => {
LifetimeName::Param(_, ParamName::Plain(name)) => {
name.fmt(f)?;
f.write_char(' ')?;
},

View File

@ -902,16 +902,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
pub fn hash_lifetime(&mut self, lifetime: Lifetime) {
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
if let LifetimeName::Param(ref name) = lifetime.name {
if let LifetimeName::Param(param_id, ref name) = lifetime.name {
std::mem::discriminant(name).hash(&mut self.s);
param_id.hash(&mut self.s);
match name {
ParamName::Plain(ref ident) => {
ident.name.hash(&mut self.s);
},
ParamName::Fresh(ref size) => {
size.hash(&mut self.s);
},
ParamName::Error => {},
ParamName::Fresh | ParamName::Error => {},
}
}
}