mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-21 12:07:31 +00:00
Auto merge of #72021 - Dylan-DPC:rollup-1w61ihk, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #71581 (Unify lints handling in rustdoc) - #71710 (Test for zero-sized function items not ICEing) - #71970 (Improve bitcode generation for Apple platforms) - #71975 (Reduce `TypedArena` creations in `check_match`.) - #72003 (allow wasm target for rustc-ap-rustc_span) - #72017 (Work around ICEs during cross-compilation for target, ast, & attr) Failed merges: r? @ghost
This commit is contained in:
commit
7ebd87a7a1
@ -19,6 +19,10 @@
|
|||||||
#![feature(unicode_internals)]
|
#![feature(unicode_internals)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
// FIXME(#56935): Work around ICEs during cross-compilation.
|
||||||
|
#[allow(unused)]
|
||||||
|
extern crate rustc_macros;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! unwrap_or {
|
macro_rules! unwrap_or {
|
||||||
($opt:expr, $default:expr) => {
|
($opt:expr, $default:expr) => {
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
#![feature(or_patterns)]
|
#![feature(or_patterns)]
|
||||||
|
|
||||||
|
// FIXME(#56935): Work around ICEs during cross-compilation.
|
||||||
|
#[allow(unused)]
|
||||||
|
extern crate rustc_macros;
|
||||||
|
|
||||||
mod builtin;
|
mod builtin;
|
||||||
|
|
||||||
pub use builtin::*;
|
pub use builtin::*;
|
||||||
|
@ -651,10 +651,8 @@ pub(crate) unsafe fn codegen(
|
|||||||
"LLVM_module_codegen_embed_bitcode",
|
"LLVM_module_codegen_embed_bitcode",
|
||||||
&module.name[..],
|
&module.name[..],
|
||||||
);
|
);
|
||||||
embed_bitcode(cgcx, llcx, llmod, Some(data));
|
embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
|
||||||
}
|
}
|
||||||
} else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
|
|
||||||
embed_bitcode(cgcx, llcx, llmod, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.emit_ir {
|
if config.emit_ir {
|
||||||
@ -777,8 +775,8 @@ pub(crate) unsafe fn codegen(
|
|||||||
/// * __LLVM,__cmdline
|
/// * __LLVM,__cmdline
|
||||||
///
|
///
|
||||||
/// It appears *both* of these sections are necessary to get the linker to
|
/// It appears *both* of these sections are necessary to get the linker to
|
||||||
/// recognize what's going on. For us though we just always throw in an empty
|
/// recognize what's going on. A suitable cmdline value is taken from the
|
||||||
/// cmdline section.
|
/// target spec.
|
||||||
///
|
///
|
||||||
/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
|
/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
|
||||||
/// embed an empty section.
|
/// embed an empty section.
|
||||||
@ -789,9 +787,10 @@ unsafe fn embed_bitcode(
|
|||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
llcx: &llvm::Context,
|
llcx: &llvm::Context,
|
||||||
llmod: &llvm::Module,
|
llmod: &llvm::Module,
|
||||||
bitcode: Option<&[u8]>,
|
cmdline: &str,
|
||||||
|
bitcode: &[u8],
|
||||||
) {
|
) {
|
||||||
let llconst = common::bytes_in_context(llcx, bitcode.unwrap_or(&[]));
|
let llconst = common::bytes_in_context(llcx, bitcode);
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
common::val_ty(llconst),
|
common::val_ty(llconst),
|
||||||
@ -800,14 +799,15 @@ unsafe fn embed_bitcode(
|
|||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
|
|
||||||
let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
|
let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
|
||||||
|| cgcx.opts.target_triple.triple().contains("-darwin");
|
|| cgcx.opts.target_triple.triple().contains("-darwin")
|
||||||
|
|| cgcx.opts.target_triple.triple().contains("-tvos");
|
||||||
|
|
||||||
let section = if is_apple { "__LLVM,__bitcode\0" } else { ".llvmbc\0" };
|
let section = if is_apple { "__LLVM,__bitcode\0" } else { ".llvmbc\0" };
|
||||||
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
|
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
|
||||||
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
|
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
|
||||||
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
|
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
|
||||||
|
|
||||||
let llconst = common::bytes_in_context(llcx, &[]);
|
let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
common::val_ty(llconst),
|
common::val_ty(llconst),
|
||||||
|
@ -68,10 +68,6 @@ pub enum BitcodeSection {
|
|||||||
// No bitcode section.
|
// No bitcode section.
|
||||||
None,
|
None,
|
||||||
|
|
||||||
// An empty bitcode section (to placate tools such as the iOS linker that
|
|
||||||
// require this section even if they don't use it).
|
|
||||||
Marker,
|
|
||||||
|
|
||||||
// A full, uncompressed bitcode section.
|
// A full, uncompressed bitcode section.
|
||||||
Full,
|
Full,
|
||||||
}
|
}
|
||||||
@ -101,6 +97,7 @@ pub struct ModuleConfig {
|
|||||||
pub emit_ir: bool,
|
pub emit_ir: bool,
|
||||||
pub emit_asm: bool,
|
pub emit_asm: bool,
|
||||||
pub emit_obj: EmitObj,
|
pub emit_obj: EmitObj,
|
||||||
|
pub bc_cmdline: String,
|
||||||
|
|
||||||
// Miscellaneous flags. These are mostly copied from command-line
|
// Miscellaneous flags. These are mostly copied from command-line
|
||||||
// options.
|
// options.
|
||||||
@ -147,14 +144,8 @@ impl ModuleConfig {
|
|||||||
|| sess.opts.cg.linker_plugin_lto.enabled()
|
|| sess.opts.cg.linker_plugin_lto.enabled()
|
||||||
{
|
{
|
||||||
EmitObj::Bitcode
|
EmitObj::Bitcode
|
||||||
} else if need_crate_bitcode_for_rlib(sess) {
|
} else if need_bitcode_in_object(sess) {
|
||||||
let force_full = need_crate_bitcode_for_rlib(sess);
|
EmitObj::ObjectCode(BitcodeSection::Full)
|
||||||
match sess.opts.optimize {
|
|
||||||
config::OptLevel::No | config::OptLevel::Less if !force_full => {
|
|
||||||
EmitObj::ObjectCode(BitcodeSection::Marker)
|
|
||||||
}
|
|
||||||
_ => EmitObj::ObjectCode(BitcodeSection::Full),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
EmitObj::ObjectCode(BitcodeSection::None)
|
EmitObj::ObjectCode(BitcodeSection::None)
|
||||||
};
|
};
|
||||||
@ -211,6 +202,7 @@ impl ModuleConfig {
|
|||||||
false
|
false
|
||||||
),
|
),
|
||||||
emit_obj,
|
emit_obj,
|
||||||
|
bc_cmdline: sess.target.target.options.bitcode_llvm_cmdline.clone(),
|
||||||
|
|
||||||
verify_llvm_ir: sess.verify_llvm_ir(),
|
verify_llvm_ir: sess.verify_llvm_ir(),
|
||||||
no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes,
|
no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes,
|
||||||
@ -372,10 +364,12 @@ pub struct CompiledModules {
|
|||||||
pub allocator_module: Option<CompiledModule>,
|
pub allocator_module: Option<CompiledModule>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
|
fn need_bitcode_in_object(sess: &Session) -> bool {
|
||||||
sess.opts.cg.embed_bitcode
|
let requested_for_rlib = sess.opts.cg.embed_bitcode
|
||||||
&& sess.crate_types.borrow().contains(&CrateType::Rlib)
|
&& sess.crate_types.borrow().contains(&CrateType::Rlib)
|
||||||
&& sess.opts.output_types.contains_key(&OutputType::Exe)
|
&& sess.opts.output_types.contains_key(&OutputType::Exe);
|
||||||
|
let forced_by_target = sess.target.target.options.forces_embed_bitcode;
|
||||||
|
requested_for_rlib || forced_by_target
|
||||||
}
|
}
|
||||||
|
|
||||||
fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
|
fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
|
||||||
|
@ -580,22 +580,11 @@ crate struct MatchCheckCtxt<'a, 'tcx> {
|
|||||||
/// outside it's module and should not be matchable with an empty match
|
/// outside it's module and should not be matchable with an empty match
|
||||||
/// statement.
|
/// statement.
|
||||||
crate module: DefId,
|
crate module: DefId,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
crate param_env: ty::ParamEnv<'tcx>,
|
||||||
crate pattern_arena: &'a TypedArena<Pat<'tcx>>,
|
crate pattern_arena: &'a TypedArena<Pat<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
||||||
crate fn create_and_enter<R>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
module: DefId,
|
|
||||||
f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>) -> R,
|
|
||||||
) -> R {
|
|
||||||
let pattern_arena = TypedArena::default();
|
|
||||||
|
|
||||||
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
||||||
if self.tcx.features().exhaustive_patterns {
|
if self.tcx.features().exhaustive_patterns {
|
||||||
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
|
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use super::_match::Usefulness::*;
|
use super::_match::Usefulness::*;
|
||||||
use super::_match::WitnessPreference::*;
|
use super::_match::WitnessPreference::*;
|
||||||
use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack};
|
use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack};
|
||||||
|
|
||||||
use super::{PatCtxt, PatKind, PatternError};
|
use super::{PatCtxt, PatKind, PatternError};
|
||||||
|
|
||||||
|
use arena::TypedArena;
|
||||||
use rustc_ast::ast::Mutability;
|
use rustc_ast::ast::Mutability;
|
||||||
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -17,7 +17,6 @@ use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERN
|
|||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
|
crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
@ -26,8 +25,12 @@ crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
|
|||||||
Some(id) => tcx.hir().body_owned_by(tcx.hir().as_local_hir_id(id)),
|
Some(id) => tcx.hir().body_owned_by(tcx.hir().as_local_hir_id(id)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut visitor =
|
let mut visitor = MatchVisitor {
|
||||||
MatchVisitor { tcx, tables: tcx.body_tables(body_id), param_env: tcx.param_env(def_id) };
|
tcx,
|
||||||
|
tables: tcx.body_tables(body_id),
|
||||||
|
param_env: tcx.param_env(def_id),
|
||||||
|
pattern_arena: TypedArena::default(),
|
||||||
|
};
|
||||||
visitor.visit_body(tcx.hir().body(body_id));
|
visitor.visit_body(tcx.hir().body(body_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +42,7 @@ struct MatchVisitor<'a, 'tcx> {
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
pattern_arena: TypedArena<super::Pat<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
|
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
|
||||||
@ -143,9 +147,13 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
(pattern, pattern_ty)
|
(pattern, pattern_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_in_cx(&self, hir_id: HirId, f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>)) {
|
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'_, 'tcx> {
|
||||||
let module = self.tcx.parent_module(hir_id);
|
MatchCheckCtxt {
|
||||||
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module.to_def_id(), |cx| f(cx));
|
tcx: self.tcx,
|
||||||
|
param_env: self.param_env,
|
||||||
|
module: self.tcx.parent_module(hir_id).to_def_id(),
|
||||||
|
pattern_arena: &self.pattern_arena,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_match(
|
fn check_match(
|
||||||
@ -159,13 +167,14 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
self.check_patterns(arm.guard.is_some(), &arm.pat);
|
self.check_patterns(arm.guard.is_some(), &arm.pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.check_in_cx(scrut.hir_id, |ref mut cx| {
|
let mut cx = self.new_cx(scrut.hir_id);
|
||||||
|
|
||||||
let mut have_errors = false;
|
let mut have_errors = false;
|
||||||
|
|
||||||
let inlined_arms: Vec<_> = arms
|
let inlined_arms: Vec<_> = arms
|
||||||
.iter()
|
.iter()
|
||||||
.map(|hir::Arm { pat, guard, .. }| {
|
.map(|hir::Arm { pat, guard, .. }| {
|
||||||
(self.lower_pattern(cx, pat, &mut have_errors).0, pat.hir_id, guard.is_some())
|
(self.lower_pattern(&mut cx, pat, &mut have_errors).0, pat.hir_id, guard.is_some())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -175,23 +184,23 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fourth, check for unreachable arms.
|
// Fourth, check for unreachable arms.
|
||||||
let matrix = check_arms(cx, &inlined_arms, source);
|
let matrix = check_arms(&mut cx, &inlined_arms, source);
|
||||||
|
|
||||||
// Fifth, check if the match is exhaustive.
|
// Fifth, check if the match is exhaustive.
|
||||||
let scrut_ty = self.tables.node_type(scrut.hir_id);
|
let scrut_ty = self.tables.node_type(scrut.hir_id);
|
||||||
// Note: An empty match isn't the same as an empty matrix for diagnostics purposes,
|
// Note: An empty match isn't the same as an empty matrix for diagnostics purposes,
|
||||||
// since an empty matrix can occur when there are arms, if those arms all have guards.
|
// since an empty matrix can occur when there are arms, if those arms all have guards.
|
||||||
let is_empty_match = inlined_arms.is_empty();
|
let is_empty_match = inlined_arms.is_empty();
|
||||||
check_exhaustive(cx, scrut_ty, scrut.span, &matrix, scrut.hir_id, is_empty_match);
|
check_exhaustive(&mut cx, scrut_ty, scrut.span, &matrix, scrut.hir_id, is_empty_match);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||||
self.check_in_cx(pat.hir_id, |ref mut cx| {
|
let mut cx = self.new_cx(pat.hir_id);
|
||||||
let (pattern, pattern_ty) = self.lower_pattern(cx, pat, &mut false);
|
|
||||||
|
let (pattern, pattern_ty) = self.lower_pattern(&mut cx, pat, &mut false);
|
||||||
let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
|
let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
|
||||||
|
|
||||||
let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) {
|
let witnesses = match check_not_useful(&mut cx, pattern_ty, &pats, pat.hir_id) {
|
||||||
Ok(_) => return,
|
Ok(_) => return,
|
||||||
Err(err) => err,
|
Err(err) => err,
|
||||||
};
|
};
|
||||||
@ -213,10 +222,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
err.span_label(
|
err.span_label(pat.span, pattern_not_covered_label(&witnesses, &joined_patterns));
|
||||||
pat.span,
|
|
||||||
pattern_not_covered_label(&witnesses, &joined_patterns),
|
|
||||||
);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -240,10 +246,9 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
adt_defined_here(cx, &mut err, pattern_ty, &witnesses);
|
adt_defined_here(&mut cx, &mut err, pattern_ty, &witnesses);
|
||||||
err.note(&format!("the matched value is of type `{}`", pattern_ty));
|
err.note(&format!("the matched value is of type `{}`", pattern_ty));
|
||||||
err.emit();
|
err.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
|
|
||||||
|
// FIXME(#56935): Work around ICEs during cross-compilation.
|
||||||
|
#[allow(unused)]
|
||||||
|
extern crate rustc_macros;
|
||||||
|
|
||||||
use rustc_data_structures::AtomicRef;
|
use rustc_data_structures::AtomicRef;
|
||||||
use rustc_macros::HashStable_Generic;
|
use rustc_macros::HashStable_Generic;
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
|
|
||||||
|
// FIXME(#56935): Work around ICEs during cross-compilation.
|
||||||
|
#[allow(unused)]
|
||||||
|
extern crate rustc_macros;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
@ -19,6 +19,18 @@ pub fn target() -> TargetResult {
|
|||||||
eliminate_frame_pointer: false,
|
eliminate_frame_pointer: false,
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
|
forces_embed_bitcode: true,
|
||||||
|
// Taken from a clang build on Xcode 11.4.1.
|
||||||
|
// These arguments are not actually invoked - they just have
|
||||||
|
// to look right to pass App Store validation.
|
||||||
|
bitcode_llvm_cmdline: "-triple\0\
|
||||||
|
arm64-apple-ios11.0.0\0\
|
||||||
|
-emit-obj\0\
|
||||||
|
-disable-llvm-passes\0\
|
||||||
|
-target-abi\0\
|
||||||
|
darwinpcs\0\
|
||||||
|
-Os\0"
|
||||||
|
.to_string(),
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -19,6 +19,7 @@ pub fn target() -> TargetResult {
|
|||||||
eliminate_frame_pointer: false,
|
eliminate_frame_pointer: false,
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
|
forces_embed_bitcode: true,
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -783,6 +783,10 @@ pub struct TargetOptions {
|
|||||||
// If we give emcc .o files that are actually .bc files it
|
// If we give emcc .o files that are actually .bc files it
|
||||||
// will 'just work'.
|
// will 'just work'.
|
||||||
pub obj_is_bitcode: bool,
|
pub obj_is_bitcode: bool,
|
||||||
|
/// Whether the target requires that emitted object code includes bitcode.
|
||||||
|
pub forces_embed_bitcode: bool,
|
||||||
|
/// Content of the LLVM cmdline section associated with embedded bitcode.
|
||||||
|
pub bitcode_llvm_cmdline: String,
|
||||||
|
|
||||||
/// Don't use this field; instead use the `.min_atomic_width()` method.
|
/// Don't use this field; instead use the `.min_atomic_width()` method.
|
||||||
pub min_atomic_width: Option<u64>,
|
pub min_atomic_width: Option<u64>,
|
||||||
@ -939,6 +943,8 @@ impl Default for TargetOptions {
|
|||||||
allow_asm: true,
|
allow_asm: true,
|
||||||
has_elf_tls: false,
|
has_elf_tls: false,
|
||||||
obj_is_bitcode: false,
|
obj_is_bitcode: false,
|
||||||
|
forces_embed_bitcode: false,
|
||||||
|
bitcode_llvm_cmdline: String::new(),
|
||||||
min_atomic_width: None,
|
min_atomic_width: None,
|
||||||
max_atomic_width: None,
|
max_atomic_width: None,
|
||||||
atomic_cas: true,
|
atomic_cas: true,
|
||||||
@ -1278,6 +1284,8 @@ impl Target {
|
|||||||
key!(main_needs_argc_argv, bool);
|
key!(main_needs_argc_argv, bool);
|
||||||
key!(has_elf_tls, bool);
|
key!(has_elf_tls, bool);
|
||||||
key!(obj_is_bitcode, bool);
|
key!(obj_is_bitcode, bool);
|
||||||
|
key!(forces_embed_bitcode, bool);
|
||||||
|
key!(bitcode_llvm_cmdline);
|
||||||
key!(max_atomic_width, Option<u64>);
|
key!(max_atomic_width, Option<u64>);
|
||||||
key!(min_atomic_width, Option<u64>);
|
key!(min_atomic_width, Option<u64>);
|
||||||
key!(atomic_cas, bool);
|
key!(atomic_cas, bool);
|
||||||
@ -1505,6 +1513,8 @@ impl ToJson for Target {
|
|||||||
target_option_val!(main_needs_argc_argv);
|
target_option_val!(main_needs_argc_argv);
|
||||||
target_option_val!(has_elf_tls);
|
target_option_val!(has_elf_tls);
|
||||||
target_option_val!(obj_is_bitcode);
|
target_option_val!(obj_is_bitcode);
|
||||||
|
target_option_val!(forces_embed_bitcode);
|
||||||
|
target_option_val!(bitcode_llvm_cmdline);
|
||||||
target_option_val!(min_atomic_width);
|
target_option_val!(min_atomic_width);
|
||||||
target_option_val!(max_atomic_width);
|
target_option_val!(max_atomic_width);
|
||||||
target_option_val!(atomic_cas);
|
target_option_val!(atomic_cas);
|
||||||
|
@ -204,6 +204,56 @@ pub fn new_handler(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function is used to setup the lint initialization. By default, in rustdoc, everything
|
||||||
|
/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
|
||||||
|
/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTE" lint is activated in both
|
||||||
|
/// modes.
|
||||||
|
///
|
||||||
|
/// A little detail easy to forget is that there is a way to set the lint level for all lints
|
||||||
|
/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
|
||||||
|
/// inside this function.
|
||||||
|
///
|
||||||
|
/// It returns a tuple containing:
|
||||||
|
/// * Vector of tuples of lints' name and their associated "max" level
|
||||||
|
/// * HashMap of lint id with their associated "max" level
|
||||||
|
pub fn init_lints<F>(
|
||||||
|
mut whitelisted_lints: Vec<String>,
|
||||||
|
lint_opts: Vec<(String, lint::Level)>,
|
||||||
|
filter_call: F,
|
||||||
|
) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
|
||||||
|
where
|
||||||
|
F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
|
||||||
|
{
|
||||||
|
let warnings_lint_name = lint::builtin::WARNINGS.name;
|
||||||
|
|
||||||
|
whitelisted_lints.push(warnings_lint_name.to_owned());
|
||||||
|
whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
|
||||||
|
|
||||||
|
let lints = || {
|
||||||
|
lint::builtin::HardwiredLints::get_lints()
|
||||||
|
.into_iter()
|
||||||
|
.chain(rustc_lint::SoftLints::get_lints().into_iter())
|
||||||
|
};
|
||||||
|
|
||||||
|
let lint_opts = lints()
|
||||||
|
.filter_map(|lint| if lint.name == warnings_lint_name { None } else { filter_call(lint) })
|
||||||
|
.chain(lint_opts.into_iter())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let lint_caps = lints()
|
||||||
|
.filter_map(|lint| {
|
||||||
|
// We don't want to whitelist *all* lints so let's
|
||||||
|
// ignore those ones.
|
||||||
|
if whitelisted_lints.iter().any(|l| lint.name == l) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((lint::LintId::of(lint), lint::Allow))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
(lint_opts, lint_caps)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) {
|
pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) {
|
||||||
// Parse, resolve, and typecheck the given crate.
|
// Parse, resolve, and typecheck the given crate.
|
||||||
|
|
||||||
@ -247,7 +297,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||||||
let input = Input::File(input);
|
let input = Input::File(input);
|
||||||
|
|
||||||
let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
|
let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
|
||||||
let warnings_lint_name = lint::builtin::WARNINGS.name;
|
|
||||||
let missing_docs = rustc_lint::builtin::MISSING_DOCS.name;
|
let missing_docs = rustc_lint::builtin::MISSING_DOCS.name;
|
||||||
let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name;
|
let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name;
|
||||||
let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
|
let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
|
||||||
@ -256,8 +305,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||||||
|
|
||||||
// In addition to those specific lints, we also need to whitelist those given through
|
// In addition to those specific lints, we also need to whitelist those given through
|
||||||
// command line, otherwise they'll get ignored and we don't want that.
|
// command line, otherwise they'll get ignored and we don't want that.
|
||||||
let mut whitelisted_lints = vec![
|
let whitelisted_lints = vec![
|
||||||
warnings_lint_name.to_owned(),
|
|
||||||
intra_link_resolution_failure_name.to_owned(),
|
intra_link_resolution_failure_name.to_owned(),
|
||||||
missing_docs.to_owned(),
|
missing_docs.to_owned(),
|
||||||
missing_doc_example.to_owned(),
|
missing_doc_example.to_owned(),
|
||||||
@ -266,39 +314,15 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||||||
invalid_codeblock_attribute_name.to_owned(),
|
invalid_codeblock_attribute_name.to_owned(),
|
||||||
];
|
];
|
||||||
|
|
||||||
whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
|
let (lint_opts, lint_caps) = init_lints(whitelisted_lints, lint_opts, |lint| {
|
||||||
|
if lint.name == intra_link_resolution_failure_name
|
||||||
let lints = || {
|
|
||||||
lint::builtin::HardwiredLints::get_lints()
|
|
||||||
.into_iter()
|
|
||||||
.chain(rustc_lint::SoftLints::get_lints().into_iter())
|
|
||||||
};
|
|
||||||
|
|
||||||
let lint_opts = lints()
|
|
||||||
.filter_map(|lint| {
|
|
||||||
if lint.name == warnings_lint_name
|
|
||||||
|| lint.name == intra_link_resolution_failure_name
|
|
||||||
|| lint.name == invalid_codeblock_attribute_name
|
|| lint.name == invalid_codeblock_attribute_name
|
||||||
{
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((lint.name_lower(), lint::Allow))
|
Some((lint.name_lower(), lint::Allow))
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.chain(lint_opts.into_iter())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let lint_caps = lints()
|
|
||||||
.filter_map(|lint| {
|
|
||||||
// We don't want to whitelist *all* lints so let's
|
|
||||||
// ignore those ones.
|
|
||||||
if whitelisted_lints.iter().any(|l| lint.name == l) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some((lint::LintId::of(lint), lint::Allow))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let crate_types =
|
let crate_types =
|
||||||
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
||||||
|
@ -28,6 +28,7 @@ use std::str;
|
|||||||
|
|
||||||
use crate::clean::Attributes;
|
use crate::clean::Attributes;
|
||||||
use crate::config::Options;
|
use crate::config::Options;
|
||||||
|
use crate::core::init_lints;
|
||||||
use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
|
use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
|
||||||
use crate::passes::span_of_attrs;
|
use crate::passes::span_of_attrs;
|
||||||
|
|
||||||
@ -45,44 +46,19 @@ pub struct TestOptions {
|
|||||||
pub fn run(options: Options) -> i32 {
|
pub fn run(options: Options) -> i32 {
|
||||||
let input = config::Input::File(options.input.clone());
|
let input = config::Input::File(options.input.clone());
|
||||||
|
|
||||||
let warnings_lint_name = lint::builtin::WARNINGS.name;
|
|
||||||
let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE.name;
|
let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE.name;
|
||||||
|
|
||||||
// In addition to those specific lints, we also need to whitelist those given through
|
// In addition to those specific lints, we also need to whitelist those given through
|
||||||
// command line, otherwise they'll get ignored and we don't want that.
|
// command line, otherwise they'll get ignored and we don't want that.
|
||||||
let mut whitelisted_lints =
|
let whitelisted_lints = vec![invalid_codeblock_attribute_name.to_owned()];
|
||||||
vec![warnings_lint_name.to_owned(), invalid_codeblock_attribute_name.to_owned()];
|
|
||||||
|
|
||||||
whitelisted_lints.extend(options.lint_opts.iter().map(|(lint, _)| lint).cloned());
|
let (lint_opts, lint_caps) = init_lints(whitelisted_lints, options.lint_opts.clone(), |lint| {
|
||||||
|
if lint.name == invalid_codeblock_attribute_name {
|
||||||
let lints = || {
|
|
||||||
lint::builtin::HardwiredLints::get_lints()
|
|
||||||
.into_iter()
|
|
||||||
.chain(rustc_lint::SoftLints::get_lints().into_iter())
|
|
||||||
};
|
|
||||||
|
|
||||||
let lint_opts = lints()
|
|
||||||
.filter_map(|lint| {
|
|
||||||
if lint.name == warnings_lint_name || lint.name == invalid_codeblock_attribute_name {
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((lint.name_lower(), lint::Allow))
|
Some((lint.name_lower(), lint::Allow))
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.chain(options.lint_opts.clone().into_iter())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let lint_caps = lints()
|
|
||||||
.filter_map(|lint| {
|
|
||||||
// We don't want to whitelist *all* lints so let's
|
|
||||||
// ignore those ones.
|
|
||||||
if whitelisted_lints.iter().any(|l| lint.name == l) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some((lint::LintId::of(lint), lint::Allow))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let crate_types =
|
let crate_types =
|
||||||
if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
#![feature(unsized_locals)]
|
||||||
|
|
||||||
|
struct Test([i32]);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _x: fn(_) -> Test = Test;
|
||||||
|
} //~^the size for values of type `[i32]` cannot be known at compilation time
|
@ -0,0 +1,14 @@
|
|||||||
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-30276-feature-flagged.rs:6:29
|
||||||
|
|
|
||||||
|
LL | let _x: fn(_) -> Test = Test;
|
||||||
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: within `Test`, the trait `std::marker::Sized` is not implemented for `[i32]`
|
||||||
|
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||||
|
= note: required because it appears within the type `Test`
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
5
src/test/ui/unsized-locals/issue-30276.rs
Normal file
5
src/test/ui/unsized-locals/issue-30276.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
struct Test([i32]);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _x: fn(_) -> Test = Test;
|
||||||
|
} //~^the size for values of type `[i32]` cannot be known at compilation time
|
14
src/test/ui/unsized-locals/issue-30276.stderr
Normal file
14
src/test/ui/unsized-locals/issue-30276.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-30276.rs:4:29
|
||||||
|
|
|
||||||
|
LL | let _x: fn(_) -> Test = Test;
|
||||||
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `std::marker::Sized` is not implemented for `[i32]`
|
||||||
|
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||||
|
= note: all function arguments must have a statically known size
|
||||||
|
= help: unsized locals are gated as an unstable feature
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user