From aab37fe52c0f142d116fee67d6eddedc7825dcc7 Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Sat, 27 Jun 2020 21:08:32 +0300 Subject: [PATCH 01/13] Add test for issue #56175 --- .../ui/issues/auxiliary/reexported-trait.rs | 17 ++++++++++++ src/test/ui/issues/issue-56175.rs | 9 +++++++ src/test/ui/issues/issue-56175.stderr | 27 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/test/ui/issues/auxiliary/reexported-trait.rs create mode 100644 src/test/ui/issues/issue-56175.rs create mode 100644 src/test/ui/issues/issue-56175.stderr diff --git a/src/test/ui/issues/auxiliary/reexported-trait.rs b/src/test/ui/issues/auxiliary/reexported-trait.rs new file mode 100644 index 0000000000000..51a991bef5959 --- /dev/null +++ b/src/test/ui/issues/auxiliary/reexported-trait.rs @@ -0,0 +1,17 @@ +mod private { + pub trait Trait { + fn trait_method(&self) { + } + } + pub trait TraitB { + fn trait_method_b(&self) { + } + } +} + +pub struct FooStruct; +pub use crate::private::Trait; +impl crate::private::Trait for FooStruct {} + +pub use crate::private::TraitB as TraitBRename; +impl crate::private::TraitB for FooStruct {} diff --git a/src/test/ui/issues/issue-56175.rs b/src/test/ui/issues/issue-56175.rs new file mode 100644 index 0000000000000..ca1d0d4310ae9 --- /dev/null +++ b/src/test/ui/issues/issue-56175.rs @@ -0,0 +1,9 @@ +// edition:2018 +// aux-crate:reexported_trait=reexported-trait.rs + +fn main() { + reexported_trait::FooStruct.trait_method(); + //~^ ERROR + reexported_trait::FooStruct.trait_method_b(); + //~^ ERROR +} diff --git a/src/test/ui/issues/issue-56175.stderr b/src/test/ui/issues/issue-56175.stderr new file mode 100644 index 0000000000000..dc5beb4271df7 --- /dev/null +++ b/src/test/ui/issues/issue-56175.stderr @@ -0,0 +1,27 @@ +error[E0599]: no method named `trait_method` found for struct `reexported_trait::FooStruct` in the current scope + --> $DIR/issue-56175.rs:5:33 + | +LL | reexported_trait::FooStruct.trait_method(); + | ^^^^^^^^^^^^ method not found in `reexported_trait::FooStruct` + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use reexported_trait::private::Trait; + | + +error[E0599]: no method named `trait_method_b` found for struct `reexported_trait::FooStruct` in the current scope + --> $DIR/issue-56175.rs:7:33 + | +LL | reexported_trait::FooStruct.trait_method_b(); + | ^^^^^^^^^^^^^^ method not found in `reexported_trait::FooStruct` + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use reexported_trait::private::TraitB; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. From 5427d3bf7c38df0c37597272bf34c6710cab3c52 Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Mon, 29 Jun 2020 21:51:32 +0300 Subject: [PATCH 02/13] Fix try_print_visible_def_path for Rust 2018 The recursive check of `try_print_visible_def_path` did not properly handle the Rust 2018 case of crate-paths without 'extern crate'. Instead, it returned a "not found" via (false, self). This fixes issue #56175. --- src/librustc_middle/ty/print/pretty.rs | 35 +++++++++++++------------- src/test/ui/issues/issue-56175.stderr | 4 +-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 061214249713d..bbf9f550c03f4 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -282,26 +282,27 @@ pub trait PrettyPrinter<'tcx>: // where there is no explicit `extern crate`, we just prepend // the crate name. match self.tcx().extern_crate(def_id) { - Some(&ExternCrate { - src: ExternCrateSource::Extern(def_id), - dependency_of: LOCAL_CRATE, - span, - .. - }) => { - debug!("try_print_visible_def_path: def_id={:?}", def_id); - return Ok(( - if !span.is_dummy() { - self.print_def_path(def_id, &[])? - } else { - self.path_crate(cnum)? - }, - true, - )); - } + Some(&ExternCrate { src, dependency_of, span, .. }) => match (src, dependency_of) { + (ExternCrateSource::Extern(def_id), LOCAL_CRATE) => { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + return Ok(( + if !span.is_dummy() { + self.print_def_path(def_id, &[])? + } else { + self.path_crate(cnum)? + }, + true, + )); + } + (ExternCrateSource::Path, LOCAL_CRATE) if self.tcx().sess.rust_2018() => { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + return Ok((self.path_crate(cnum)?, true)); + } + _ => {} + }, None => { return Ok((self.path_crate(cnum)?, true)); } - _ => {} } } diff --git a/src/test/ui/issues/issue-56175.stderr b/src/test/ui/issues/issue-56175.stderr index dc5beb4271df7..c0799db7c1286 100644 --- a/src/test/ui/issues/issue-56175.stderr +++ b/src/test/ui/issues/issue-56175.stderr @@ -7,7 +7,7 @@ LL | reexported_trait::FooStruct.trait_method(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use reexported_trait::private::Trait; +LL | use reexported_trait::Trait; | error[E0599]: no method named `trait_method_b` found for struct `reexported_trait::FooStruct` in the current scope @@ -19,7 +19,7 @@ LL | reexported_trait::FooStruct.trait_method_b(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use reexported_trait::private::TraitB; +LL | use reexported_trait::TraitBRename; | error: aborting due to 2 previous errors From f77b6fe5711e42321b3e2b8b438e00e682f5411b Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Wed, 1 Jul 2020 20:05:51 +0300 Subject: [PATCH 03/13] Review fix --- src/librustc_middle/ty/print/pretty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index bbf9f550c03f4..f94a51feca3b8 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -294,7 +294,7 @@ pub trait PrettyPrinter<'tcx>: true, )); } - (ExternCrateSource::Path, LOCAL_CRATE) if self.tcx().sess.rust_2018() => { + (ExternCrateSource::Path, LOCAL_CRATE) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok((self.path_crate(cnum)?, true)); } From 825eb478c5fee6edefc8e032298ac5317e2f09ca Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Sat, 4 Jul 2020 00:23:54 +0900 Subject: [PATCH 04/13] Add support for storing code model to LLVM module IR This patch avoids undefined behavior by linking different object files. Also this would it could be propagated properly to LTO. See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323. --- src/librustc_codegen_llvm/context.rs | 16 +++++++++++++++- src/librustc_codegen_llvm/llvm/ffi.rs | 1 + src/rustllvm/PassWrapper.cpp | 14 ++++++++++++++ src/test/codegen/codemodels.rs | 21 +++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen/codemodels.rs diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index e9a001bab7540..42120c5ee6906 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -22,7 +22,7 @@ use rustc_session::Session; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::Symbol; use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx}; -use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel}; +use rustc_target::spec::{CodeModel, HasTargetSpec, RelocModel, Target, TlsModel}; use std::cell::{Cell, RefCell}; use std::ffi::CStr; @@ -99,6 +99,16 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { } } +fn to_llvm_code_model(code_model: CodeModel) -> llvm::CodeModel { + match code_model { + CodeModel::Tiny => llvm::CodeModel::Tiny, + CodeModel::Small => llvm::CodeModel::Small, + CodeModel::Kernel => llvm::CodeModel::Kernel, + CodeModel::Medium => llvm::CodeModel::Medium, + CodeModel::Large => llvm::CodeModel::Large, + } +} + fn strip_function_ptr_alignment(data_layout: String) -> String { // FIXME: Make this more general. data_layout.replace("-Fi8-", "-") @@ -181,6 +191,10 @@ pub unsafe fn create_module( } } + if let Some(code_model) = sess.code_model() { + llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(code_model)); + } + // If skipping the PLT is enabled, we need to add some module metadata // to ensure intrinsic calls don't use it. if !sess.needs_plt() { diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 7beb4fc897472..c7ebd3f0684fa 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -2129,6 +2129,7 @@ extern "C" { pub fn LLVMRustUnsetComdat(V: &Value); pub fn LLVMRustSetModulePICLevel(M: &Module); pub fn LLVMRustSetModulePIELevel(M: &Module); + pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel); pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer; pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8; pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize; diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 41b14714842fd..c719f02b771f8 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1163,6 +1163,20 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) { unwrap(M)->setPIELevel(PIELevel::Level::Large); } +// Linking object files with different code models is undefined behavior +// because the compiler would have to generate additional code (to span +// longer jumps) if a larger code model is used with a smaller one. +// Therefore we will treat attempts to mix code models as an error. +// +// See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323. +extern "C" void LLVMRustSetModuleCodeModel(LLVMModuleRef M, + LLVMRustCodeModel Model) { + auto CM = fromRust(Model); + if (!CM.hasValue()) + return; + unwrap(M)->setCodeModel(*CM); +} + // Here you'll find an implementation of ThinLTO as used by the Rust compiler // right now. This ThinLTO support is only enabled on "recent ish" versions of // LLVM, and otherwise it's just blanket rejected from other compilers. diff --git a/src/test/codegen/codemodels.rs b/src/test/codegen/codemodels.rs new file mode 100644 index 0000000000000..7edbf0ea6f6aa --- /dev/null +++ b/src/test/codegen/codemodels.rs @@ -0,0 +1,21 @@ +// revisions: NOMODEL MODEL-TINY MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE +//[NOMODEL] compile-flags: +//[MODEL-TINY] compile-flags: --target=riscv32i-unknown-none-elf -C code-model=tiny +//[MODEL-SMALL] compile-flags: -C code-model=small +//[MODEL-KERNEL] compile-flags: --target=x86_64-unknown-linux-gnu -C code-model=kernel +//[MODEL-MEDIUM] compile-flags: --target=x86_64-unknown-linux-gnu -C code-model=medium +//[MODEL-LARGE] compile-flags: -C code-model=large + +#![crate_type = "lib"] + +// MODEL-TINY: !llvm.module.flags = !{{{.*}}} +// MODEL-TINY: !(([0-9]+)) = !(i32 1, !"Code-Model", i32 0) +// MODEL-SMALL: !llvm.module.flags = !{{{.*}}} +// MODEL-SMALL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 1} +// MODEL-KERNEL: !llvm.module.flags = !{{{.*}}} +// MODEL-KERNEL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 2} +// MODEL-MEDIUM: !llvm.module.flags = !{{{.*}}} +// MODEL-MEDIUM: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 3} +// MODEL-LARGE: !llvm.module.flags = !{{{.*}}} +// MODEL-LARGE: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 4} +// NOMODEL-NOT: Code Model From b99a08a3a561c06c0a9ff1a432602d174d0e1c7f Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Sat, 4 Jul 2020 02:10:18 +0900 Subject: [PATCH 05/13] Remove code-model=tiny from module IR test --- src/test/codegen/codemodels.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/codegen/codemodels.rs b/src/test/codegen/codemodels.rs index 7edbf0ea6f6aa..e3c258f864c61 100644 --- a/src/test/codegen/codemodels.rs +++ b/src/test/codegen/codemodels.rs @@ -1,6 +1,5 @@ -// revisions: NOMODEL MODEL-TINY MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE +// revisions: NOMODEL MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE //[NOMODEL] compile-flags: -//[MODEL-TINY] compile-flags: --target=riscv32i-unknown-none-elf -C code-model=tiny //[MODEL-SMALL] compile-flags: -C code-model=small //[MODEL-KERNEL] compile-flags: --target=x86_64-unknown-linux-gnu -C code-model=kernel //[MODEL-MEDIUM] compile-flags: --target=x86_64-unknown-linux-gnu -C code-model=medium @@ -8,8 +7,6 @@ #![crate_type = "lib"] -// MODEL-TINY: !llvm.module.flags = !{{{.*}}} -// MODEL-TINY: !(([0-9]+)) = !(i32 1, !"Code-Model", i32 0) // MODEL-SMALL: !llvm.module.flags = !{{{.*}}} // MODEL-SMALL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 1} // MODEL-KERNEL: !llvm.module.flags = !{{{.*}}} From 4a89c9fdedd8dc5ce59f55b4aa7b370183a01f74 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Sat, 4 Jul 2020 04:57:59 +0900 Subject: [PATCH 06/13] Remove duplicated to_llvm_code_model function --- src/librustc_codegen_llvm/back/write.rs | 2 +- src/librustc_codegen_llvm/context.rs | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 54271d3dd0491..180f3f2e2cf5c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -108,7 +108,7 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel { } } -fn to_llvm_code_model(code_model: Option) -> llvm::CodeModel { +pub fn to_llvm_code_model(code_model: Option) -> llvm::CodeModel { match code_model { Some(CodeModel::Tiny) => llvm::CodeModel::Tiny, Some(CodeModel::Small) => llvm::CodeModel::Small, diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 42120c5ee6906..7c48c50ab2e45 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,4 +1,5 @@ use crate::attributes; +use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; @@ -22,7 +23,7 @@ use rustc_session::Session; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::Symbol; use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx}; -use rustc_target::spec::{CodeModel, HasTargetSpec, RelocModel, Target, TlsModel}; +use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel}; use std::cell::{Cell, RefCell}; use std::ffi::CStr; @@ -99,16 +100,6 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { } } -fn to_llvm_code_model(code_model: CodeModel) -> llvm::CodeModel { - match code_model { - CodeModel::Tiny => llvm::CodeModel::Tiny, - CodeModel::Small => llvm::CodeModel::Small, - CodeModel::Kernel => llvm::CodeModel::Kernel, - CodeModel::Medium => llvm::CodeModel::Medium, - CodeModel::Large => llvm::CodeModel::Large, - } -} - fn strip_function_ptr_alignment(data_layout: String) -> String { // FIXME: Make this more general. data_layout.replace("-Fi8-", "-") @@ -191,9 +182,7 @@ pub unsafe fn create_module( } } - if let Some(code_model) = sess.code_model() { - llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(code_model)); - } + llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model())); // If skipping the PLT is enabled, we need to add some module metadata // to ensure intrinsic calls don't use it. From 7a3081baaf81c1d924f3143479ec0c4a8f1e62b7 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 3 Jul 2020 18:11:21 +0200 Subject: [PATCH 07/13] add `lazy_normalization_consts` feature gate --- src/librustc_feature/active.rs | 4 ++++ src/librustc_middle/ty/context.rs | 2 +- src/librustc_span/symbol.rs | 1 + .../{lazy-normalization => }/issue-71986.rs | 0 .../feature-gate-lazy_normalization_consts.rs | 10 +++++++++ ...ture-gate-lazy_normalization_consts.stderr | 21 +++++++++++++++++++ .../lazy_normalization_consts/issue-47814.rs | 16 ++++++++++++++ .../lazy_normalization_consts/issue-57739.rs | 17 +++++++++++++++ .../issue-57739.stderr | 19 +++++++++++++++++ .../lazy_normalization_consts/issue-73980.rs | 14 +++++++++++++ 10 files changed, 103 insertions(+), 1 deletion(-) rename src/test/ui/const-generics/{lazy-normalization => }/issue-71986.rs (100%) create mode 100644 src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs create mode 100644 src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr create mode 100644 src/test/ui/lazy_normalization_consts/issue-47814.rs create mode 100644 src/test/ui/lazy_normalization_consts/issue-57739.rs create mode 100644 src/test/ui/lazy_normalization_consts/issue-57739.stderr create mode 100644 src/test/ui/lazy_normalization_consts/issue-73980.rs diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 313744efb3fce..32481bf2b9574 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -570,6 +570,9 @@ declare_features! ( /// Allows capturing variables in scope using format_args! (active, format_args_capture, "1.46.0", Some(67984), None), + /// Lazily evaluate constants. This allows constants to depend on type parameters. + (active, lazy_normalization_consts, "1.46.0", Some(72219), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -586,5 +589,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::raw_dylib, sym::const_trait_impl, sym::const_trait_bound_opt_out, + sym::lazy_normalization_consts, sym::specialization, ]; diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d942c07965a49..698bef4374545 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1370,7 +1370,7 @@ impl<'tcx> TyCtxt<'tcx> { /// we still evaluate them eagerly. #[inline] pub fn lazy_normalization(self) -> bool { - self.features().const_generics + self.features().const_generics || self.features().lazy_normalization_consts } #[inline] diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index acc2a50abe88e..e35e1dd34134b 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -427,6 +427,7 @@ symbols! { label_break_value, lang, lang_items, + lazy_normalization_consts, lateout, let_chains, lhs, diff --git a/src/test/ui/const-generics/lazy-normalization/issue-71986.rs b/src/test/ui/const-generics/issue-71986.rs similarity index 100% rename from src/test/ui/const-generics/lazy-normalization/issue-71986.rs rename to src/test/ui/const-generics/issue-71986.rs diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs new file mode 100644 index 0000000000000..44cb74815c6a0 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs @@ -0,0 +1,10 @@ +pub const fn sof() -> usize { + 10 +} + +fn test() { + let _: [u8; sof::()]; + //~^ ERROR the size for values of type `T` +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr new file mode 100644 index 0000000000000..6e19251c72800 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr @@ -0,0 +1,21 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/feature-gate-lazy_normalization_consts.rs:6:23 + | +LL | pub const fn sof() -> usize { + | - required by this bound in `sof` +... +LL | fn test() { + | - this type parameter needs to be `std::marker::Sized` +LL | let _: [u8; sof::()]; + | ^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `T` + = note: to learn more, visit +help: consider relaxing the implicit `Sized` restriction + | +LL | pub const fn sof() -> usize { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/lazy_normalization_consts/issue-47814.rs b/src/test/ui/lazy_normalization_consts/issue-47814.rs new file mode 100644 index 0000000000000..1fd0c45841b0d --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-47814.rs @@ -0,0 +1,16 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] +pub struct ArpIPv4<'a> { + _s: &'a u8 +} + +impl<'a> ArpIPv4<'a> { + const LENGTH: usize = 20; + + pub fn to_buffer() -> [u8; Self::LENGTH] { + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/issue-57739.rs b/src/test/ui/lazy_normalization_consts/issue-57739.rs new file mode 100644 index 0000000000000..4607f3e99b51f --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-57739.rs @@ -0,0 +1,17 @@ +#![feature(lazy_normalization_consts)] +//~^ WARN the feature `lazy_normalization_consts` is incomplete +trait ArraySizeTrait { + const SIZE: usize = 0; +} + +impl ArraySizeTrait for T { + const SIZE: usize = 1; +} + +struct SomeArray { + array: [u8; T::SIZE], + //~^ ERROR constant expression depends on a generic parameter + phantom: std::marker::PhantomData, +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/issue-57739.stderr b/src/test/ui/lazy_normalization_consts/issue-57739.stderr new file mode 100644 index 0000000000000..1987f5890c041 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-57739.stderr @@ -0,0 +1,19 @@ +warning: the feature `lazy_normalization_consts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-57739.rs:1:12 + | +LL | #![feature(lazy_normalization_consts)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #72219 for more information + +error: constant expression depends on a generic parameter + --> $DIR/issue-57739.rs:12:5 + | +LL | array: [u8; T::SIZE], + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error; 1 warning emitted + diff --git a/src/test/ui/lazy_normalization_consts/issue-73980.rs b/src/test/ui/lazy_normalization_consts/issue-73980.rs new file mode 100644 index 0000000000000..339b22c0b423d --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-73980.rs @@ -0,0 +1,14 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] + +pub struct X(P, Q); +pub struct L(T); + +impl L { + const S: usize = 1; +} + +impl X::S]> {} + +fn main() {} From 20d6941be7039eb7fad9a4f893792a77d65bc792 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 4 Jul 2020 14:02:41 +0200 Subject: [PATCH 08/13] ConstCx to LocalDefId --- src/librustc_mir/const_eval/eval_queries.rs | 8 ++++---- src/librustc_mir/transform/check_consts/mod.rs | 4 ++-- .../check_consts/post_drop_elaboration.rs | 8 +------- .../transform/check_consts/qualifs.rs | 2 +- .../transform/check_consts/validation.rs | 18 +++++++++--------- src/librustc_mir/transform/mod.rs | 5 +++-- src/librustc_mir/transform/promote_consts.rs | 9 +++++---- 7 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index d62300b3f5541..75067ffa4b338 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -334,9 +334,9 @@ pub fn const_eval_raw_provider<'tcx>( } v - } else if def_id.is_local() { + } else if let Some(def_id) = def_id.as_local() { // constant defined in this crate, we can figure out a lint level! - match tcx.def_kind(def_id) { + match tcx.def_kind(def_id.to_def_id()) { // constants never produce a hard error at the definition site. Anything else is // a backwards compatibility hazard (and will break old versions of winapi for // sure) @@ -346,7 +346,7 @@ pub fn const_eval_raw_provider<'tcx>( // validation thus preventing such a hard error from being a backwards // compatibility hazard DefKind::Const | DefKind::AssocConst => { - let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + let hir_id = tcx.hir().as_local_hir_id(def_id); err.report_as_lint( tcx.at(tcx.def_span(def_id)), "any use of this value will cause an error", @@ -369,7 +369,7 @@ pub fn const_eval_raw_provider<'tcx>( err.report_as_lint( tcx.at(span), "reaching this expression at runtime will panic or abort", - tcx.hir().as_local_hir_id(def_id.expect_local()), + tcx.hir().as_local_hir_id(def_id), Some(err.span), ) } diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs index e4aa88e3c20a7..81c1b0b5bd49f 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/src/librustc_mir/transform/check_consts/mod.rs @@ -22,7 +22,7 @@ pub mod validation; pub struct ConstCx<'mir, 'tcx> { pub body: &'mir mir::Body<'tcx>, pub tcx: TyCtxt<'tcx>, - pub def_id: DefId, + pub def_id: LocalDefId, pub param_env: ty::ParamEnv<'tcx>, pub const_kind: Option, } @@ -40,7 +40,7 @@ impl ConstCx<'mir, 'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Self { let const_kind = tcx.hir().body_const_context(def_id); - ConstCx { body, tcx, def_id: def_id.to_def_id(), param_env, const_kind } + ConstCx { body, tcx, def_id: def_id, param_env, const_kind } } /// Returns the kind of const context this `Item` represents (`const`, `static`, etc.). diff --git a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs index 1fd907f89fe18..33fe2758c28fe 100644 --- a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs +++ b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs @@ -29,13 +29,7 @@ pub fn check_live_drops(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &mir::Body< return; } - let ccx = ConstCx { - body, - tcx, - def_id: def_id.to_def_id(), - const_kind, - param_env: tcx.param_env(def_id), - }; + let ccx = ConstCx { body, tcx, def_id: def_id, const_kind, param_env: tcx.param_env(def_id) }; let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() }; diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index e2893e81a2ce6..3dddd9c1c1766 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -126,7 +126,7 @@ impl Qualif for CustomEq { // because that component may be part of an enum variant (e.g., // `Option::::Some`), in which case some values of this type may be // structural-match (`Option::None`). - let id = cx.tcx.hir().local_def_id_to_hir_id(cx.def_id.as_local().unwrap()); + let id = cx.tcx.hir().local_def_id_to_hir_id(cx.def_id); traits::search_for_structural_match_violation(id, cx.body.span, cx.tcx, ty).is_some() } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index f00fc96e5915a..5cb161ebcfb5e 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -56,7 +56,7 @@ impl Qualifs<'mir, 'tcx> { // without breaking stable code? MaybeMutBorrowedLocals::mut_borrows_only(tcx, &body, param_env) .unsound_ignore_borrow_on_drop() - .into_engine(tcx, &body, def_id) + .into_engine(tcx, &body, def_id.to_def_id()) .iterate_to_fixpoint() .into_results_cursor(&body) }); @@ -83,7 +83,7 @@ impl Qualifs<'mir, 'tcx> { let ConstCx { tcx, body, def_id, .. } = *ccx; FlowSensitiveAnalysis::new(NeedsDrop, ccx) - .into_engine(tcx, &body, def_id) + .into_engine(tcx, &body, def_id.to_def_id()) .iterate_to_fixpoint() .into_results_cursor(&body) }); @@ -110,7 +110,7 @@ impl Qualifs<'mir, 'tcx> { let ConstCx { tcx, body, def_id, .. } = *ccx; FlowSensitiveAnalysis::new(HasMutInterior, ccx) - .into_engine(tcx, &body, def_id) + .into_engine(tcx, &body, def_id.to_def_id()) .iterate_to_fixpoint() .into_results_cursor(&body) }); @@ -153,7 +153,7 @@ impl Qualifs<'mir, 'tcx> { hir::ConstContext::Const | hir::ConstContext::Static(_) => { let mut cursor = FlowSensitiveAnalysis::new(CustomEq, ccx) - .into_engine(ccx.tcx, &ccx.body, ccx.def_id) + .into_engine(ccx.tcx, &ccx.body, ccx.def_id.to_def_id()) .iterate_to_fixpoint() .into_results_cursor(&ccx.body); @@ -195,13 +195,13 @@ impl Validator<'mir, 'tcx> { let ConstCx { tcx, body, def_id, const_kind, .. } = *self.ccx; let use_min_const_fn_checks = (const_kind == Some(hir::ConstContext::ConstFn) - && crate::const_eval::is_min_const_fn(tcx, def_id)) + && crate::const_eval::is_min_const_fn(tcx, def_id.to_def_id())) && !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you; if use_min_const_fn_checks { // Enforce `min_const_fn` for stable `const fn`s. use crate::transform::qualify_min_const_fn::is_min_const_fn; - if let Err((span, err)) = is_min_const_fn(tcx, def_id, &body) { + if let Err((span, err)) = is_min_const_fn(tcx, def_id.to_def_id(), &body) { error_min_const_fn_violation(tcx, span, err); return; } @@ -212,10 +212,10 @@ impl Validator<'mir, 'tcx> { // Ensure that the end result is `Sync` in a non-thread local `static`. let should_check_for_sync = const_kind == Some(hir::ConstContext::Static(hir::Mutability::Not)) - && !tcx.is_thread_local_static(def_id); + && !tcx.is_thread_local_static(def_id.to_def_id()); if should_check_for_sync { - let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + let hir_id = tcx.hir().as_local_hir_id(def_id); check_return_ty_is_sync(tcx, &body, hir_id); } } @@ -535,7 +535,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { // `#[allow_internal_unstable]`. use crate::transform::qualify_min_const_fn::lib_feature_allowed; if !self.span.allows_unstable(feature) - && !lib_feature_allowed(self.tcx, self.def_id, feature) + && !lib_feature_allowed(self.tcx, self.def_id.to_def_id(), feature) { self.check_op(ops::FnCallUnstable(def_id, feature)); } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 8ca240d2c7da7..14c3093e1e9a1 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -203,7 +203,8 @@ pub fn run_passes( } fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { - let const_kind = tcx.hir().body_const_context(def_id.expect_local()); + let def_id = def_id.expect_local(); + let const_kind = tcx.hir().body_const_context(def_id); // No need to const-check a non-const `fn`. if const_kind.is_none() { @@ -214,7 +215,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before // performing the steal. - let body = &tcx.mir_const(def_id).borrow(); + let body = &tcx.mir_const(def_id.to_def_id()).borrow(); if body.return_ty().references_error() { tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors"); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index bd7ebaa01f81b..5aa67227994d9 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -60,15 +60,16 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> { return; } - let def_id = src.def_id(); + let def_id = src.def_id().expect_local(); let mut rpo = traversal::reverse_postorder(body); - let ccx = ConstCx::new(tcx, def_id.expect_local(), body); + let ccx = ConstCx::new(tcx, def_id, body); let (temps, all_candidates) = collect_temps_and_candidates(&ccx, &mut rpo); let promotable_candidates = validate_candidates(&ccx, &temps, &all_candidates); - let promoted = promote_candidates(def_id, body, tcx, temps, promotable_candidates); + let promoted = + promote_candidates(def_id.to_def_id(), body, tcx, temps, promotable_candidates); self.promoted_fragments.set(promoted); } } @@ -724,7 +725,7 @@ impl<'tcx> Validator<'_, 'tcx> { ty::FnDef(def_id, _) => { is_const_fn(self.tcx, def_id) || is_unstable_const_fn(self.tcx, def_id).is_some() - || is_lang_panic_fn(self.tcx, self.def_id) + || is_lang_panic_fn(self.tcx, self.def_id.to_def_id()) } _ => false, }; From dbcabc248c0e035f916a5f4bb64b714640a5c338 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 4 Jul 2020 14:14:41 +0200 Subject: [PATCH 09/13] instantiate_opaque_types LocalDefId --- .../borrow_check/type_check/input_output.rs | 4 ++-- src/librustc_mir/borrow_check/type_check/mod.rs | 8 ++++---- src/librustc_trait_selection/opaque_types.rs | 17 ++++++----------- src/librustc_typeck/check/mod.rs | 6 +++--- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/src/librustc_mir/borrow_check/type_check/input_output.rs index edd2dc3c2de55..8cebd3679345f 100644 --- a/src/librustc_mir/borrow_check/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/type_check/input_output.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Err(terr) = self.eq_opaque_type_and_type( mir_output_ty, normalized_output_ty, - self.mir_def_id.to_def_id(), + self.mir_def_id, Locations::All(output_span), ConstraintCategory::BoringNoLocation, ) { @@ -145,7 +145,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Err(err) = self.eq_opaque_type_and_type( mir_output_ty, user_provided_output_ty, - self.mir_def_id.to_def_id(), + self.mir_def_id, Locations::All(output_span), ConstraintCategory::BoringNoLocation, ) { diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 0e35cafb9f3e9..3532b6de003ba 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -1144,7 +1144,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // When you have `let x: impl Foo = ...` in a closure, // the resulting inferend values are stored with the // def-id of the base function. - let parent_def_id = self.tcx().closure_base_def_id(self.mir_def_id.to_def_id()); + let parent_def_id = + self.tcx().closure_base_def_id(self.mir_def_id.to_def_id()).expect_local(); return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category); } else { return Err(terr); @@ -1208,7 +1209,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, revealed_ty: Ty<'tcx>, anon_ty: Ty<'tcx>, - anon_owner_def_id: DefId, + anon_owner_def_id: LocalDefId, locations: Locations, category: ConstraintCategory, ) -> Fallible<()> { @@ -1238,8 +1239,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = infcx.tcx; let param_env = self.param_env; let body = self.body; - let concrete_opaque_types = - &tcx.typeck_tables_of(anon_owner_def_id.expect_local()).concrete_opaque_types; + let concrete_opaque_types = &tcx.typeck_tables_of(anon_owner_def_id).concrete_opaque_types; let mut opaque_type_values = Vec::new(); debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id); diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index ce478de7c755c..b60531833bd41 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -108,7 +108,7 @@ pub enum GenerateMemberConstraints { pub trait InferCtxtExt<'tcx> { fn instantiate_opaque_types>( &self, - parent_def_id: DefId, + parent_def_id: LocalDefId, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, value: &T, @@ -184,7 +184,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// - `value_span` -- the span where the value came from, used in error reporting fn instantiate_opaque_types>( &self, - parent_def_id: DefId, + parent_def_id: LocalDefId, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, value: &T, @@ -986,7 +986,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { struct Instantiator<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, - parent_def_id: DefId, + parent_def_id: LocalDefId, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, value_span: Span, @@ -1043,8 +1043,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let parent_def_id = self.parent_def_id; let def_scope_default = || { let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); - parent_def_id - == tcx.hir().local_def_id(opaque_parent_hir_id).to_def_id() + parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id) }; let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) { Some(Node::Item(item)) => match item.kind { @@ -1053,18 +1052,14 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { impl_trait_fn: Some(parent), origin, .. - }) => (parent == self.parent_def_id, origin), + }) => (parent == self.parent_def_id.to_def_id(), origin), // Named `type Foo = impl Bar;` hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, origin, .. }) => ( - may_define_opaque_type( - tcx, - self.parent_def_id.expect_local(), - opaque_hir_id, - ), + may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id), origin, ), _ => (def_scope_default(), hir::OpaqueTyOrigin::Misc), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 58fd0f989c678..e564b01b11721 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1321,8 +1321,8 @@ fn check_fn<'a, 'tcx>( fcx.resume_yield_tys = Some((resume_ty, yield_ty)); } - let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()); - let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local()); + let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local(); + let outer_hir_id = hir.as_local_hir_id(outer_def_id); GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body); // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` @@ -3427,7 +3427,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (value, opaque_type_map) = self.register_infer_ok_obligations(self.instantiate_opaque_types( - parent_def_id.to_def_id(), + parent_def_id, self.body_id, self.param_env, value, From 67a5e2b1a006c624d1fe41c627b3e0c612e8daf3 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Sat, 4 Jul 2020 23:02:07 +0900 Subject: [PATCH 10/13] Fix for reviews --- src/librustc_codegen_llvm/back/write.rs | 2 +- src/librustc_codegen_llvm/context.rs | 5 +++++ src/rustllvm/PassWrapper.cpp | 6 ------ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 180f3f2e2cf5c..af87651833d88 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -108,7 +108,7 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel { } } -pub fn to_llvm_code_model(code_model: Option) -> llvm::CodeModel { +pub(crate) fn to_llvm_code_model(code_model: Option) -> llvm::CodeModel { match code_model { Some(CodeModel::Tiny) => llvm::CodeModel::Tiny, Some(CodeModel::Small) => llvm::CodeModel::Small, diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 7c48c50ab2e45..d7ab1e2327519 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -182,6 +182,11 @@ pub unsafe fn create_module( } } + // Linking object files with different code models is undefined behavior + // because the compiler would have to generate additional code (to span + // longer jumps) if a larger code model is used with a smaller one. + // + // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323. llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model())); // If skipping the PLT is enabled, we need to add some module metadata diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index c719f02b771f8..3ad3c5353b7b0 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1163,12 +1163,6 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) { unwrap(M)->setPIELevel(PIELevel::Level::Large); } -// Linking object files with different code models is undefined behavior -// because the compiler would have to generate additional code (to span -// longer jumps) if a larger code model is used with a smaller one. -// Therefore we will treat attempts to mix code models as an error. -// -// See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323. extern "C" void LLVMRustSetModuleCodeModel(LLVMModuleRef M, LLVMRustCodeModel Model) { auto CM = fromRust(Model); From f5305c3d16fb8221463ef604a1ea5ac11506ba6d Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 4 Jul 2020 16:20:27 +0200 Subject: [PATCH 11/13] nit Co-authored-by: varkor --- .../transform/check_consts/post_drop_elaboration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs index 33fe2758c28fe..55075b3ab5e99 100644 --- a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs +++ b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs @@ -29,7 +29,7 @@ pub fn check_live_drops(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &mir::Body< return; } - let ccx = ConstCx { body, tcx, def_id: def_id, const_kind, param_env: tcx.param_env(def_id) }; + let ccx = ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) }; let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() }; From 66fb778acc512213b8883101f275a7fa44c9b75d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 27 Jun 2020 11:47:18 +0200 Subject: [PATCH 12/13] Make `rustc_peek` a safe intrinsic --- src/librustc_typeck/check/intrinsic.rs | 2 +- src/test/ui/mir-dataflow/def-inits-1.rs | 18 +++++------ src/test/ui/mir-dataflow/def-inits-1.stderr | 24 +++++++-------- .../mir-dataflow/indirect-mutation-offset.rs | 2 +- .../indirect-mutation-offset.stderr | 6 ++-- src/test/ui/mir-dataflow/inits-1.rs | 18 +++++------ src/test/ui/mir-dataflow/inits-1.stderr | 18 +++++------ src/test/ui/mir-dataflow/liveness-ptr.rs | 6 ++-- src/test/ui/mir-dataflow/liveness-ptr.stderr | 6 ++-- src/test/ui/mir-dataflow/uninits-1.rs | 18 +++++------ src/test/ui/mir-dataflow/uninits-1.stderr | 30 +++++++++---------- src/test/ui/mir-dataflow/uninits-2.rs | 4 +-- src/test/ui/mir-dataflow/uninits-2.stderr | 6 ++-- 13 files changed, 79 insertions(+), 79 deletions(-) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 6205088adadb7..da5b9f18c0719 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -75,7 +75,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { | "saturating_sub" | "rotate_left" | "rotate_right" | "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" | "discriminant_value" | "type_id" | "likely" | "unlikely" | "ptr_guaranteed_eq" | "ptr_guaranteed_ne" | "minnumf32" | "minnumf64" | "maxnumf32" - | "maxnumf64" | "type_name" | "variant_count" => hir::Unsafety::Normal, + | "rustc_peek" | "maxnumf64" | "type_name" | "variant_count" => hir::Unsafety::Normal, _ => hir::Unsafety::Unsafe, } } diff --git a/src/test/ui/mir-dataflow/def-inits-1.rs b/src/test/ui/mir-dataflow/def-inits-1.rs index 91d41e9b5794e..30460824a1678 100644 --- a/src/test/ui/mir-dataflow/def-inits-1.rs +++ b/src/test/ui/mir-dataflow/def-inits-1.rs @@ -11,13 +11,13 @@ struct S(i32); fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { let ret; // `ret` starts off uninitialized - unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set + rustc_peek(&ret); //~ ERROR rustc_peek: bit not set // All function formal parameters start off initialized. - unsafe { rustc_peek(&x) }; - unsafe { rustc_peek(&y) }; - unsafe { rustc_peek(&z) }; + rustc_peek(&x); + rustc_peek(&y); + rustc_peek(&z); ret = if test { ::std::mem::replace(x, y) @@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { }; // `z` may be uninitialized here. - unsafe { rustc_peek(&z); } //~ ERROR rustc_peek: bit not set + rustc_peek(&z); //~ ERROR rustc_peek: bit not set // `y` is definitely uninitialized here. - unsafe { rustc_peek(&y); } //~ ERROR rustc_peek: bit not set + rustc_peek(&y); //~ ERROR rustc_peek: bit not set // `x` is still (definitely) initialized (replace above is a reborrow). - unsafe { rustc_peek(&x); } + rustc_peek(&x); ::std::mem::drop(x); // `x` is *definitely* uninitialized here - unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set + rustc_peek(&x); //~ ERROR rustc_peek: bit not set // `ret` is now definitely initialized (via `if` above). - unsafe { rustc_peek(&ret); } + rustc_peek(&ret); ret } diff --git a/src/test/ui/mir-dataflow/def-inits-1.stderr b/src/test/ui/mir-dataflow/def-inits-1.stderr index 48d8450489488..e2bddb54d9ba8 100644 --- a/src/test/ui/mir-dataflow/def-inits-1.stderr +++ b/src/test/ui/mir-dataflow/def-inits-1.stderr @@ -1,26 +1,26 @@ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:14:14 + --> $DIR/def-inits-1.rs:14:5 | -LL | unsafe { rustc_peek(&ret); } - | ^^^^^^^^^^^^^^^^ +LL | rustc_peek(&ret); + | ^^^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:30:14 + --> $DIR/def-inits-1.rs:30:5 | -LL | unsafe { rustc_peek(&z); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&z); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:33:14 + --> $DIR/def-inits-1.rs:33:5 | -LL | unsafe { rustc_peek(&y); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&y); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:41:14 + --> $DIR/def-inits-1.rs:41:5 | -LL | unsafe { rustc_peek(&x); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&x); + | ^^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs index caa307e269fe7..374a9f75a134b 100644 --- a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs +++ b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs @@ -38,7 +38,7 @@ const BOO: i32 = { *rmut_cell = 42; // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!! let val = *rmut_cell; - unsafe { rustc_peek(x) }; //~ ERROR rustc_peek: bit not set + rustc_peek(x); //~ ERROR rustc_peek: bit not set val }; diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr index 8d3548ececdd9..1d5287c15ab79 100644 --- a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr +++ b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr @@ -1,8 +1,8 @@ error: rustc_peek: bit not set - --> $DIR/indirect-mutation-offset.rs:41:14 + --> $DIR/indirect-mutation-offset.rs:41:5 | -LL | unsafe { rustc_peek(x) }; - | ^^^^^^^^^^^^^ +LL | rustc_peek(x); + | ^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation diff --git a/src/test/ui/mir-dataflow/inits-1.rs b/src/test/ui/mir-dataflow/inits-1.rs index 4a4786a2a7378..8fb1d4bc736d6 100644 --- a/src/test/ui/mir-dataflow/inits-1.rs +++ b/src/test/ui/mir-dataflow/inits-1.rs @@ -11,13 +11,13 @@ struct S(i32); fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { let ret; // `ret` starts off uninitialized, so we get an error report here. - unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set + rustc_peek(&ret); //~ ERROR rustc_peek: bit not set // All function formal parameters start off initialized. - unsafe { rustc_peek(&x) }; - unsafe { rustc_peek(&y) }; - unsafe { rustc_peek(&z) }; + rustc_peek(&x); + rustc_peek(&y); + rustc_peek(&z); ret = if test { ::std::mem::replace(x, y) @@ -28,21 +28,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { // `z` may be initialized here. - unsafe { rustc_peek(&z); } + rustc_peek(&z); // `y` is definitely uninitialized here. - unsafe { rustc_peek(&y); } //~ ERROR rustc_peek: bit not set + rustc_peek(&y); //~ ERROR rustc_peek: bit not set // `x` is still (definitely) initialized (replace above is a reborrow). - unsafe { rustc_peek(&x); } + rustc_peek(&x); ::std::mem::drop(x); // `x` is *definitely* uninitialized here - unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set + rustc_peek(&x); //~ ERROR rustc_peek: bit not set // `ret` is now definitely initialized (via `if` above). - unsafe { rustc_peek(&ret); } + rustc_peek(&ret); ret } diff --git a/src/test/ui/mir-dataflow/inits-1.stderr b/src/test/ui/mir-dataflow/inits-1.stderr index 23d0679cb1ac1..7a00a70af6f84 100644 --- a/src/test/ui/mir-dataflow/inits-1.stderr +++ b/src/test/ui/mir-dataflow/inits-1.stderr @@ -1,20 +1,20 @@ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:14:14 + --> $DIR/inits-1.rs:14:5 | -LL | unsafe { rustc_peek(&ret); } - | ^^^^^^^^^^^^^^^^ +LL | rustc_peek(&ret); + | ^^^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:34:14 + --> $DIR/inits-1.rs:34:5 | -LL | unsafe { rustc_peek(&y); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&y); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:42:14 + --> $DIR/inits-1.rs:42:5 | -LL | unsafe { rustc_peek(&x); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&x); + | ^^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation diff --git a/src/test/ui/mir-dataflow/liveness-ptr.rs b/src/test/ui/mir-dataflow/liveness-ptr.rs index 34097d7526a6e..786da523a3391 100644 --- a/src/test/ui/mir-dataflow/liveness-ptr.rs +++ b/src/test/ui/mir-dataflow/liveness-ptr.rs @@ -10,17 +10,17 @@ fn foo() -> i32 { x = 0; // `x` is live here since it is used in the next statement... - unsafe { rustc_peek(x); } + rustc_peek(x); p = &x; // ... but not here, even while it can be accessed through `p`. - unsafe { rustc_peek(x); } //~ ERROR rustc_peek: bit not set + rustc_peek(x); //~ ERROR rustc_peek: bit not set let tmp = unsafe { *p }; x = tmp + 1; - unsafe { rustc_peek(x); } + rustc_peek(x); x } diff --git a/src/test/ui/mir-dataflow/liveness-ptr.stderr b/src/test/ui/mir-dataflow/liveness-ptr.stderr index 3397d0c5a121d..858cdbac3d312 100644 --- a/src/test/ui/mir-dataflow/liveness-ptr.stderr +++ b/src/test/ui/mir-dataflow/liveness-ptr.stderr @@ -1,8 +1,8 @@ error: rustc_peek: bit not set - --> $DIR/liveness-ptr.rs:18:14 + --> $DIR/liveness-ptr.rs:18:5 | -LL | unsafe { rustc_peek(x); } - | ^^^^^^^^^^^^^ +LL | rustc_peek(x); + | ^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation diff --git a/src/test/ui/mir-dataflow/uninits-1.rs b/src/test/ui/mir-dataflow/uninits-1.rs index 66b3f458a5159..c2b4284a7b4f8 100644 --- a/src/test/ui/mir-dataflow/uninits-1.rs +++ b/src/test/ui/mir-dataflow/uninits-1.rs @@ -11,13 +11,13 @@ struct S(i32); fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { let ret; // `ret` starts off uninitialized - unsafe { rustc_peek(&ret); } + rustc_peek(&ret); // All function formal parameters start off initialized. - unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set - unsafe { rustc_peek(&y) }; //~ ERROR rustc_peek: bit not set - unsafe { rustc_peek(&z) }; //~ ERROR rustc_peek: bit not set + rustc_peek(&x); //~ ERROR rustc_peek: bit not set + rustc_peek(&y); //~ ERROR rustc_peek: bit not set + rustc_peek(&z); //~ ERROR rustc_peek: bit not set ret = if test { ::std::mem::replace(x, y) @@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { }; // `z` may be uninitialized here. - unsafe { rustc_peek(&z); } + rustc_peek(&z); // `y` is definitely uninitialized here. - unsafe { rustc_peek(&y); } + rustc_peek(&y); // `x` is still (definitely) initialized (replace above is a reborrow). - unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set + rustc_peek(&x); //~ ERROR rustc_peek: bit not set ::std::mem::drop(x); // `x` is *definitely* uninitialized here - unsafe { rustc_peek(&x); } + rustc_peek(&x); // `ret` is now definitely initialized (via `if` above). - unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set + rustc_peek(&ret); //~ ERROR rustc_peek: bit not set ret } diff --git a/src/test/ui/mir-dataflow/uninits-1.stderr b/src/test/ui/mir-dataflow/uninits-1.stderr index 5f6dbde212d0a..c52f5ac7bd9b6 100644 --- a/src/test/ui/mir-dataflow/uninits-1.stderr +++ b/src/test/ui/mir-dataflow/uninits-1.stderr @@ -1,32 +1,32 @@ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:18:14 + --> $DIR/uninits-1.rs:18:5 | -LL | unsafe { rustc_peek(&x) }; - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&x); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:19:14 + --> $DIR/uninits-1.rs:19:5 | -LL | unsafe { rustc_peek(&y) }; - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&y); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:20:14 + --> $DIR/uninits-1.rs:20:5 | -LL | unsafe { rustc_peek(&z) }; - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&z); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:36:14 + --> $DIR/uninits-1.rs:36:5 | -LL | unsafe { rustc_peek(&x); } - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&x); + | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:44:14 + --> $DIR/uninits-1.rs:44:5 | -LL | unsafe { rustc_peek(&ret); } - | ^^^^^^^^^^^^^^^^ +LL | rustc_peek(&ret); + | ^^^^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation diff --git a/src/test/ui/mir-dataflow/uninits-2.rs b/src/test/ui/mir-dataflow/uninits-2.rs index 2ccf1c7f9d6c6..c584ee74afb48 100644 --- a/src/test/ui/mir-dataflow/uninits-2.rs +++ b/src/test/ui/mir-dataflow/uninits-2.rs @@ -11,12 +11,12 @@ struct S(i32); fn foo(x: &mut S) { // `x` is initialized here, so maybe-uninit bit is 0. - unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set + rustc_peek(&x); //~ ERROR rustc_peek: bit not set ::std::mem::drop(x); // `x` definitely uninitialized here, so maybe-uninit bit is 1. - unsafe { rustc_peek(&x) }; + rustc_peek(&x); } fn main() { foo(&mut S(13)); diff --git a/src/test/ui/mir-dataflow/uninits-2.stderr b/src/test/ui/mir-dataflow/uninits-2.stderr index dcb61371994db..0ef954e35a4d8 100644 --- a/src/test/ui/mir-dataflow/uninits-2.stderr +++ b/src/test/ui/mir-dataflow/uninits-2.stderr @@ -1,8 +1,8 @@ error: rustc_peek: bit not set - --> $DIR/uninits-2.rs:14:14 + --> $DIR/uninits-2.rs:14:5 | -LL | unsafe { rustc_peek(&x) }; - | ^^^^^^^^^^^^^^ +LL | rustc_peek(&x); + | ^^^^^^^^^^^^^^ error: stop_after_dataflow ended compilation From 394b8cdfb7734a6dcb10b392c5b83e1b3d9521d3 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 28 Jun 2020 12:58:20 +0200 Subject: [PATCH 13/13] Match on `Symbol` instead of `&str` for type-checking intrinsics. --- src/librustc_span/symbol.rs | 79 ++++++++ src/librustc_typeck/check/intrinsic.rs | 263 ++++++++++++++----------- src/librustc_typeck/collect.rs | 2 +- 3 files changed, 229 insertions(+), 115 deletions(-) diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index acc2a50abe88e..c34da8b1cf326 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -152,10 +152,14 @@ symbols! { arm_target_feature, asm, assert, + assert_inhabited, + assert_uninit_valid, + assert_zero_valid, associated_consts, associated_type_bounds, associated_type_defaults, associated_types, + assume, assume_init, async_await, async_closure, @@ -181,11 +185,14 @@ symbols! { box_patterns, box_syntax, braced_empty_structs, + breakpoint, bswap, bitreverse, C, caller_location, cdylib, + ceilf32, + ceilf64, cfg, cfg_accessible, cfg_attr, @@ -239,8 +246,14 @@ symbols! { convert, Copy, copy_closures, + copy, + copy_nonoverlapping, + copysignf32, + copysignf64, core, core_intrinsics, + cosf32, + cosf64, count_code_region, coverage_counter_add, coverage_counter_subtract, @@ -299,6 +312,7 @@ symbols! { dropck_eyepatch, dropck_parametricity, drop_types_in_const, + drop_in_place, dylib, dyn_trait, eh_personality, @@ -311,11 +325,16 @@ symbols! { Eq, Equal, enclosing_scope, + exact_div, except, exclusive_range_pattern, exhaustive_integer_patterns, exhaustive_patterns, existential_type, + expf32, + expf64, + exp2f32, + exp2f64, expected, export_name, expr, @@ -329,6 +348,10 @@ symbols! { f16c_target_feature, f32, f64, + fadd_fast, + fabsf32, + fabsf64, + fdiv_fast, feature, ffi_const, ffi_pure, @@ -336,13 +359,21 @@ symbols! { field, field_init_shorthand, file, + float_to_int_unchecked, + floorf64, + floorf32, + fmaf32, + fmaf64, fmt, fmt_internals, + fmul_fast, fn_must_use, forbid, + forget, format_args, format_args_nl, format_args_capture, + frem_fast, from, From, from_desugaring, @@ -352,6 +383,7 @@ symbols! { from_ok, from_usize, from_trait, + fsub_fast, fundamental, future, Future, @@ -448,6 +480,12 @@ symbols! { llvm_asm, local_inner_macros, log_syntax, + logf32, + logf64, + log10f32, + log10f64, + log2f32, + log2f64, loop_break_value, macro_at_most_once_rep, macro_escape, @@ -475,10 +513,16 @@ symbols! { message, meta, min_align_of, + min_align_of_val, min_const_fn, min_const_unsafe_fn, min_specialization, + minnumf32, + minnumf64, + maxnumf32, + maxnumf64, mips_target_feature, + miri_start_panic, mmx_target_feature, module, module_path, @@ -491,6 +535,8 @@ symbols! { naked, naked_functions, name, + nearbyintf32, + nearbyintf64, needs_allocator, needs_drop, needs_panic_runtime, @@ -518,6 +564,7 @@ symbols! { None, non_exhaustive, non_modrs_mods, + nontemporal_store, nontrapping_fptoint: "nontrapping-fptoint", noreturn, no_niche, @@ -577,8 +624,16 @@ symbols! { poll, Poll, powerpc_target_feature, + powf32, + powf64, + powif32, + powif64, precise_pointer_size_matching, pref_align_of, + prefetch_read_data, + prefetch_read_instruction, + prefetch_write_data, + prefetch_write_instruction, prelude, prelude_import, preserves_flags, @@ -640,10 +695,14 @@ symbols! { Result, Return, rhs, + rintf32, + rintf64, riscv_target_feature, rlib, rotate_left, rotate_right, + roundf32, + roundf64, rt, rtm_target_feature, rust, @@ -726,14 +785,19 @@ symbols! { simd_ffi, simd_insert, since, + sinf32, + sinf64, size, size_of, + size_of_val, slice_patterns, slicing_syntax, soft, Some, specialization, speed, + sqrtf32, + sqrtf64, sse4a_target_feature, stable, staged_api, @@ -787,6 +851,8 @@ symbols! { transparent_enums, transparent_unions, trivial_bounds, + truncf32, + truncf64, Try, try_blocks, try_trait, @@ -809,6 +875,8 @@ symbols! { u32, u64, u8, + unaligned_volatile_load, + unaligned_volatile_store, unboxed_closures, unchecked_add, unchecked_div, @@ -824,6 +892,7 @@ symbols! { universal_impl_trait, unlikely, unmarked_api, + unreachable, unreachable_code, unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, @@ -843,12 +912,21 @@ symbols! { val, var, variant_count, + va_arg, + va_copy, + va_end, + va_start, vec, Vec, version, vis, visible_private_types, volatile, + volatile_copy_memory, + volatile_copy_nonoverlapping_memory, + volatile_load, + volatile_set_memory, + volatile_store, warn, wasm_import_module, wasm_target_feature, @@ -858,6 +936,7 @@ symbols! { wrapping_add, wrapping_sub, wrapping_mul, + write_bytes, Yield, } } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index da5b9f18c0719..9b3b4a67650a2 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -5,10 +5,11 @@ use crate::require_same_types; use rustc_errors::struct_span_err; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; use std::iter; @@ -16,14 +17,13 @@ use std::iter; fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, it: &hir::ForeignItem<'_>, + def_id: DefId, n_tps: usize, abi: Abi, safety: hir::Unsafety, inputs: Vec>, output: Ty<'tcx>, ) { - let def_id = tcx.hir().local_def_id(it.hir_id); - match it.kind { hir::ForeignItemKind::Fn(..) => {} _ => { @@ -67,15 +67,43 @@ fn equate_intrinsic_type<'tcx>( } /// Returns `true` if the given intrinsic is unsafe to call or not. -pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { +pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { match intrinsic { - "abort" | "size_of" | "min_align_of" | "needs_drop" | "caller_location" | "size_of_val" - | "min_align_of_val" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" - | "wrapping_add" | "wrapping_sub" | "wrapping_mul" | "saturating_add" - | "saturating_sub" | "rotate_left" | "rotate_right" | "ctpop" | "ctlz" | "cttz" - | "bswap" | "bitreverse" | "discriminant_value" | "type_id" | "likely" | "unlikely" - | "ptr_guaranteed_eq" | "ptr_guaranteed_ne" | "minnumf32" | "minnumf64" | "maxnumf32" - | "rustc_peek" | "maxnumf64" | "type_name" | "variant_count" => hir::Unsafety::Normal, + sym::abort + | sym::size_of + | sym::min_align_of + | sym::needs_drop + | sym::caller_location + | sym::size_of_val + | sym::min_align_of_val + | sym::add_with_overflow + | sym::sub_with_overflow + | sym::mul_with_overflow + | sym::wrapping_add + | sym::wrapping_sub + | sym::wrapping_mul + | sym::saturating_add + | sym::saturating_sub + | sym::rotate_left + | sym::rotate_right + | sym::ctpop + | sym::ctlz + | sym::cttz + | sym::bswap + | sym::bitreverse + | sym::discriminant_value + | sym::type_id + | sym::likely + | sym::unlikely + | sym::ptr_guaranteed_eq + | sym::ptr_guaranteed_ne + | sym::minnumf32 + | sym::minnumf64 + | sym::maxnumf32 + | sym::rustc_peek + | sym::maxnumf64 + | sym::type_name + | sym::variant_count => hir::Unsafety::Normal, _ => hir::Unsafety::Unsafe, } } @@ -84,7 +112,9 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { /// and in libcore/intrinsics.rs pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); - let name = it.ident.as_str(); + let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id(); + let intrinsic_name = tcx.item_name(def_id); + let name_str = intrinsic_name.as_str(); let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { @@ -98,8 +128,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }) }; - let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") { - let split: Vec<&str> = name.split('_').collect(); + let (n_tps, inputs, output, unsafety) = if name_str.starts_with("atomic_") { + let split: Vec<&str> = name_str.split('_').collect(); assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format"); //We only care about the operation here @@ -129,32 +159,30 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { } }; (n_tps, inputs, output, hir::Unsafety::Unsafe) - } else if &name[..] == "abort" { - (0, Vec::new(), tcx.types.never, hir::Unsafety::Normal) - } else if &name[..] == "unreachable" { - (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe) } else { - let unsafety = intrinsic_operation_unsafety(&name[..]); - let (n_tps, inputs, output) = match &name[..] { - "breakpoint" => (0, Vec::new(), tcx.mk_unit()), - "size_of" | "pref_align_of" | "min_align_of" | "variant_count" => { + let unsafety = intrinsic_operation_unsafety(intrinsic_name); + let (n_tps, inputs, output) = match intrinsic_name { + sym::abort => (0, Vec::new(), tcx.types.never), + sym::unreachable => (0, Vec::new(), tcx.types.never), + sym::breakpoint => (0, Vec::new(), tcx.mk_unit()), + sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => { (1, Vec::new(), tcx.types.usize) } - "size_of_val" | "min_align_of_val" => { + sym::size_of_val | sym::min_align_of_val => { (1, vec![tcx.mk_imm_ptr(param(0))], tcx.types.usize) } - "rustc_peek" => (1, vec![param(0)], param(0)), - "caller_location" => (0, vec![], tcx.caller_location_ty()), - "assert_inhabited" | "assert_zero_valid" | "assert_uninit_valid" => { + sym::rustc_peek => (1, vec![param(0)], param(0)), + sym::caller_location => (0, vec![], tcx.caller_location_ty()), + sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => { (1, Vec::new(), tcx.mk_unit()) } - "forget" => (1, vec![param(0)], tcx.mk_unit()), - "transmute" => (2, vec![param(0)], param(1)), - "move_val_init" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), - "prefetch_read_data" - | "prefetch_write_data" - | "prefetch_read_instruction" - | "prefetch_write_instruction" => ( + sym::forget => (1, vec![param(0)], tcx.mk_unit()), + sym::transmute => (2, vec![param(0)], param(1)), + sym::move_val_init => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), + sym::prefetch_read_data + | sym::prefetch_write_data + | sym::prefetch_read_instruction + | sym::prefetch_write_instruction => ( 1, vec![ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }), @@ -162,12 +190,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], tcx.mk_unit(), ), - "drop_in_place" => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()), - "needs_drop" => (1, Vec::new(), tcx.types.bool), + sym::drop_in_place => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()), + sym::needs_drop => (1, Vec::new(), tcx.types.bool), - "type_name" => (1, Vec::new(), tcx.mk_static_str()), - "type_id" => (1, Vec::new(), tcx.types.u64), - "offset" | "arith_offset" => ( + sym::type_name => (1, Vec::new(), tcx.mk_static_str()), + sym::type_id => (1, Vec::new(), tcx.types.u64), + sym::offset | sym::arith_offset => ( 1, vec![ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }), @@ -175,7 +203,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }), ), - "copy" | "copy_nonoverlapping" => ( + sym::copy | sym::copy_nonoverlapping => ( 1, vec![ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }), @@ -184,7 +212,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], tcx.mk_unit(), ), - "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => ( + sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => ( 1, vec![ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }), @@ -193,7 +221,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], tcx.mk_unit(), ), - "write_bytes" | "volatile_set_memory" => ( + sym::write_bytes | sym::volatile_set_memory => ( 1, vec![ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }), @@ -202,93 +230,98 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], tcx.mk_unit(), ), - "sqrtf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "sqrtf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "powif32" => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32), - "powif64" => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64), - "sinf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "sinf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "cosf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "cosf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "powf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - "powf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - "expf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "expf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "exp2f32" => (0, vec![tcx.types.f32], tcx.types.f32), - "exp2f64" => (0, vec![tcx.types.f64], tcx.types.f64), - "logf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "logf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "log10f32" => (0, vec![tcx.types.f32], tcx.types.f32), - "log10f64" => (0, vec![tcx.types.f64], tcx.types.f64), - "log2f32" => (0, vec![tcx.types.f32], tcx.types.f32), - "log2f64" => (0, vec![tcx.types.f64], tcx.types.f64), - "fmaf32" => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32), - "fmaf64" => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64), - "fabsf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "fabsf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "minnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - "minnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - "maxnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - "maxnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - "copysignf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - "copysignf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - "floorf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "floorf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "ceilf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "ceilf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "truncf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "truncf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "rintf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "rintf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "nearbyintf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "nearbyintf64" => (0, vec![tcx.types.f64], tcx.types.f64), - "roundf32" => (0, vec![tcx.types.f32], tcx.types.f32), - "roundf64" => (0, vec![tcx.types.f64], tcx.types.f64), - - "volatile_load" | "unaligned_volatile_load" => { + sym::sqrtf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::sqrtf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::powif32 => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32), + sym::powif64 => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64), + sym::sinf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::sinf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::cosf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::cosf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::powf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::powf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::expf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::expf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::exp2f32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::exp2f64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::logf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::logf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::log10f32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::log10f64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::log2f32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::log2f64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::fmaf32 => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::fmaf64 => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::fabsf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::fabsf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::minnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::minnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::maxnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::maxnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::copysignf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::copysignf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::floorf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::floorf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::ceilf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::ceilf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::truncf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::truncf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::rintf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::rintf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::nearbyintf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::nearbyintf64 => (0, vec![tcx.types.f64], tcx.types.f64), + sym::roundf32 => (0, vec![tcx.types.f32], tcx.types.f32), + sym::roundf64 => (0, vec![tcx.types.f64], tcx.types.f64), + + sym::volatile_load | sym::unaligned_volatile_load => { (1, vec![tcx.mk_imm_ptr(param(0))], param(0)) } - "volatile_store" | "unaligned_volatile_store" => { + sym::volatile_store | sym::unaligned_volatile_store => { (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()) } - "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "bswap" - | "bitreverse" => (1, vec![param(0)], param(0)), + sym::ctpop + | sym::ctlz + | sym::ctlz_nonzero + | sym::cttz + | sym::cttz_nonzero + | sym::bswap + | sym::bitreverse => (1, vec![param(0)], param(0)), - "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => { + sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { (1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool])) } - "ptr_guaranteed_eq" | "ptr_guaranteed_ne" => { + sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => { (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.bool) } - "ptr_offset_from" => { + sym::ptr_offset_from => { (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize) } - "unchecked_div" | "unchecked_rem" | "exact_div" => { + sym::unchecked_div | sym::unchecked_rem | sym::exact_div => { (1, vec![param(0), param(0)], param(0)) } - "unchecked_shl" | "unchecked_shr" | "rotate_left" | "rotate_right" => { + sym::unchecked_shl | sym::unchecked_shr | sym::rotate_left | sym::rotate_right => { (1, vec![param(0), param(0)], param(0)) } - "unchecked_add" | "unchecked_sub" | "unchecked_mul" => { + sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => { (1, vec![param(0), param(0)], param(0)) } - "wrapping_add" | "wrapping_sub" | "wrapping_mul" => { + sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => { (1, vec![param(0), param(0)], param(0)) } - "saturating_add" | "saturating_sub" => (1, vec![param(0), param(0)], param(0)), - "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { + sym::saturating_add | sym::saturating_sub => (1, vec![param(0), param(0)], param(0)), + sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => { (1, vec![param(0), param(0)], param(0)) } - "float_to_int_unchecked" => (2, vec![param(0)], param(1)), + sym::float_to_int_unchecked => (2, vec![param(0)], param(1)), - "assume" => (0, vec![tcx.types.bool], tcx.mk_unit()), - "likely" => (0, vec![tcx.types.bool], tcx.types.bool), - "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool), + sym::assume => (0, vec![tcx.types.bool], tcx.mk_unit()), + sym::likely => (0, vec![tcx.types.bool], tcx.types.bool), + sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool), - "discriminant_value" => { + sym::discriminant_value => { let assoc_items = tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; @@ -303,7 +336,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ) } - "try" => { + kw::Try => { let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8); let try_fn_ty = ty::Binder::bind(tcx.mk_fn_sig( iter::once(mut_u8), @@ -326,12 +359,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ) } - "va_start" | "va_end" => match mk_va_list_ty(hir::Mutability::Mut) { + sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) { Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()), None => bug!("`va_list` language item needed for C-variadic intrinsics"), }, - "va_copy" => match mk_va_list_ty(hir::Mutability::Not) { + sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) { Some((va_list_ref_ty, va_list_ty)) => { let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty); (0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit()) @@ -339,38 +372,38 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { None => bug!("`va_list` language item needed for C-variadic intrinsics"), }, - "va_arg" => match mk_va_list_ty(hir::Mutability::Mut) { + sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) { Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)), None => bug!("`va_list` language item needed for C-variadic intrinsics"), }, - "nontemporal_store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), + sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), - "miri_start_panic" => { + sym::miri_start_panic => { // FIXME - the relevant types aren't lang items, // so it's not trivial to check this return; } - "count_code_region" => { + sym::count_code_region => { (0, vec![tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit()) } - "coverage_counter_add" | "coverage_counter_subtract" => ( + sym::coverage_counter_add | sym::coverage_counter_subtract => ( 0, vec![tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit(), ), - "coverage_unreachable" => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()), + sym::coverage_unreachable => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()), - ref other => { + other => { struct_span_err!( tcx.sess, it.span, E0093, "unrecognized intrinsic function: `{}`", - *other + other, ) .span_label(it.span, "unrecognized intrinsic") .emit(); @@ -379,7 +412,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, inputs, output, unsafety) }; - equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, unsafety, inputs, output) + equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -389,6 +422,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) tcx.mk_ty_param(n, name) }; + let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id(); let name = it.ident.as_str(); let (n_tps, inputs, output) = match &*name { @@ -463,6 +497,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) equate_intrinsic_type( tcx, it, + def_id, n_tps, Abi::PlatformIntrinsic, hir::Unsafety::Unsafe, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8920203e6af40..cc491c527db0b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2063,7 +2063,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( ident: Ident, ) -> ty::PolyFnSig<'tcx> { let unsafety = if abi == abi::Abi::RustIntrinsic { - intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str()) + intrinsic_operation_unsafety(tcx.item_name(def_id)) } else { hir::Unsafety::Unsafe };