Skip to content

Commit 873a0f2

Browse files
committed
Add wasm_c_abi future-incompat lint
1 parent c5b5713 commit 873a0f2

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

compiler/rustc_lint_defs/src/builtin.rs

+39
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ declare_lint_pass! {
130130
UNUSED_VARIABLES,
131131
USELESS_DEPRECATED,
132132
WARNINGS,
133+
WASM_C_ABI,
133134
WHERE_CLAUSES_OBJECT_SAFETY,
134135
WRITES_THROUGH_IMMUTABLE_POINTER,
135136
// tidy-alphabetical-end
@@ -4564,3 +4565,41 @@ declare_lint! {
45644565
reference: "issue #120192 <https://github.com/rust-lang/rust/issues/120192>",
45654566
};
45664567
}
4568+
4569+
declare_lint! {
4570+
/// The `wasm_c_abi` lint detects crate dependencies that are incompatible
4571+
/// with future versions of Rust that will emit spec-compliant C ABI.
4572+
///
4573+
/// ### Example
4574+
///
4575+
/// ```rust,ignore (needs extern crate)
4576+
/// #![deny(wasm_c_abi)]
4577+
/// ```
4578+
///
4579+
/// This will produce:
4580+
///
4581+
/// ```text
4582+
/// error: the following packages contain code that will be rejected by a future version of Rust: wasm-bindgen v0.2.87
4583+
/// |
4584+
/// note: the lint level is defined here
4585+
/// --> src/lib.rs:1:9
4586+
/// |
4587+
/// 1 | #![deny(wasm_c_abi)]
4588+
/// | ^^^^^^^^^^
4589+
/// ```
4590+
///
4591+
/// ### Explanation
4592+
///
4593+
/// Rust has historically emitted non-spec-compliant C ABI. This has caused
4594+
/// incompatibilities between other compilers and Wasm targets. In a future
4595+
/// version of Rust this will be fixed and therefore dependencies relying
4596+
/// on the non-spec-compliant C ABI will stop functioning.
4597+
pub WASM_C_ABI,
4598+
Warn,
4599+
"detects dependencies that are incompatible with the Wasm C ABI",
4600+
@future_incompatible = FutureIncompatibleInfo {
4601+
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
4602+
reference: "issue #71871 <https://github.com/rust-lang/rust/issues/71871>",
4603+
};
4604+
crate_level_only
4605+
}

compiler/rustc_metadata/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ metadata_unsupported_abi =
281281
metadata_unsupported_abi_i686 =
282282
ABI not supported by `#[link(kind = "raw-dylib")]` on i686
283283
284+
metadata_wasm_c_abi =
285+
older versions of the `wasm-bindgen` crate will be incompatible with future versions of Rust; please update to `wasm-bindgen` v0.2.88
284286
metadata_wasm_import_form =
285287
wasm import module must be of the form `wasm_import_module = "string"`
286288

compiler/rustc_metadata/src/creader.rs

+41-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ use proc_macro::bridge::client::ProcMacro;
3131
use std::error::Error;
3232
use std::ops::Fn;
3333
use std::path::Path;
34+
use std::str::FromStr;
3435
use std::time::Duration;
35-
use std::{cmp, iter};
36+
use std::{cmp, env, iter};
3637

3738
/// The backend's way to give the crate store access to the metadata in a library.
3839
/// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -985,13 +986,52 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
985986
}
986987
}
987988

989+
fn report_future_incompatible_deps(&self, krate: &ast::Crate) {
990+
let name = self.tcx.crate_name(LOCAL_CRATE);
991+
992+
if name.as_str() == "wasm_bindgen" {
993+
let major = env::var("CARGO_PKG_VERSION_MAJOR")
994+
.ok()
995+
.and_then(|major| u64::from_str(&major).ok());
996+
let minor = env::var("CARGO_PKG_VERSION_MINOR")
997+
.ok()
998+
.and_then(|minor| u64::from_str(&minor).ok());
999+
let patch = env::var("CARGO_PKG_VERSION_PATCH")
1000+
.ok()
1001+
.and_then(|patch| u64::from_str(&patch).ok());
1002+
1003+
match (major, minor, patch) {
1004+
// v1 or bigger is valid.
1005+
(Some(1..), _, _) => return,
1006+
// v0.3 or bigger is valid.
1007+
(Some(0), Some(3..), _) => return,
1008+
// v0.2.88 or bigger is valid.
1009+
(Some(0), Some(2), Some(88..)) => return,
1010+
// Not using Cargo.
1011+
(None, None, None) => return,
1012+
_ => (),
1013+
}
1014+
1015+
// Make a point span rather than covering the whole file
1016+
let span = krate.spans.inner_span.shrink_to_lo();
1017+
1018+
self.sess.psess.buffer_lint(
1019+
lint::builtin::WASM_C_ABI,
1020+
span,
1021+
ast::CRATE_NODE_ID,
1022+
crate::fluent_generated::metadata_wasm_c_abi,
1023+
);
1024+
}
1025+
}
1026+
9881027
pub fn postprocess(&mut self, krate: &ast::Crate) {
9891028
self.inject_forced_externs();
9901029
self.inject_profiler_runtime(krate);
9911030
self.inject_allocator_crate(krate);
9921031
self.inject_panic_runtime(krate);
9931032

9941033
self.report_unused_deps(krate);
1034+
self.report_future_incompatible_deps(krate);
9951035

9961036
info!("{:?}", CrateDump(self.cstore));
9971037
}

0 commit comments

Comments
 (0)