Auto merge of #95562 - lcnr:attr-no-encode, r=davidtwco
don't encode only locally used attrs Part of https://github.com/rust-lang/compiler-team/issues/505. We now filter builtin attributes before encoding them in the crate metadata in case they should only be used in the local crate. To prevent accidental misuse `get_attrs` now requires the caller to state which attribute they are interested in. For places where that isn't trivially possible, I've added a method `fn get_attrs_unchecked` which I intend to remove in a followup PR. After this pull request landed, we can then slowly move all attributes to only be used in the local crate while being certain that we don't accidentally try to access them from extern crates. cc https://github.com/rust-lang/rust/pull/94963#issuecomment-1082924289
This commit is contained in:
commit
481db40311
55 changed files with 455 additions and 467 deletions
|
@ -1056,9 +1056,7 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
if let Some(missing_items) = must_implement_one_of {
|
||||
let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
|
||||
let attr_span = tcx
|
||||
.get_attrs(impl_trait_ref.def_id)
|
||||
.iter()
|
||||
.find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
|
||||
.get_attr(impl_trait_ref.def_id, sym::rustc_must_implement_one_of)
|
||||
.map(|attr| attr.span);
|
||||
|
||||
missing_items_must_implement_one_of_err(tcx, impl_span, missing_items, attr_span);
|
||||
|
@ -1158,20 +1156,20 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
|||
pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
||||
let repr = def.repr();
|
||||
if repr.packed() {
|
||||
for attr in tcx.get_attrs(def.did()).iter() {
|
||||
for r in attr::find_repr_attrs(&tcx.sess, attr) {
|
||||
for attr in tcx.get_attrs(def.did(), sym::repr) {
|
||||
for r in attr::parse_repr_attr(&tcx.sess, attr) {
|
||||
if let attr::ReprPacked(pack) = r
|
||||
&& let Some(repr_pack) = repr.pack
|
||||
&& pack as u64 != repr_pack.bytes()
|
||||
{
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0634,
|
||||
"type has conflicting packed representation hints"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
&& let Some(repr_pack) = repr.pack
|
||||
&& pack as u64 != repr_pack.bytes()
|
||||
{
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0634,
|
||||
"type has conflicting packed representation hints"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
if repr.align.is_some() {
|
||||
|
@ -1321,8 +1319,7 @@ fn check_enum<'tcx>(
|
|||
def.destructor(tcx); // force the destructor to be evaluated
|
||||
|
||||
if vs.is_empty() {
|
||||
let attributes = tcx.get_attrs(def_id.to_def_id());
|
||||
if let Some(attr) = tcx.sess.find_by_name(&attributes, sym::repr) {
|
||||
if let Some(attr) = tcx.get_attr(def_id.to_def_id(), sym::repr) {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
attr.span,
|
||||
|
|
|
@ -407,8 +407,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.has_only_self_parameter(m)
|
||||
&& self
|
||||
.tcx
|
||||
.get_attrs(m.def_id)
|
||||
.iter()
|
||||
// This special internal attribute is used to permit
|
||||
// "identity-like" conversion methods to be suggested here.
|
||||
//
|
||||
|
@ -419,7 +417,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
//
|
||||
// FIXME? Other potential candidate methods: `as_ref` and
|
||||
// `as_mut`?
|
||||
.any(|a| a.has_name(sym::rustc_conversion_suggestion))
|
||||
.has_attr(m.def_id, sym::rustc_conversion_suggestion)
|
||||
});
|
||||
|
||||
methods
|
||||
|
|
|
@ -609,44 +609,43 @@ fn check_must_not_suspend_def(
|
|||
hir_id: HirId,
|
||||
data: SuspendCheckData<'_, '_>,
|
||||
) -> bool {
|
||||
for attr in tcx.get_attrs(def_id).iter() {
|
||||
if attr.has_name(sym::must_not_suspend) {
|
||||
tcx.struct_span_lint_hir(
|
||||
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
|
||||
hir_id,
|
||||
data.source_span,
|
||||
|lint| {
|
||||
let msg = format!(
|
||||
"{}`{}`{} held across a suspend point, but should not be",
|
||||
data.descr_pre,
|
||||
tcx.def_path_str(def_id),
|
||||
data.descr_post,
|
||||
);
|
||||
let mut err = lint.build(&msg);
|
||||
if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
|
||||
tcx.struct_span_lint_hir(
|
||||
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
|
||||
hir_id,
|
||||
data.source_span,
|
||||
|lint| {
|
||||
let msg = format!(
|
||||
"{}`{}`{} held across a suspend point, but should not be",
|
||||
data.descr_pre,
|
||||
tcx.def_path_str(def_id),
|
||||
data.descr_post,
|
||||
);
|
||||
let mut err = lint.build(&msg);
|
||||
|
||||
// add span pointing to the offending yield/await
|
||||
err.span_label(data.yield_span, "the value is held across this suspend point");
|
||||
// add span pointing to the offending yield/await
|
||||
err.span_label(data.yield_span, "the value is held across this suspend point");
|
||||
|
||||
// Add optional reason note
|
||||
if let Some(note) = attr.value_str() {
|
||||
// FIXME(guswynn): consider formatting this better
|
||||
err.span_note(data.source_span, note.as_str());
|
||||
}
|
||||
// Add optional reason note
|
||||
if let Some(note) = attr.value_str() {
|
||||
// FIXME(guswynn): consider formatting this better
|
||||
err.span_note(data.source_span, note.as_str());
|
||||
}
|
||||
|
||||
// Add some quick suggestions on what to do
|
||||
// FIXME: can `drop` work as a suggestion here as well?
|
||||
err.span_help(
|
||||
data.source_span,
|
||||
"consider using a block (`{ ... }`) \
|
||||
to shrink the value's scope, ending before the suspend point",
|
||||
);
|
||||
// Add some quick suggestions on what to do
|
||||
// FIXME: can `drop` work as a suggestion here as well?
|
||||
err.span_help(
|
||||
data.source_span,
|
||||
"consider using a block (`{ ... }`) \
|
||||
to shrink the value's scope, ending before the suspend point",
|
||||
);
|
||||
|
||||
err.emit();
|
||||
},
|
||||
);
|
||||
err.emit();
|
||||
},
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
@ -128,7 +128,8 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
|||
tcx.struct_span_lint_hir(lint, id, span, |lint| {
|
||||
// Removal suggestion span needs to include attributes (Issue #54400)
|
||||
let span_with_attrs = tcx
|
||||
.get_attrs(extern_crate.def_id)
|
||||
.hir()
|
||||
.attrs(id)
|
||||
.iter()
|
||||
.map(|attr| attr.span)
|
||||
.fold(span, |acc, attr_span| acc.to(attr_span));
|
||||
|
@ -166,13 +167,13 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
// If the extern crate has any attributes, they may have funky
|
||||
// semantics we can't faithfully represent using `use` (most
|
||||
// notably `#[macro_use]`). Ignore it.
|
||||
if !tcx.get_attrs(extern_crate.def_id).is_empty() {
|
||||
if !tcx.hir().attrs(id).is_empty() {
|
||||
continue;
|
||||
}
|
||||
let id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
tcx.struct_span_lint_hir(lint, id, extern_crate.span, |lint| {
|
||||
// Otherwise, we can convert it into a `use` of some kind.
|
||||
let base_replacement = match extern_crate.orig_name {
|
||||
|
|
|
@ -1200,9 +1200,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
|
|||
ty::trait_def::TraitSpecializationKind::None
|
||||
};
|
||||
let must_implement_one_of = tcx
|
||||
.get_attrs(def_id)
|
||||
.iter()
|
||||
.find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
|
||||
.get_attr(def_id, sym::rustc_must_implement_one_of)
|
||||
// Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
|
||||
// and that they are all identifiers
|
||||
.and_then(|attr| match attr.meta_item_list() {
|
||||
|
|
|
@ -298,17 +298,12 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
error = true;
|
||||
}
|
||||
|
||||
for attr in tcx.get_attrs(main_def_id) {
|
||||
if attr.has_name(sym::track_caller) {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"`main` function is not allowed to be `#[track_caller]`",
|
||||
)
|
||||
.span_label(main_span, "`main` function is not allowed to be `#[track_caller]`")
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
for attr in tcx.get_attrs(main_def_id, sym::track_caller) {
|
||||
tcx.sess
|
||||
.struct_span_err(attr.span, "`main` function is not allowed to be `#[track_caller]`")
|
||||
.span_label(main_span, "`main` function is not allowed to be `#[track_caller]`")
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
|
||||
if error {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue