Skip to content

Commit 74cd754

Browse files
Collect lang items from AST
1 parent df0295f commit 74cd754

12 files changed

+322
-168
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
418418
tcx.ensure_with_value().output_filenames(());
419419
tcx.ensure_with_value().early_lint_checks(());
420420
tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
421+
tcx.ensure_with_value().get_lang_items(());
421422
let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
422423

423424
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);

compiler/rustc_passes/src/lang_items.rs

+228-139
Large diffs are not rendered by default.

compiler/rustc_passes/src/weak_lang_items.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Validity checking for weak lang items
22
3+
use rustc_ast as ast;
4+
use rustc_ast::visit;
35
use rustc_data_structures::fx::FxHashSet;
46
use rustc_hir::lang_items::{self, LangItem};
57
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
1113

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

25-
let crate_items = tcx.hir_crate_items(());
26-
for id in crate_items.foreign_items() {
27-
let attrs = tcx.hir().attrs(id.hir_id());
28-
if let Some((lang_item, _)) = lang_items::extract(attrs) {
27+
visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);
28+
29+
verify(tcx, items);
30+
}
31+
32+
struct WeakLangItemVisitor<'a, 'tcx> {
33+
tcx: TyCtxt<'tcx>,
34+
items: &'a mut lang_items::LanguageItems,
35+
}
36+
37+
impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
38+
fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) {
39+
if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
2940
if let Some(item) = LangItem::from_name(lang_item)
3041
&& item.is_weak()
3142
{
32-
if items.get(item).is_none() {
33-
items.missing.push(item);
43+
if self.items.get(item).is_none() {
44+
self.items.missing.push(item);
3445
}
3546
} else {
36-
let span = tcx.def_span(id.owner_id);
37-
tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
47+
self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item });
3848
}
3949
}
4050
}
41-
42-
verify(tcx, items);
4351
}
4452

4553
fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {

tests/ui/duplicate_entry_error.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
error[E0152]: found duplicate lang item `panic_impl`
22
--> $DIR/duplicate_entry_error.rs:11:1
33
|
4-
LL | fn panic_impl(info: &PanicInfo) -> ! {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | / fn panic_impl(info: &PanicInfo) -> ! {
5+
LL | |
6+
LL | | loop {}
7+
LL | | }
8+
| |_^
69
|
710
= note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on)
811
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib

tests/ui/error-codes/E0152.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box`
22
--> $DIR/E0152.rs:5:1
33
|
44
LL | struct Foo<T>(T);
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^
66
|
77
= note: the lang item is first defined in crate `alloc` (which `std` depends on)
88
= note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib

tests/ui/error-codes/E0264.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake`
22
--> $DIR/E0264.rs:5:5
33
|
44
LL | fn cake();
5-
| ^^^^^^^^^
5+
| ^^^^^^^^^^
66

77
error: aborting due to 1 previous error
88

tests/ui/lang-items/lang-item-generic-requirements.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ trait MyIndex<'a, T> {}
2222
#[lang = "phantom_data"]
2323
//~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument
2424
struct MyPhantomData<T, U>;
25+
//~^ ERROR parameter `T` is never used
26+
//~| ERROR parameter `U` is never used
2527

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

4447
// Use drop in place
4548
my_ptr_drop();

tests/ui/lang-items/lang-item-generic-requirements.stderr

+33-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>;
3333
| ------ this struct has 2 generic arguments
3434

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

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

53-
error: aborting due to 6 previous errors
53+
error[E0392]: parameter `T` is never used
54+
--> $DIR/lang-item-generic-requirements.rs:24:22
55+
|
56+
LL | struct MyPhantomData<T, U>;
57+
| ^ unused parameter
58+
|
59+
= help: consider removing `T` or referring to it in a field
60+
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
61+
62+
error[E0392]: parameter `U` is never used
63+
--> $DIR/lang-item-generic-requirements.rs:24:25
64+
|
65+
LL | struct MyPhantomData<T, U>;
66+
| ^ unused parameter
67+
|
68+
= help: consider removing `U` or referring to it in a field
69+
= help: if you intended `U` to be a const parameter, use `const U: usize` instead
70+
71+
error[E0369]: cannot add `{integer}` to `{integer}`
72+
--> $DIR/lang-item-generic-requirements.rs:44:7
73+
|
74+
LL | r + a;
75+
| - ^ - {integer}
76+
| |
77+
| {integer}
78+
79+
error: requires `copy` lang_item
80+
81+
error: aborting due to 10 previous errors
5482

55-
For more information about this error, try `rustc --explain E0718`.
83+
Some errors have detailed explanations: E0369, E0392, E0718.
84+
For more information about an error, try `rustc --explain E0369`.

tests/ui/panic-handler/panic-handler-duplicate.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
error[E0152]: found duplicate lang item `panic_impl`
22
--> $DIR/panic-handler-duplicate.rs:15:1
33
|
4-
LL | fn panic2(info: &PanicInfo) -> ! {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | / fn panic2(info: &PanicInfo) -> ! {
5+
LL | | loop {}
6+
LL | | }
7+
| |_^
68
|
79
note: the lang item is first defined here
810
--> $DIR/panic-handler-duplicate.rs:10:1
911
|
10-
LL | fn panic(info: &PanicInfo) -> ! {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
LL | / fn panic(info: &PanicInfo) -> ! {
13+
LL | | loop {}
14+
LL | | }
15+
| |_^
1216

1317
error: aborting due to 1 previous error
1418

tests/ui/panic-handler/panic-handler-std.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0152]: found duplicate lang item `panic_impl`
22
--> $DIR/panic-handler-std.rs:8:1
33
|
4-
LL | fn panic(info: PanicInfo) -> ! {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | / fn panic(info: PanicInfo) -> ! {
5+
LL | | loop {}
6+
LL | | }
7+
| |_^
68
|
79
= note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
810
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib

tests/ui/traits/issue-102989.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized`
77
fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
88
//~^ ERROR `self` parameter is only allowed in associated functions
99
//~| ERROR cannot find type `Struct` in this scope
10+
//~| ERROR mismatched types
1011
let x = x << 1;
1112
//~^ ERROR cannot find value `x` in this scope
1213
}

tests/ui/traits/issue-102989.stderr

+18-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
1313
| ^^^^^^ not found in this scope
1414

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

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

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

0 commit comments

Comments
 (0)