Auto merge of #139938 - matthiaskrgr:rollup-19ddpus, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #139084 (hygiene: Rename semi-transparent to semi-opaque) - #139236 (Use a session counter to make anon dep nodes unique) - #139650 (Fix `register_group_alias` for tools) - #139770 (Rename `LifetimeName` as `LifetimeKind`.) - #139846 (Remove `kw::Empty` uses in rustdoc) - #139891 (Include optional dso_local marker for functions in `enum-match.rs`) - #139908 (parser: Remove old diagnostic notes for type ascription syntax) - #139917 (fix for multiple `#[repr(align(N))]` on functions) Failed merges: - #139615 (Remove `name_or_empty`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
79a272c640
66 changed files with 265 additions and 302 deletions
|
@ -1767,21 +1767,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
) -> &'hir hir::Lifetime {
|
||||
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
|
||||
let res = match res {
|
||||
LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
|
||||
LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
let param = self.local_def_id(param);
|
||||
hir::LifetimeName::Param(param)
|
||||
hir::LifetimeKind::Param(param)
|
||||
}
|
||||
LifetimeRes::Infer => {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
hir::LifetimeName::Infer
|
||||
hir::LifetimeKind::Infer
|
||||
}
|
||||
LifetimeRes::Static { .. } => {
|
||||
debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
|
||||
hir::LifetimeName::Static
|
||||
hir::LifetimeKind::Static
|
||||
}
|
||||
LifetimeRes::Error => hir::LifetimeName::Error,
|
||||
LifetimeRes::Error => hir::LifetimeKind::Error,
|
||||
LifetimeRes::ElidedAnchor { .. } => {
|
||||
panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
|
||||
}
|
||||
|
@ -2388,7 +2388,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let r = hir::Lifetime::new(
|
||||
self.next_id(),
|
||||
Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault,
|
||||
hir::LifetimeKind::ImplicitObjectLifetimeDefault,
|
||||
IsAnonInPath::No,
|
||||
);
|
||||
debug!("elided_dyn_bound: r={:?}", r);
|
||||
|
|
|
@ -20,7 +20,7 @@ impl SingleAttributeParser for TransparencyParser {
|
|||
fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
match args.name_value().and_then(|nv| nv.value_as_str()) {
|
||||
Some(sym::transparent) => Some(Transparency::Transparent),
|
||||
Some(sym::semitransparent) => Some(Transparency::SemiTransparent),
|
||||
Some(sym::semiopaque | sym::semitransparent) => Some(Transparency::SemiOpaque),
|
||||
Some(sym::opaque) => Some(Transparency::Opaque),
|
||||
Some(other) => {
|
||||
cx.dcx().span_err(cx.attr_span, format!("unknown macro transparency: `{other}`"));
|
||||
|
|
|
@ -888,7 +888,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
// Skip `async` desugaring `impl Future`.
|
||||
}
|
||||
if let TyKind::TraitObject(_, lt) = alias_ty.kind {
|
||||
if lt.res == hir::LifetimeName::ImplicitObjectLifetimeDefault {
|
||||
if lt.kind == hir::LifetimeKind::ImplicitObjectLifetimeDefault {
|
||||
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
|
||||
} else {
|
||||
spans_suggs.push((lt.ident.span, "'a".to_string()));
|
||||
|
|
|
@ -114,7 +114,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
AttributeKind::Repr(reprs) => {
|
||||
codegen_fn_attrs.alignment = reprs
|
||||
.iter()
|
||||
.find_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None });
|
||||
.filter_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None })
|
||||
.max();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -767,7 +767,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
rustc_attr!(
|
||||
rustc_macro_transparency, Normal,
|
||||
template!(NameValueStr: "transparent|semitransparent|opaque"), ErrorFollowing,
|
||||
template!(NameValueStr: "transparent|semiopaque|opaque"), ErrorFollowing,
|
||||
EncodeCrossCrate::Yes, "used internally for testing macro hygiene",
|
||||
),
|
||||
rustc_attr!(
|
||||
|
|
|
@ -42,7 +42,7 @@ pub enum IsAnonInPath {
|
|||
}
|
||||
|
||||
/// A lifetime. The valid field combinations are non-obvious. The following
|
||||
/// example shows some of them. See also the comments on `LifetimeName`.
|
||||
/// example shows some of them. See also the comments on `LifetimeKind`.
|
||||
/// ```
|
||||
/// #[repr(C)]
|
||||
/// struct S<'a>(&'a u32); // res=Param, name='a, IsAnonInPath::No
|
||||
|
@ -84,7 +84,7 @@ pub struct Lifetime {
|
|||
pub ident: Ident,
|
||||
|
||||
/// Semantics of this lifetime.
|
||||
pub res: LifetimeName,
|
||||
pub kind: LifetimeKind,
|
||||
|
||||
/// Is the lifetime anonymous and in a path? Used only for error
|
||||
/// suggestions. See `Lifetime::suggestion` for example use.
|
||||
|
@ -130,7 +130,7 @@ impl ParamName {
|
|||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
|
||||
pub enum LifetimeName {
|
||||
pub enum LifetimeKind {
|
||||
/// User-given names or fresh (synthetic) names.
|
||||
Param(LocalDefId),
|
||||
|
||||
|
@ -160,16 +160,16 @@ pub enum LifetimeName {
|
|||
Static,
|
||||
}
|
||||
|
||||
impl LifetimeName {
|
||||
impl LifetimeKind {
|
||||
fn is_elided(&self) -> bool {
|
||||
match self {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
|
||||
LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer => true,
|
||||
|
||||
// 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 equivalently to "some fresh name".
|
||||
// They correspond to early-bound regions on an impl, in other words.
|
||||
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
|
||||
LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,10 +184,10 @@ impl Lifetime {
|
|||
pub fn new(
|
||||
hir_id: HirId,
|
||||
ident: Ident,
|
||||
res: LifetimeName,
|
||||
kind: LifetimeKind,
|
||||
is_anon_in_path: IsAnonInPath,
|
||||
) -> Lifetime {
|
||||
let lifetime = Lifetime { hir_id, ident, res, is_anon_in_path };
|
||||
let lifetime = Lifetime { hir_id, ident, kind, is_anon_in_path };
|
||||
|
||||
// Sanity check: elided lifetimes form a strict subset of anonymous lifetimes.
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -202,7 +202,7 @@ impl Lifetime {
|
|||
}
|
||||
|
||||
pub fn is_elided(&self) -> bool {
|
||||
self.res.is_elided()
|
||||
self.kind.is_elided()
|
||||
}
|
||||
|
||||
pub fn is_anonymous(&self) -> bool {
|
||||
|
@ -1014,7 +1014,7 @@ pub struct WhereRegionPredicate<'hir> {
|
|||
impl<'hir> WhereRegionPredicate<'hir> {
|
||||
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
|
||||
fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
|
||||
self.lifetime.res == LifetimeName::Param(param_def_id)
|
||||
self.lifetime.kind == LifetimeKind::Param(param_def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
|
|||
Lifetime {
|
||||
hir_id: HirId::INVALID,
|
||||
ident: Ident::new(sym::name, DUMMY_SP),
|
||||
res: LifetimeName::Static,
|
||||
kind: LifetimeKind::Static,
|
||||
is_anon_in_path: IsAnonInPath::No,
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@ use rustc_errors::ErrorGuaranteed;
|
|||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
|
||||
use rustc_hir::{
|
||||
self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node,
|
||||
self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
|
||||
};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -646,14 +646,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
arg: &'tcx hir::PreciseCapturingArg<'tcx>,
|
||||
) -> Self::Result {
|
||||
match *arg {
|
||||
hir::PreciseCapturingArg::Lifetime(lt) => match lt.res {
|
||||
LifetimeName::Param(def_id) => {
|
||||
hir::PreciseCapturingArg::Lifetime(lt) => match lt.kind {
|
||||
LifetimeKind::Param(def_id) => {
|
||||
self.resolve_lifetime_ref(def_id, lt);
|
||||
}
|
||||
LifetimeName::Error => {}
|
||||
LifetimeName::ImplicitObjectLifetimeDefault
|
||||
| LifetimeName::Infer
|
||||
| LifetimeName::Static => {
|
||||
LifetimeKind::Error => {}
|
||||
LifetimeKind::ImplicitObjectLifetimeDefault
|
||||
| LifetimeKind::Infer
|
||||
| LifetimeKind::Static => {
|
||||
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
|
||||
span: lt.ident.span,
|
||||
kind: "lifetime",
|
||||
|
@ -774,26 +774,26 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
});
|
||||
match lifetime.res {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
match lifetime.kind {
|
||||
LifetimeKind::ImplicitObjectLifetimeDefault => {
|
||||
// If the user does not write *anything*, we
|
||||
// use the object lifetime defaulting
|
||||
// rules. So e.g., `Box<dyn Debug>` becomes
|
||||
// `Box<dyn Debug + 'static>`.
|
||||
self.resolve_object_lifetime_default(&*lifetime)
|
||||
}
|
||||
LifetimeName::Infer => {
|
||||
LifetimeKind::Infer => {
|
||||
// If the user writes `'_`, we use the *ordinary* elision
|
||||
// rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
|
||||
// resolved the same as the `'_` in `&'_ Foo`.
|
||||
//
|
||||
// cc #48468
|
||||
}
|
||||
LifetimeName::Param(..) | LifetimeName::Static => {
|
||||
LifetimeKind::Param(..) | LifetimeKind::Static => {
|
||||
// If the user wrote an explicit name, use that.
|
||||
self.visit_lifetime(&*lifetime);
|
||||
}
|
||||
LifetimeName::Error => {}
|
||||
LifetimeKind::Error => {}
|
||||
}
|
||||
}
|
||||
hir::TyKind::Ref(lifetime_ref, ref mt) => {
|
||||
|
@ -873,17 +873,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
match lifetime_ref.res {
|
||||
hir::LifetimeName::Static => {
|
||||
match lifetime_ref.kind {
|
||||
hir::LifetimeKind::Static => {
|
||||
self.insert_lifetime(lifetime_ref, ResolvedArg::StaticLifetime)
|
||||
}
|
||||
hir::LifetimeName::Param(param_def_id) => {
|
||||
hir::LifetimeKind::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 => {}
|
||||
hir::LifetimeKind::Error => {}
|
||||
// Those will be resolved by typechecking.
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => {}
|
||||
hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Infer => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1063,15 +1063,15 @@ fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectL
|
|||
|
||||
for bound in bound.bounds {
|
||||
if let hir::GenericBound::Outlives(lifetime) = bound {
|
||||
set.insert(lifetime.res);
|
||||
set.insert(lifetime.kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match set {
|
||||
Set1::Empty => ObjectLifetimeDefault::Empty,
|
||||
Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
|
||||
Set1::One(hir::LifetimeName::Param(param_def_id)) => {
|
||||
Set1::One(hir::LifetimeKind::Static) => ObjectLifetimeDefault::Static,
|
||||
Set1::One(hir::LifetimeKind::Param(param_def_id)) => {
|
||||
ObjectLifetimeDefault::Param(param_def_id.to_def_id())
|
||||
}
|
||||
_ => ObjectLifetimeDefault::Ambiguous,
|
||||
|
@ -1241,7 +1241,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
|
||||
// regular fns.
|
||||
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
|
||||
&& let hir::LifetimeName::Param(param_id) = lifetime_ref.res
|
||||
&& let hir::LifetimeKind::Param(param_id) = lifetime_ref.kind
|
||||
&& let Some(generics) =
|
||||
self.tcx.hir_get_generics(self.tcx.local_parent(param_id))
|
||||
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
|
||||
|
@ -2440,7 +2440,7 @@ fn is_late_bound_map(
|
|||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
|
||||
if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
|
||||
if let hir::LifetimeKind::Param(def_id) = lifetime_ref.kind {
|
||||
self.regions.insert(def_id);
|
||||
}
|
||||
}
|
||||
|
@ -2453,7 +2453,7 @@ fn is_late_bound_map(
|
|||
|
||||
impl<'tcx> Visitor<'tcx> for AllCollector {
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
|
||||
if let hir::LifetimeKind::Param(def_id) = lifetime_ref.kind {
|
||||
self.regions.insert(def_id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -415,7 +415,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
|
||||
} else {
|
||||
let reason =
|
||||
if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
|
||||
if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind {
|
||||
if let hir::Node::Ty(hir::Ty {
|
||||
kind: hir::TyKind::Ref(parent_lifetime, _),
|
||||
..
|
||||
|
|
|
@ -83,11 +83,6 @@ enum TargetLint {
|
|||
Ignored,
|
||||
}
|
||||
|
||||
pub enum FindLintError {
|
||||
NotFound,
|
||||
Removed,
|
||||
}
|
||||
|
||||
struct LintAlias {
|
||||
name: &'static str,
|
||||
/// Whether deprecation warnings should be suppressed for this alias.
|
||||
|
@ -231,13 +226,24 @@ impl LintStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn register_group_alias(&mut self, lint_name: &'static str, alias: &'static str) {
|
||||
self.lint_groups.insert(
|
||||
fn insert_group(&mut self, name: &'static str, group: LintGroup) {
|
||||
let previous = self.lint_groups.insert(name, group);
|
||||
if previous.is_some() {
|
||||
bug!("group {name:?} already exists");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_group_alias(&mut self, group_name: &'static str, alias: &'static str) {
|
||||
let Some(LintGroup { lint_ids, .. }) = self.lint_groups.get(group_name) else {
|
||||
bug!("group alias {alias:?} points to unregistered group {group_name:?}")
|
||||
};
|
||||
|
||||
self.insert_group(
|
||||
alias,
|
||||
LintGroup {
|
||||
lint_ids: vec![],
|
||||
lint_ids: lint_ids.clone(),
|
||||
is_externally_loaded: false,
|
||||
depr: Some(LintAlias { name: lint_name, silent: true }),
|
||||
depr: Some(LintAlias { name: group_name, silent: true }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -249,24 +255,17 @@ impl LintStore {
|
|||
deprecated_name: Option<&'static str>,
|
||||
to: Vec<LintId>,
|
||||
) {
|
||||
let new = self
|
||||
.lint_groups
|
||||
.insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None })
|
||||
.is_none();
|
||||
if let Some(deprecated) = deprecated_name {
|
||||
self.lint_groups.insert(
|
||||
self.insert_group(
|
||||
deprecated,
|
||||
LintGroup {
|
||||
lint_ids: vec![],
|
||||
lint_ids: to.clone(),
|
||||
is_externally_loaded,
|
||||
depr: Some(LintAlias { name, silent: false }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if !new {
|
||||
bug!("duplicate specification of lint group {}", name);
|
||||
}
|
||||
self.insert_group(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None });
|
||||
}
|
||||
|
||||
/// This lint should give no warning and have no effect.
|
||||
|
@ -292,23 +291,15 @@ impl LintStore {
|
|||
self.by_name.insert(name.into(), Removed(reason.into()));
|
||||
}
|
||||
|
||||
pub fn find_lints(&self, mut lint_name: &str) -> Result<Vec<LintId>, FindLintError> {
|
||||
pub fn find_lints(&self, lint_name: &str) -> Option<&[LintId]> {
|
||||
match self.by_name.get(lint_name) {
|
||||
Some(&Id(lint_id)) => Ok(vec![lint_id]),
|
||||
Some(&Renamed(_, lint_id)) => Ok(vec![lint_id]),
|
||||
Some(&Removed(_)) => Err(FindLintError::Removed),
|
||||
Some(&Ignored) => Ok(vec![]),
|
||||
None => loop {
|
||||
return match self.lint_groups.get(lint_name) {
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
if let Some(LintAlias { name, .. }) = depr {
|
||||
lint_name = name;
|
||||
continue;
|
||||
}
|
||||
Ok(lint_ids.clone())
|
||||
}
|
||||
None => Err(FindLintError::Removed),
|
||||
};
|
||||
Some(Id(lint_id)) => Some(slice::from_ref(lint_id)),
|
||||
Some(Renamed(_, lint_id)) => Some(slice::from_ref(lint_id)),
|
||||
Some(Removed(_)) => None,
|
||||
Some(Ignored) => Some(&[]),
|
||||
None => match self.lint_groups.get(lint_name) {
|
||||
Some(LintGroup { lint_ids, .. }) => Some(lint_ids),
|
||||
None => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -374,8 +365,12 @@ impl LintStore {
|
|||
CheckLintNameResult::MissingTool
|
||||
};
|
||||
}
|
||||
Some(LintGroup { lint_ids, .. }) => {
|
||||
return CheckLintNameResult::Tool(lint_ids, None);
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
return if let &Some(LintAlias { name, silent: false }) = depr {
|
||||
CheckLintNameResult::Tool(lint_ids, Some(name.to_string()))
|
||||
} else {
|
||||
CheckLintNameResult::Tool(lint_ids, None)
|
||||
};
|
||||
}
|
||||
},
|
||||
Some(Id(id)) => return CheckLintNameResult::Tool(slice::from_ref(id), None),
|
||||
|
@ -393,15 +388,11 @@ impl LintStore {
|
|||
None => self.check_tool_name_for_backwards_compat(&complete_name, "clippy"),
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
// Check if the lint group name is deprecated
|
||||
if let Some(LintAlias { name, silent }) = depr {
|
||||
let LintGroup { lint_ids, .. } = self.lint_groups.get(name).unwrap();
|
||||
return if *silent {
|
||||
CheckLintNameResult::Ok(lint_ids)
|
||||
} else {
|
||||
CheckLintNameResult::Tool(lint_ids, Some((*name).to_string()))
|
||||
};
|
||||
if let &Some(LintAlias { name, silent: false }) = depr {
|
||||
CheckLintNameResult::Tool(lint_ids, Some(name.to_string()))
|
||||
} else {
|
||||
CheckLintNameResult::Ok(lint_ids)
|
||||
}
|
||||
CheckLintNameResult::Ok(lint_ids)
|
||||
}
|
||||
},
|
||||
Some(Id(id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
|
||||
|
@ -412,7 +403,7 @@ impl LintStore {
|
|||
fn no_lint_suggestion(&self, lint_name: &str, tool_name: &str) -> CheckLintNameResult<'_> {
|
||||
let name_lower = lint_name.to_lowercase();
|
||||
|
||||
if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() {
|
||||
if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_some() {
|
||||
// First check if the lint name is (partly) in upper case instead of lower case...
|
||||
return CheckLintNameResult::NoLint(Some((Symbol::intern(&name_lower), false)));
|
||||
}
|
||||
|
@ -455,18 +446,8 @@ impl LintStore {
|
|||
None => match self.lint_groups.get(&*complete_name) {
|
||||
// Now we are sure, that this lint exists nowhere
|
||||
None => self.no_lint_suggestion(lint_name, tool_name),
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
// Reaching this would be weird, but let's cover this case anyway
|
||||
if let Some(LintAlias { name, silent }) = depr {
|
||||
let LintGroup { lint_ids, .. } = self.lint_groups.get(name).unwrap();
|
||||
if *silent {
|
||||
CheckLintNameResult::Tool(lint_ids, Some(complete_name))
|
||||
} else {
|
||||
CheckLintNameResult::Tool(lint_ids, Some((*name).to_string()))
|
||||
}
|
||||
} else {
|
||||
CheckLintNameResult::Tool(lint_ids, Some(complete_name))
|
||||
}
|
||||
Some(LintGroup { lint_ids, .. }) => {
|
||||
CheckLintNameResult::Tool(lint_ids, Some(complete_name))
|
||||
}
|
||||
},
|
||||
Some(Id(id)) => CheckLintNameResult::Tool(slice::from_ref(id), Some(complete_name)),
|
||||
|
|
|
@ -517,11 +517,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
|
||||
let lint_flag_val = Symbol::intern(lint_name);
|
||||
|
||||
let Ok(ids) = self.store.find_lints(lint_name) else {
|
||||
let Some(ids) = self.store.find_lints(lint_name) else {
|
||||
// errors already handled above
|
||||
continue;
|
||||
};
|
||||
for id in ids {
|
||||
for &id in ids {
|
||||
// ForceWarn and Forbid cannot be overridden
|
||||
if let Some(LevelAndSource { level: Level::ForceWarn | Level::Forbid, .. }) =
|
||||
self.current_specs().get(&id)
|
||||
|
|
|
@ -124,9 +124,7 @@ use unused::*;
|
|||
|
||||
#[rustfmt::skip]
|
||||
pub use builtin::{MissingDoc, SoftLints};
|
||||
pub use context::{
|
||||
CheckLintNameResult, EarlyContext, FindLintError, LateContext, LintContext, LintStore,
|
||||
};
|
||||
pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore};
|
||||
pub use early::{EarlyCheckNode, check_ast_node};
|
||||
pub use late::{check_crate, late_lint_mod, unerased_lint_store};
|
||||
pub use levels::LintLevelsBuilder;
|
||||
|
|
|
@ -578,8 +578,8 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
|||
match ty.kind {
|
||||
hir::TyKind::TraitObject(_, tagged_ptr)
|
||||
if let hir::Lifetime {
|
||||
res:
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
|
||||
kind:
|
||||
hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Static,
|
||||
..
|
||||
} = tagged_ptr.pointer() =>
|
||||
{
|
||||
|
|
|
@ -806,9 +806,6 @@ parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
|
|||
parse_transpose_dyn_or_impl = `for<...>` expected after `{$kw}`, not before
|
||||
.suggestion = move `{$kw}` before the `for<...>`
|
||||
|
||||
parse_type_ascription_removed =
|
||||
if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
|
||||
parse_unclosed_unicode_escape = unterminated unicode escape
|
||||
.label = missing a closing `{"}"}`
|
||||
.terminate = terminate the unicode escape
|
||||
|
|
|
@ -1598,9 +1598,6 @@ pub(crate) struct PathSingleColon {
|
|||
|
||||
#[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")]
|
||||
pub suggestion: Span,
|
||||
|
||||
#[note(parse_type_ascription_removed)]
|
||||
pub type_ascription: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -1617,9 +1614,6 @@ pub(crate) struct ColonAsSemi {
|
|||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = ";", style = "verbose")]
|
||||
pub span: Span,
|
||||
|
||||
#[note(parse_type_ascription_removed)]
|
||||
pub type_ascription: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -1943,10 +1943,7 @@ impl<'a> Parser<'a> {
|
|||
&& self.token == token::Colon
|
||||
&& self.look_ahead(1, |next| line_idx(self.token.span) < line_idx(next.span))
|
||||
{
|
||||
self.dcx().emit_err(ColonAsSemi {
|
||||
span: self.token.span,
|
||||
type_ascription: self.psess.unstable_features.is_nightly_build(),
|
||||
});
|
||||
self.dcx().emit_err(ColonAsSemi { span: self.token.span });
|
||||
self.bump();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -273,7 +273,6 @@ impl<'a> Parser<'a> {
|
|||
self.dcx().emit_err(PathSingleColon {
|
||||
span: self.prev_token.span,
|
||||
suggestion: self.prev_token.span.shrink_to_hi(),
|
||||
type_ascription: self.psess.unstable_features.is_nightly_build(),
|
||||
});
|
||||
}
|
||||
continue;
|
||||
|
@ -348,7 +347,6 @@ impl<'a> Parser<'a> {
|
|||
err = self.dcx().create_err(PathSingleColon {
|
||||
span: self.token.span,
|
||||
suggestion: self.prev_token.span.shrink_to_hi(),
|
||||
type_ascription: self.psess.unstable_features.is_nightly_build(),
|
||||
});
|
||||
}
|
||||
// Attempt to find places where a missing `>` might belong.
|
||||
|
|
|
@ -771,10 +771,6 @@ impl<'a> Parser<'a> {
|
|||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
if self.psess.unstable_features.is_nightly_build() {
|
||||
// FIXME(Nilstrieb): Remove this again after a few months.
|
||||
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1174,8 +1174,7 @@ pub(super) struct CurrentDepGraph<D: Deps> {
|
|||
/// ID from the previous session. In order to side-step this problem, we make
|
||||
/// sure that anonymous `NodeId`s allocated in different sessions don't overlap.
|
||||
/// This is implemented by mixing a session-key into the ID fingerprint of
|
||||
/// each anon node. The session-key is just a random number generated when
|
||||
/// the `DepGraph` is created.
|
||||
/// each anon node. The session-key is a hash of the number of previous sessions.
|
||||
anon_id_seed: Fingerprint,
|
||||
|
||||
/// These are simple counters that are for profiling and
|
||||
|
@ -1193,12 +1192,8 @@ impl<D: Deps> CurrentDepGraph<D> {
|
|||
record_stats: bool,
|
||||
previous: Arc<SerializedDepGraph>,
|
||||
) -> Self {
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let nanos = duration.as_nanos();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
nanos.hash(&mut stable_hasher);
|
||||
previous.session_count().hash(&mut stable_hasher);
|
||||
let anon_id_seed = stable_hasher.finish();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
|
@ -92,6 +92,9 @@ pub struct SerializedDepGraph {
|
|||
/// Stores a map from fingerprints to nodes per dep node kind.
|
||||
/// This is the reciprocal of `nodes`.
|
||||
index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
|
||||
/// The number of previous compilation sessions. This is used to generate
|
||||
/// unique anon dep nodes per session.
|
||||
session_count: u64,
|
||||
}
|
||||
|
||||
impl SerializedDepGraph {
|
||||
|
@ -146,6 +149,11 @@ impl SerializedDepGraph {
|
|||
pub fn node_count(&self) -> usize {
|
||||
self.nodes.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn session_count(&self) -> u64 {
|
||||
self.session_count
|
||||
}
|
||||
}
|
||||
|
||||
/// A packed representation of an edge's start index and byte width.
|
||||
|
@ -252,6 +260,8 @@ impl SerializedDepGraph {
|
|||
.map(|_| UnhashMap::with_capacity_and_hasher(d.read_u32() as usize, Default::default()))
|
||||
.collect();
|
||||
|
||||
let session_count = d.read_u64();
|
||||
|
||||
for (idx, node) in nodes.iter_enumerated() {
|
||||
if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
|
||||
// Side effect nodes can have duplicates
|
||||
|
@ -273,6 +283,7 @@ impl SerializedDepGraph {
|
|||
edge_list_indices,
|
||||
edge_list_data,
|
||||
index,
|
||||
session_count,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -603,7 +614,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
stats: _,
|
||||
kind_stats,
|
||||
marker: _,
|
||||
previous: _,
|
||||
previous,
|
||||
} = self;
|
||||
|
||||
let node_count = total_node_count.try_into().unwrap();
|
||||
|
@ -614,6 +625,8 @@ impl<D: Deps> EncoderState<D> {
|
|||
count.encode(&mut encoder);
|
||||
}
|
||||
|
||||
previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
|
||||
|
||||
debug!(?node_count, ?edge_count);
|
||||
debug!("position: {:?}", encoder.position());
|
||||
IntEncodedWithFixedSize(node_count).encode(&mut encoder);
|
||||
|
|
|
@ -2007,16 +2007,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
result,
|
||||
result.map(|r| r.expn_data())
|
||||
);
|
||||
// Then find the last semi-transparent mark from the end if it exists.
|
||||
// Then find the last semi-opaque mark from the end if it exists.
|
||||
for (mark, transparency) in iter {
|
||||
if transparency == Transparency::SemiTransparent {
|
||||
if transparency == Transparency::SemiOpaque {
|
||||
result = Some(mark);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug!(
|
||||
"resolve_crate_root: found semi-transparent mark {:?} {:?}",
|
||||
"resolve_crate_root: found semi-opaque mark {:?} {:?}",
|
||||
result,
|
||||
result.map(|r| r.expn_data())
|
||||
);
|
||||
|
|
|
@ -63,10 +63,10 @@ struct SyntaxContextData {
|
|||
outer_expn: ExpnId,
|
||||
outer_transparency: Transparency,
|
||||
parent: SyntaxContext,
|
||||
/// This context, but with all transparent and semi-transparent expansions filtered away.
|
||||
/// This context, but with all transparent and semi-opaque expansions filtered away.
|
||||
opaque: SyntaxContext,
|
||||
/// This context, but with all transparent expansions filtered away.
|
||||
opaque_and_semitransparent: SyntaxContext,
|
||||
opaque_and_semiopaque: SyntaxContext,
|
||||
/// Name of the crate to which `$crate` with this context would resolve.
|
||||
dollar_crate_name: Symbol,
|
||||
}
|
||||
|
@ -75,14 +75,14 @@ impl SyntaxContextData {
|
|||
fn new(
|
||||
(parent, outer_expn, outer_transparency): SyntaxContextKey,
|
||||
opaque: SyntaxContext,
|
||||
opaque_and_semitransparent: SyntaxContext,
|
||||
opaque_and_semiopaque: SyntaxContext,
|
||||
) -> SyntaxContextData {
|
||||
SyntaxContextData {
|
||||
outer_expn,
|
||||
outer_transparency,
|
||||
parent,
|
||||
opaque,
|
||||
opaque_and_semitransparent,
|
||||
opaque_and_semiopaque,
|
||||
dollar_crate_name: kw::DollarCrate,
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ impl SyntaxContextData {
|
|||
outer_transparency: Transparency::Opaque,
|
||||
parent: SyntaxContext::root(),
|
||||
opaque: SyntaxContext::root(),
|
||||
opaque_and_semitransparent: SyntaxContext::root(),
|
||||
opaque_and_semiopaque: SyntaxContext::root(),
|
||||
dollar_crate_name: kw::DollarCrate,
|
||||
}
|
||||
}
|
||||
|
@ -204,13 +204,13 @@ pub enum Transparency {
|
|||
/// Identifier produced by a transparent expansion is always resolved at call-site.
|
||||
/// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
|
||||
Transparent,
|
||||
/// Identifier produced by a semi-transparent expansion may be resolved
|
||||
/// Identifier produced by a semi-opaque expansion may be resolved
|
||||
/// either at call-site or at definition-site.
|
||||
/// If it's a local variable, label or `$crate` then it's resolved at def-site.
|
||||
/// Otherwise it's resolved at call-site.
|
||||
/// `macro_rules` macros behave like this, built-in macros currently behave like this too,
|
||||
/// but that's an implementation detail.
|
||||
SemiTransparent,
|
||||
SemiOpaque,
|
||||
/// Identifier produced by an opaque expansion is always resolved at definition-site.
|
||||
/// Def-site spans in procedural macros, identifiers from `macro` by default use this.
|
||||
Opaque,
|
||||
|
@ -218,7 +218,7 @@ pub enum Transparency {
|
|||
|
||||
impl Transparency {
|
||||
pub fn fallback(macro_rules: bool) -> Self {
|
||||
if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque }
|
||||
if macro_rules { Transparency::SemiOpaque } else { Transparency::Opaque }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,7 +466,7 @@ impl HygieneData {
|
|||
|
||||
fn normalize_to_macro_rules(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
debug_assert!(!self.syntax_context_data[ctxt.0 as usize].is_decode_placeholder());
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque_and_semitransparent
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque
|
||||
}
|
||||
|
||||
fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId {
|
||||
|
@ -559,7 +559,7 @@ impl HygieneData {
|
|||
}
|
||||
|
||||
let call_site_ctxt = self.expn_data(expn_id).call_site.ctxt();
|
||||
let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
|
||||
let mut call_site_ctxt = if transparency == Transparency::SemiOpaque {
|
||||
self.normalize_to_macros_2_0(call_site_ctxt)
|
||||
} else {
|
||||
self.normalize_to_macro_rules(call_site_ctxt)
|
||||
|
@ -605,33 +605,32 @@ impl HygieneData {
|
|||
self.syntax_context_data.push(SyntaxContextData::decode_placeholder());
|
||||
self.syntax_context_map.insert(key, ctxt);
|
||||
|
||||
// Opaque and semi-transparent versions of the parent. Note that they may be equal to the
|
||||
// Opaque and semi-opaque versions of the parent. Note that they may be equal to the
|
||||
// parent itself. E.g. `parent_opaque` == `parent` if the expn chain contains only opaques,
|
||||
// and `parent_opaque_and_semitransparent` == `parent` if the expn contains only opaques
|
||||
// and semi-transparents.
|
||||
// and `parent_opaque_and_semiopaque` == `parent` if the expn contains only (semi-)opaques.
|
||||
let parent_opaque = self.syntax_context_data[parent.0 as usize].opaque;
|
||||
let parent_opaque_and_semitransparent =
|
||||
self.syntax_context_data[parent.0 as usize].opaque_and_semitransparent;
|
||||
let parent_opaque_and_semiopaque =
|
||||
self.syntax_context_data[parent.0 as usize].opaque_and_semiopaque;
|
||||
|
||||
// Evaluate opaque and semi-transparent versions of the new syntax context.
|
||||
let (opaque, opaque_and_semitransparent) = match transparency {
|
||||
Transparency::Transparent => (parent_opaque, parent_opaque_and_semitransparent),
|
||||
Transparency::SemiTransparent => (
|
||||
// Evaluate opaque and semi-opaque versions of the new syntax context.
|
||||
let (opaque, opaque_and_semiopaque) = match transparency {
|
||||
Transparency::Transparent => (parent_opaque, parent_opaque_and_semiopaque),
|
||||
Transparency::SemiOpaque => (
|
||||
parent_opaque,
|
||||
// Will be the same as `ctxt` if the expn chain contains only opaques and semi-transparents.
|
||||
self.alloc_ctxt(parent_opaque_and_semitransparent, expn_id, transparency),
|
||||
// Will be the same as `ctxt` if the expn chain contains only (semi-)opaques.
|
||||
self.alloc_ctxt(parent_opaque_and_semiopaque, expn_id, transparency),
|
||||
),
|
||||
Transparency::Opaque => (
|
||||
// Will be the same as `ctxt` if the expn chain contains only opaques.
|
||||
self.alloc_ctxt(parent_opaque, expn_id, transparency),
|
||||
// Will be the same as `ctxt` if the expn chain contains only opaques and semi-transparents.
|
||||
self.alloc_ctxt(parent_opaque_and_semitransparent, expn_id, transparency),
|
||||
// Will be the same as `ctxt` if the expn chain contains only (semi-)opaques.
|
||||
self.alloc_ctxt(parent_opaque_and_semiopaque, expn_id, transparency),
|
||||
),
|
||||
};
|
||||
|
||||
// Fill the full data, now that we have it.
|
||||
self.syntax_context_data[ctxt.as_u32() as usize] =
|
||||
SyntaxContextData::new(key, opaque, opaque_and_semitransparent);
|
||||
SyntaxContextData::new(key, opaque, opaque_and_semiopaque);
|
||||
ctxt
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1117,7 +1117,7 @@ impl Span {
|
|||
/// Equivalent of `Span::mixed_site` from the proc macro API,
|
||||
/// except that the location is taken from the `self` span.
|
||||
pub fn with_mixed_site_ctxt(self, expn_id: ExpnId) -> Span {
|
||||
self.with_ctxt_from_mark(expn_id, Transparency::SemiTransparent)
|
||||
self.with_ctxt_from_mark(expn_id, Transparency::SemiOpaque)
|
||||
}
|
||||
|
||||
/// Produces a span with the same location as `self` and context produced by a macro with the
|
||||
|
|
|
@ -1882,6 +1882,7 @@ symbols! {
|
|||
select_unpredictable,
|
||||
self_in_typedefs,
|
||||
self_struct_ctor,
|
||||
semiopaque,
|
||||
semitransparent,
|
||||
sha2,
|
||||
sha3,
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
|
||||
use rustc_hir::{
|
||||
self as hir, AmbigArg, GenericBound, GenericParam, GenericParamKind, Item, ItemKind, Lifetime,
|
||||
LifetimeName, LifetimeParamKind, MissingLifetimeKind, Node, TyKind,
|
||||
LifetimeKind, LifetimeParamKind, MissingLifetimeKind, Node, TyKind,
|
||||
};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
@ -165,7 +165,7 @@ pub fn suggest_new_region_bound(
|
|||
|
||||
if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime {
|
||||
res: LifetimeName::Static, ident, ..
|
||||
kind: LifetimeKind::Static, ident, ..
|
||||
}) => Some(ident.span),
|
||||
_ => None,
|
||||
}) {
|
||||
|
@ -253,7 +253,7 @@ pub fn suggest_new_region_bound(
|
|||
}
|
||||
}
|
||||
TyKind::TraitObject(_, lt) => {
|
||||
if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res {
|
||||
if let LifetimeKind::ImplicitObjectLifetimeDefault = lt.kind {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
format!("{declare} the trait object {captures}, {explicit}",),
|
||||
|
@ -414,7 +414,7 @@ pub struct HirTraitObjectVisitor<'a>(pub &'a mut Vec<Span>, pub DefId);
|
|||
impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) {
|
||||
if let TyKind::TraitObject(poly_trait_refs, lifetime_ptr) = t.kind
|
||||
&& let Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. } =
|
||||
&& let Lifetime { kind: LifetimeKind::ImplicitObjectLifetimeDefault, .. } =
|
||||
lifetime_ptr.pointer()
|
||||
{
|
||||
for ptr in poly_trait_refs {
|
||||
|
|
|
@ -850,14 +850,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
add_lt_suggs: &mut Vec<(Span, String)>,
|
||||
) -> String {
|
||||
struct LifetimeReplaceVisitor<'a> {
|
||||
needle: hir::LifetimeName,
|
||||
needle: hir::LifetimeKind,
|
||||
new_lt: &'a str,
|
||||
add_lt_suggs: &'a mut Vec<(Span, String)>,
|
||||
}
|
||||
|
||||
impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> {
|
||||
fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
|
||||
if lt.res == self.needle {
|
||||
if lt.kind == self.needle {
|
||||
self.add_lt_suggs.push(lt.suggestion(self.new_lt));
|
||||
}
|
||||
}
|
||||
|
@ -894,7 +894,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let mut visitor = LifetimeReplaceVisitor {
|
||||
needle: hir::LifetimeName::Param(lifetime_def_id),
|
||||
needle: hir::LifetimeKind::Param(lifetime_def_id),
|
||||
add_lt_suggs,
|
||||
new_lt: &new_lt,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue