Skip to content

Commit

Permalink
Collect lang items from AST
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 15, 2023
1 parent 4d1bd0d commit ad00641
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 173 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
tcx.ensure_with_value().output_filenames(());
tcx.ensure_with_value().early_lint_checks(());
tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
tcx.ensure_with_value().get_lang_items(());
let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();

let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
Expand Down
370 changes: 226 additions & 144 deletions compiler/rustc_passes/src/lang_items.rs

Large diffs are not rendered by default.

30 changes: 19 additions & 11 deletions compiler/rustc_passes/src/weak_lang_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Validity checking for weak lang items

use rustc_ast as ast;
use rustc_ast::visit;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::lang_items::{self, LangItem};
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
Expand All @@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}

/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
// These are never called by user code, they're generated by the compiler.
// They will never implicitly be added to the `missing` array unless we do
// so here.
Expand All @@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
items.missing.push(LangItem::EhCatchTypeinfo);
}

let crate_items = tcx.hir_crate_items(());
for id in crate_items.foreign_items() {
let attrs = tcx.hir().attrs(id.hir_id());
if let Some((lang_item, _)) = lang_items::extract(attrs) {
visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);

verify(tcx, items);
}

struct WeakLangItemVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
items: &'a mut lang_items::LanguageItems,
}

impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) {
if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
if let Some(item) = LangItem::from_name(lang_item)
&& item.is_weak()
{
if items.get(item).is_none() {
items.missing.push(item);
if self.items.get(item).is_none() {
self.items.missing.push(item);
}
} else {
let span = tcx.def_span(id.owner_id);
tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item });
}
}
}

verify(tcx, items);
}

fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
Expand Down
7 changes: 5 additions & 2 deletions tests/ui/duplicate_entry_error.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
error[E0152]: found duplicate lang item `panic_impl`
--> $DIR/duplicate_entry_error.rs:11:1
|
LL | fn panic_impl(info: &PanicInfo) -> ! {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / fn panic_impl(info: &PanicInfo) -> ! {
LL | |
LL | | loop {}
LL | | }
| |_^
|
= note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on)
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0152.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box`
--> $DIR/E0152.rs:5:1
|
LL | struct Foo<T>(T);
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^
|
= note: the lang item is first defined in crate `alloc` (which `std` depends on)
= note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0264.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake`
--> $DIR/E0264.rs:5:5
|
LL | fn cake();
| ^^^^^^^^^
| ^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
3 changes: 3 additions & 0 deletions tests/ui/lang-items/lang-item-generic-requirements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ trait MyIndex<'a, T> {}
#[lang = "phantom_data"]
//~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument
struct MyPhantomData<T, U>;
//~^ ERROR parameter `T` is never used
//~| ERROR parameter `U` is never used

#[lang = "owned_box"]
//~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument
Expand All @@ -40,6 +42,7 @@ fn ice() {
let r = 5;
let a = 6;
r + a;
//~^ ERROR cannot add `{integer}` to `{integer}`

// Use drop in place
my_ptr_drop();
Expand Down
37 changes: 33 additions & 4 deletions tests/ui/lang-items/lang-item-generic-requirements.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>;
| ------ this struct has 2 generic arguments

error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:26:1
--> $DIR/lang-item-generic-requirements.rs:28:1
|
LL | #[lang = "owned_box"]
| ^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -42,14 +42,43 @@ LL | struct Foo;
| - this struct has 0 generic arguments

error[E0718]: `start` language item must be applied to a function with 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:32:1
--> $DIR/lang-item-generic-requirements.rs:34:1
|
LL | #[lang = "start"]
| ^^^^^^^^^^^^^^^^^
LL |
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
| - this function has 0 generic arguments

error: aborting due to 6 previous errors
error[E0392]: parameter `T` is never used
--> $DIR/lang-item-generic-requirements.rs:24:22
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
|
= help: consider removing `T` or referring to it in a field
= help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `U` is never used
--> $DIR/lang-item-generic-requirements.rs:24:25
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
|
= help: consider removing `U` or referring to it in a field
= help: if you intended `U` to be a const parameter, use `const U: usize` instead

error[E0369]: cannot add `{integer}` to `{integer}`
--> $DIR/lang-item-generic-requirements.rs:44:7
|
LL | r + a;
| - ^ - {integer}
| |
| {integer}

error: requires `copy` lang_item

error: aborting due to 10 previous errors

For more information about this error, try `rustc --explain E0718`.
Some errors have detailed explanations: E0369, E0392, E0718.
For more information about an error, try `rustc --explain E0369`.
12 changes: 8 additions & 4 deletions tests/ui/panic-handler/panic-handler-duplicate.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
error[E0152]: found duplicate lang item `panic_impl`
--> $DIR/panic-handler-duplicate.rs:15:1
|
LL | fn panic2(info: &PanicInfo) -> ! {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / fn panic2(info: &PanicInfo) -> ! {
LL | | loop {}
LL | | }
| |_^
|
note: the lang item is first defined here
--> $DIR/panic-handler-duplicate.rs:10:1
|
LL | fn panic(info: &PanicInfo) -> ! {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / fn panic(info: &PanicInfo) -> ! {
LL | | loop {}
LL | | }
| |_^

error: aborting due to 1 previous error

Expand Down
6 changes: 4 additions & 2 deletions tests/ui/panic-handler/panic-handler-std.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0152]: found duplicate lang item `panic_impl`
--> $DIR/panic-handler-std.rs:8:1
|
LL | fn panic(info: PanicInfo) -> ! {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / fn panic(info: PanicInfo) -> ! {
LL | | loop {}
LL | | }
| |_^
|
= note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
Expand Down
1 change: 1 addition & 0 deletions tests/ui/traits/issue-102989.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized`
fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
//~^ ERROR `self` parameter is only allowed in associated functions
//~| ERROR cannot find type `Struct` in this scope
//~| ERROR mismatched types
let x = x << 1;
//~^ ERROR cannot find value `x` in this scope
}
Expand Down
22 changes: 18 additions & 4 deletions tests/ui/traits/issue-102989.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ^^^^^^ not found in this scope

error[E0425]: cannot find value `x` in this scope
--> $DIR/issue-102989.rs:10:13
--> $DIR/issue-102989.rs:11:13
|
LL | let x = x << 1;
| ^ help: a local variable with a similar name exists: `f`
Expand All @@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized`
--> $DIR/issue-102989.rs:5:1
|
LL | trait Sized { }
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
|
= note: the lang item is first defined in crate `core` (which `std` depends on)
= note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
= note: second definition in the local crate (`issue_102989`)

error: aborting due to 4 previous errors
error[E0308]: mismatched types
--> $DIR/issue-102989.rs:7:42
|
LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ---------- ^^^^ expected `&u32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
|
help: consider returning the local binding `f`
|
LL ~ let x = x << 1;
LL + f
|

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0152, E0412, E0425.
Some errors have detailed explanations: E0152, E0308, E0412, E0425.
For more information about an error, try `rustc --explain E0152`.

0 comments on commit ad00641

Please sign in to comment.