Auto merge of #70441 - Dylan-DPC:rollup-qv7h2ph, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #70384 (Refactor object file handling) - #70397 (add 'fn write_u16s' to Memory) - #70413 (Fix incorrect pattern warning "unreachable pattern") - #70428 (`error_bad_item_kind`: add help text) - #70429 (Clean up E0459 explanation) - #70437 (Miri float->int casts: be explicit that this is saturating) Failed merges: r? @ghost
This commit is contained in:
commit
62c6006450
@ -16,7 +16,9 @@ use crate::ModuleLlvm;
|
||||
use log::debug;
|
||||
use rustc::bug;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig};
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
run_assembler, BitcodeSection, CodegenContext, EmitObj, ModuleConfig,
|
||||
};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
@ -651,7 +653,7 @@ pub(crate) unsafe fn codegen(
|
||||
let thin = ThinBuffer::new(llmod);
|
||||
let data = thin.data();
|
||||
|
||||
if config.emit_bc || config.obj_is_bitcode {
|
||||
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||
"LLVM_module_codegen_emit_bitcode",
|
||||
&module.name[..],
|
||||
@ -662,7 +664,7 @@ pub(crate) unsafe fn codegen(
|
||||
}
|
||||
}
|
||||
|
||||
if config.embed_bitcode == EmbedBitcode::Full {
|
||||
if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||
"LLVM_module_codegen_embed_bitcode",
|
||||
&module.name[..],
|
||||
@ -682,7 +684,7 @@ pub(crate) unsafe fn codegen(
|
||||
diag_handler.err(&msg);
|
||||
}
|
||||
}
|
||||
} else if config.embed_bitcode == EmbedBitcode::Marker {
|
||||
} else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
|
||||
embed_bitcode(cgcx, llcx, llmod, None);
|
||||
}
|
||||
|
||||
@ -732,9 +734,9 @@ pub(crate) unsafe fn codegen(
|
||||
})?;
|
||||
}
|
||||
|
||||
let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
|
||||
let config_emit_object_code = matches!(config.emit_obj, EmitObj::ObjectCode(_));
|
||||
|
||||
if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) {
|
||||
if config.emit_asm || (config_emit_object_code && config.no_integrated_as) {
|
||||
let _timer = cgcx
|
||||
.prof
|
||||
.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
|
||||
@ -743,60 +745,65 @@ pub(crate) unsafe fn codegen(
|
||||
// We can't use the same module for asm and binary output, because that triggers
|
||||
// various errors like invalid IR or broken binaries, so we might have to clone the
|
||||
// module to produce the asm output
|
||||
let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod };
|
||||
let llmod = if config_emit_object_code { llvm::LLVMCloneModule(llmod) } else { llmod };
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile)
|
||||
})?;
|
||||
}
|
||||
|
||||
if config_emit_normal_obj {
|
||||
if !config.no_integrated_as {
|
||||
let _timer = cgcx
|
||||
.prof
|
||||
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(
|
||||
diag_handler,
|
||||
tm,
|
||||
cpm,
|
||||
llmod,
|
||||
&obj_out,
|
||||
llvm::FileType::ObjectFile,
|
||||
)
|
||||
})?;
|
||||
} else {
|
||||
let _timer = cgcx
|
||||
.prof
|
||||
.generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
|
||||
let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
|
||||
run_assembler(cgcx, diag_handler, &assembly, &obj_out);
|
||||
match config.emit_obj {
|
||||
EmitObj::ObjectCode(_) => {
|
||||
if !config.no_integrated_as {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||
"LLVM_module_codegen_emit_obj",
|
||||
&module.name[..],
|
||||
);
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(
|
||||
diag_handler,
|
||||
tm,
|
||||
cpm,
|
||||
llmod,
|
||||
&obj_out,
|
||||
llvm::FileType::ObjectFile,
|
||||
)
|
||||
})?;
|
||||
} else {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||
"LLVM_module_codegen_asm_to_obj",
|
||||
&module.name[..],
|
||||
);
|
||||
let assembly =
|
||||
cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
|
||||
run_assembler(cgcx, diag_handler, &assembly, &obj_out);
|
||||
|
||||
if !config.emit_asm && !cgcx.save_temps {
|
||||
drop(fs::remove_file(&assembly));
|
||||
if !config.emit_asm && !cgcx.save_temps {
|
||||
drop(fs::remove_file(&assembly));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.obj_is_bitcode {
|
||||
if config.emit_obj {
|
||||
EmitObj::Bitcode => {
|
||||
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
|
||||
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
|
||||
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
if !config.emit_bc {
|
||||
debug!("removing_bitcode {:?}", bc_out);
|
||||
if let Err(e) = fs::remove_file(&bc_out) {
|
||||
diag_handler.err(&format!("failed to remove bitcode: {}", e));
|
||||
if !config.emit_bc {
|
||||
debug!("removing_bitcode {:?}", bc_out);
|
||||
if let Err(e) = fs::remove_file(&bc_out) {
|
||||
diag_handler.err(&format!("failed to remove bitcode: {}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmitObj::None => {}
|
||||
}
|
||||
|
||||
drop(handlers);
|
||||
}
|
||||
Ok(module.into_compiled_module(
|
||||
config.emit_obj,
|
||||
config.emit_obj != EmitObj::None,
|
||||
config.emit_bc,
|
||||
config.emit_bc_compressed,
|
||||
&cgcx.output_filenames,
|
||||
|
@ -51,11 +51,31 @@ use std::thread;
|
||||
|
||||
const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
|
||||
|
||||
/// The kind of bitcode to embed in object files.
|
||||
#[derive(PartialEq)]
|
||||
pub enum EmbedBitcode {
|
||||
/// What kind of object file to emit.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum EmitObj {
|
||||
// No object file.
|
||||
None,
|
||||
|
||||
// Just uncompressed llvm bitcode. Provides easy compatibility with
|
||||
// emscripten's ecc compiler, when used as the linker.
|
||||
Bitcode,
|
||||
|
||||
// Object code, possibly augmented with a bitcode section.
|
||||
ObjectCode(BitcodeSection),
|
||||
}
|
||||
|
||||
/// What kind of llvm bitcode section to embed in an object file.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum BitcodeSection {
|
||||
// No bitcode section.
|
||||
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.
|
||||
Full,
|
||||
}
|
||||
|
||||
@ -84,7 +104,7 @@ pub struct ModuleConfig {
|
||||
pub emit_bc_compressed: bool,
|
||||
pub emit_ir: bool,
|
||||
pub emit_asm: bool,
|
||||
pub emit_obj: bool,
|
||||
pub emit_obj: EmitObj,
|
||||
// Miscellaneous flags. These are mostly copied from command-line
|
||||
// options.
|
||||
pub verify_llvm_ir: bool,
|
||||
@ -96,12 +116,7 @@ pub struct ModuleConfig {
|
||||
pub merge_functions: bool,
|
||||
pub inline_threshold: Option<usize>,
|
||||
pub new_llvm_pass_manager: Option<bool>,
|
||||
// Instead of creating an object file by doing LLVM codegen, just
|
||||
// make the object file bitcode. Provides easy compatibility with
|
||||
// emscripten's ecc compiler, when used as the linker.
|
||||
pub obj_is_bitcode: bool,
|
||||
pub no_integrated_as: bool,
|
||||
pub embed_bitcode: EmbedBitcode,
|
||||
}
|
||||
|
||||
impl ModuleConfig {
|
||||
@ -124,9 +139,7 @@ impl ModuleConfig {
|
||||
emit_bc_compressed: false,
|
||||
emit_ir: false,
|
||||
emit_asm: false,
|
||||
emit_obj: false,
|
||||
obj_is_bitcode: false,
|
||||
embed_bitcode: EmbedBitcode::None,
|
||||
emit_obj: EmitObj::None,
|
||||
no_integrated_as: false,
|
||||
|
||||
verify_llvm_ir: false,
|
||||
@ -147,17 +160,6 @@ impl ModuleConfig {
|
||||
self.no_builtins = no_builtins || sess.target.target.options.no_builtins;
|
||||
self.inline_threshold = sess.opts.cg.inline_threshold;
|
||||
self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
|
||||
self.obj_is_bitcode =
|
||||
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
|
||||
self.embed_bitcode =
|
||||
if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode {
|
||||
match sess.opts.optimize {
|
||||
config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
|
||||
_ => EmbedBitcode::Full,
|
||||
}
|
||||
} else {
|
||||
EmbedBitcode::None
|
||||
};
|
||||
|
||||
// Copy what clang does by turning on loop vectorization at O2 and
|
||||
// slp vectorization at O3. Otherwise configure other optimization aspects
|
||||
@ -194,9 +196,9 @@ impl ModuleConfig {
|
||||
|
||||
pub fn bitcode_needed(&self) -> bool {
|
||||
self.emit_bc
|
||||
|| self.obj_is_bitcode
|
||||
|| self.emit_bc_compressed
|
||||
|| self.embed_bitcode == EmbedBitcode::Full
|
||||
|| self.emit_obj == EmitObj::Bitcode
|
||||
|| self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,6 +399,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
|
||||
allocator_config.emit_bc_compressed = true;
|
||||
}
|
||||
|
||||
let emit_obj =
|
||||
if sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
|
||||
EmitObj::Bitcode
|
||||
} else if sess.opts.debugging_opts.embed_bitcode {
|
||||
match sess.opts.optimize {
|
||||
config::OptLevel::No | config::OptLevel::Less => {
|
||||
EmitObj::ObjectCode(BitcodeSection::Marker)
|
||||
}
|
||||
_ => EmitObj::ObjectCode(BitcodeSection::Full),
|
||||
}
|
||||
} else {
|
||||
EmitObj::ObjectCode(BitcodeSection::None)
|
||||
};
|
||||
|
||||
modules_config.emit_pre_lto_bc = need_pre_lto_bitcode_for_incr_comp(sess);
|
||||
|
||||
modules_config.no_integrated_as =
|
||||
@ -416,20 +432,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
|
||||
// could be invoked specially with output_type_assembly, so
|
||||
// in this case we still want the metadata object file.
|
||||
if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
|
||||
metadata_config.emit_obj = true;
|
||||
allocator_config.emit_obj = true;
|
||||
metadata_config.emit_obj = emit_obj;
|
||||
allocator_config.emit_obj = emit_obj;
|
||||
}
|
||||
}
|
||||
OutputType::Object => {
|
||||
modules_config.emit_obj = true;
|
||||
modules_config.emit_obj = emit_obj;
|
||||
}
|
||||
OutputType::Metadata => {
|
||||
metadata_config.emit_obj = true;
|
||||
metadata_config.emit_obj = emit_obj;
|
||||
}
|
||||
OutputType::Exe => {
|
||||
modules_config.emit_obj = true;
|
||||
metadata_config.emit_obj = true;
|
||||
allocator_config.emit_obj = true;
|
||||
modules_config.emit_obj = emit_obj;
|
||||
metadata_config.emit_obj = emit_obj;
|
||||
allocator_config.emit_obj = emit_obj;
|
||||
}
|
||||
OutputType::Mir => {}
|
||||
OutputType::DepInfo => {}
|
||||
@ -880,7 +896,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(object.is_some(), module_config.emit_obj);
|
||||
assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
|
||||
assert_eq!(bytecode.is_some(), module_config.emit_bc);
|
||||
assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed);
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
A link was used without a name parameter. Erroneous code example:
|
||||
A link was used without a name parameter.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0459
|
||||
#[link(kind = "dylib")] extern {}
|
||||
|
@ -229,6 +229,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// float -> uint
|
||||
Uint(t) => {
|
||||
let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits());
|
||||
// `to_u128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
let v = f.to_u128(usize::try_from(width).unwrap()).value;
|
||||
// This should already fit the bit width
|
||||
Ok(Scalar::from_uint(v, Size::from_bits(width)))
|
||||
@ -236,6 +238,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// float -> int
|
||||
Int(t) => {
|
||||
let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits());
|
||||
// `to_i128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
let v = f.to_i128(usize::try_from(width).unwrap()).value;
|
||||
Ok(Scalar::from_int(v, Size::from_bits(width)))
|
||||
}
|
||||
|
@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
ptr: Scalar<M::PointerTag>,
|
||||
src: impl IntoIterator<Item = u8>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let src = src.into_iter();
|
||||
let mut src = src.into_iter();
|
||||
let size = Size::from_bytes(src.size_hint().0);
|
||||
// `write_bytes` checks that this lower bound `size` matches the upper bound and reality.
|
||||
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? {
|
||||
Some(ptr) => ptr,
|
||||
None => return Ok(()), // zero-sized access
|
||||
None => {
|
||||
// zero-sized access
|
||||
src.next().expect_none("iterator said it was empty but returned an element");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let tcx = self.tcx.tcx;
|
||||
self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
|
||||
}
|
||||
|
||||
/// Writes the given stream of u16s into memory.
|
||||
///
|
||||
/// Performs appropriate bounds checks.
|
||||
pub fn write_u16s(
|
||||
&mut self,
|
||||
ptr: Scalar<M::PointerTag>,
|
||||
src: impl IntoIterator<Item = u16>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let mut src = src.into_iter();
|
||||
let (lower, upper) = src.size_hint();
|
||||
let len = upper.expect("can only write bounded iterators");
|
||||
assert_eq!(lower, len, "can only write iterators with a precise length");
|
||||
|
||||
let size = Size::from_bytes(lower);
|
||||
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? {
|
||||
Some(ptr) => ptr,
|
||||
None => {
|
||||
// zero-sized access
|
||||
src.next().expect_none("iterator said it was empty but returned an element");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let tcx = self.tcx.tcx;
|
||||
let allocation = self.get_raw_mut(ptr.alloc_id)?;
|
||||
|
||||
for idx in 0..len {
|
||||
let val = Scalar::from_u16(
|
||||
src.next().expect("iterator was shorter than it said it would be"),
|
||||
);
|
||||
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
|
||||
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
|
||||
}
|
||||
src.next().expect_none("iterator was longer than it said it would be");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Expects the caller to have checked bounds and alignment.
|
||||
pub fn copy(
|
||||
&mut self,
|
||||
|
@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust.
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(option_expect_none)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -1619,12 +1619,17 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> {
|
||||
/// relation to preceding patterns, it is not reachable) and exhaustiveness
|
||||
/// checking (if a wildcard pattern is useful in relation to a matrix, the
|
||||
/// matrix isn't exhaustive).
|
||||
///
|
||||
/// `is_under_guard` is used to inform if the pattern has a guard. If it
|
||||
/// has one it must not be inserted into the matrix. This shouldn't be
|
||||
/// relied on for soundness.
|
||||
crate fn is_useful<'p, 'tcx>(
|
||||
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
||||
matrix: &Matrix<'p, 'tcx>,
|
||||
v: &PatStack<'p, 'tcx>,
|
||||
witness_preference: WitnessPreference,
|
||||
hir_id: HirId,
|
||||
is_under_guard: bool,
|
||||
is_top_level: bool,
|
||||
) -> Usefulness<'tcx, 'p> {
|
||||
let &Matrix(ref rows) = matrix;
|
||||
@ -1653,7 +1658,7 @@ crate fn is_useful<'p, 'tcx>(
|
||||
let mut unreachable_pats = Vec::new();
|
||||
let mut any_is_useful = false;
|
||||
for v in vs {
|
||||
let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, false);
|
||||
let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
|
||||
match res {
|
||||
Useful(pats) => {
|
||||
any_is_useful = true;
|
||||
@ -1664,7 +1669,10 @@ crate fn is_useful<'p, 'tcx>(
|
||||
bug!("Encountered or-pat in `v` during exhaustiveness checking")
|
||||
}
|
||||
}
|
||||
matrix.push(v);
|
||||
// If pattern has a guard don't add it to the matrix
|
||||
if !is_under_guard {
|
||||
matrix.push(v);
|
||||
}
|
||||
}
|
||||
return if any_is_useful { Useful(unreachable_pats) } else { NotUseful };
|
||||
}
|
||||
@ -1712,7 +1720,18 @@ crate fn is_useful<'p, 'tcx>(
|
||||
Some(hir_id),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id))
|
||||
.map(|c| {
|
||||
is_useful_specialized(
|
||||
cx,
|
||||
matrix,
|
||||
v,
|
||||
c,
|
||||
pcx.ty,
|
||||
witness_preference,
|
||||
hir_id,
|
||||
is_under_guard,
|
||||
)
|
||||
})
|
||||
.find(|result| result.is_useful())
|
||||
.unwrap_or(NotUseful)
|
||||
} else {
|
||||
@ -1746,14 +1765,24 @@ crate fn is_useful<'p, 'tcx>(
|
||||
split_grouped_constructors(cx.tcx, cx.param_env, pcx, all_ctors, matrix, DUMMY_SP, None)
|
||||
.into_iter()
|
||||
.map(|c| {
|
||||
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id)
|
||||
is_useful_specialized(
|
||||
cx,
|
||||
matrix,
|
||||
v,
|
||||
c,
|
||||
pcx.ty,
|
||||
witness_preference,
|
||||
hir_id,
|
||||
is_under_guard,
|
||||
)
|
||||
})
|
||||
.find(|result| result.is_useful())
|
||||
.unwrap_or(NotUseful)
|
||||
} else {
|
||||
let matrix = matrix.specialize_wildcard();
|
||||
let v = v.to_tail();
|
||||
let usefulness = is_useful(cx, &matrix, &v, witness_preference, hir_id, false);
|
||||
let usefulness =
|
||||
is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
|
||||
|
||||
// In this case, there's at least one "free"
|
||||
// constructor that is only matched against by
|
||||
@ -1810,6 +1839,7 @@ fn is_useful_specialized<'p, 'tcx>(
|
||||
lty: Ty<'tcx>,
|
||||
witness_preference: WitnessPreference,
|
||||
hir_id: HirId,
|
||||
is_under_guard: bool,
|
||||
) -> Usefulness<'tcx, 'p> {
|
||||
debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty);
|
||||
|
||||
@ -1817,7 +1847,7 @@ fn is_useful_specialized<'p, 'tcx>(
|
||||
cx.pattern_arena.alloc_from_iter(ctor.wildcard_subpatterns(cx, lty));
|
||||
let matrix = matrix.specialize_constructor(cx, &ctor, ctor_wild_subpatterns);
|
||||
v.specialize_constructor(cx, &ctor, ctor_wild_subpatterns)
|
||||
.map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, false))
|
||||
.map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false))
|
||||
.map(|u| u.apply_constructor(cx, &ctor, lty))
|
||||
.unwrap_or(NotUseful)
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ fn check_arms<'p, 'tcx>(
|
||||
let mut catchall = None;
|
||||
for (arm_index, (pat, id, has_guard)) in arms.iter().copied().enumerate() {
|
||||
let v = PatStack::from_pattern(pat);
|
||||
match is_useful(cx, &seen, &v, LeaveOutWitness, id, true) {
|
||||
match is_useful(cx, &seen, &v, LeaveOutWitness, id, has_guard, true) {
|
||||
NotUseful => {
|
||||
match source {
|
||||
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(),
|
||||
@ -410,7 +410,10 @@ fn check_not_useful<'p, 'tcx>(
|
||||
) -> Result<(), Vec<super::Pat<'tcx>>> {
|
||||
let wild_pattern = cx.pattern_arena.alloc(super::Pat::wildcard_from_ty(ty));
|
||||
let v = PatStack::from_pattern(wild_pattern);
|
||||
match is_useful(cx, matrix, &v, ConstructWitness, hir_id, true) {
|
||||
|
||||
// false is given for `is_under_guard` argument due to the wildcard
|
||||
// pattern not having a guard
|
||||
match is_useful(cx, matrix, &v, ConstructWitness, hir_id, false, true) {
|
||||
NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
|
||||
UsefulWithWitness(pats) => Err(if pats.is_empty() {
|
||||
bug!("Exhaustiveness check returned no witnesses")
|
||||
|
@ -908,8 +908,10 @@ impl<'a> Parser<'a> {
|
||||
|
||||
fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option<T> {
|
||||
let span = self.sess.source_map().guess_head_span(span);
|
||||
let msg = format!("{} is not supported in {}", kind.descr(), ctx);
|
||||
self.struct_span_err(span, &msg).emit();
|
||||
let descr = kind.descr();
|
||||
self.struct_span_err(span, &format!("{} is not supported in {}", descr, ctx))
|
||||
.help(&format!("consider moving the {} out to a nearby module scope", descr))
|
||||
.emit();
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -771,9 +771,6 @@ pub struct TargetOptions {
|
||||
/// rather than "default"
|
||||
pub default_hidden_visibility: bool,
|
||||
|
||||
/// Whether or not bitcode is embedded in object files
|
||||
pub embed_bitcode: bool,
|
||||
|
||||
/// Whether a .debug_gdb_scripts section will be added to the output object file
|
||||
pub emit_debug_gdb_scripts: bool,
|
||||
|
||||
@ -893,7 +890,6 @@ impl Default for TargetOptions {
|
||||
no_builtins: false,
|
||||
codegen_backend: "llvm".to_string(),
|
||||
default_hidden_visibility: false,
|
||||
embed_bitcode: false,
|
||||
emit_debug_gdb_scripts: true,
|
||||
requires_uwtable: false,
|
||||
simd_types_indirect: true,
|
||||
@ -1208,7 +1204,6 @@ impl Target {
|
||||
key!(no_builtins, bool);
|
||||
key!(codegen_backend);
|
||||
key!(default_hidden_visibility, bool);
|
||||
key!(embed_bitcode, bool);
|
||||
key!(emit_debug_gdb_scripts, bool);
|
||||
key!(requires_uwtable, bool);
|
||||
key!(simd_types_indirect, bool);
|
||||
@ -1437,7 +1432,6 @@ impl ToJson for Target {
|
||||
target_option_val!(no_builtins);
|
||||
target_option_val!(codegen_backend);
|
||||
target_option_val!(default_hidden_visibility);
|
||||
target_option_val!(embed_bitcode);
|
||||
target_option_val!(emit_debug_gdb_scripts);
|
||||
target_option_val!(requires_uwtable);
|
||||
target_option_val!(simd_types_indirect);
|
||||
|
@ -0,0 +1,22 @@
|
||||
// check-pass
|
||||
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
#![feature(or_patterns)]
|
||||
fn main() {
|
||||
match (3,42) {
|
||||
(a,_) | (_,a) if a > 10 => {println!("{}", a)}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
match Some((3,42)) {
|
||||
Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)}
|
||||
_ => ()
|
||||
|
||||
}
|
||||
|
||||
match Some((3,42)) {
|
||||
Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)}
|
||||
_ => ()
|
||||
}
|
||||
}
|
@ -123,6 +123,8 @@ error: extern crate is not supported in `extern` blocks
|
||||
|
|
||||
LL | default extern crate foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern crate out to a nearby module scope
|
||||
|
||||
error: a `use` import cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:35:5
|
||||
@ -137,6 +139,8 @@ error: `use` import is not supported in `extern` blocks
|
||||
|
|
||||
LL | default use foo;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the `use` import out to a nearby module scope
|
||||
|
||||
error: a static item cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:37:5
|
||||
@ -169,6 +173,8 @@ error: module is not supported in `extern` blocks
|
||||
|
|
||||
LL | default mod foo {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the module out to a nearby module scope
|
||||
|
||||
error: an extern block cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:43:5
|
||||
@ -183,6 +189,8 @@ error: extern block is not supported in `extern` blocks
|
||||
|
|
||||
LL | default extern "C" {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern block out to a nearby module scope
|
||||
|
||||
error: an enum cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:46:5
|
||||
@ -197,6 +205,8 @@ error: enum is not supported in `extern` blocks
|
||||
|
|
||||
LL | default enum foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
|
||||
error: a struct cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:48:5
|
||||
@ -211,6 +221,8 @@ error: struct is not supported in `extern` blocks
|
||||
|
|
||||
LL | default struct foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: a union cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:50:5
|
||||
@ -225,6 +237,8 @@ error: union is not supported in `extern` blocks
|
||||
|
|
||||
LL | default union foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the union out to a nearby module scope
|
||||
|
||||
error: a trait cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:52:5
|
||||
@ -239,6 +253,8 @@ error: trait is not supported in `extern` blocks
|
||||
|
|
||||
LL | default trait foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait out to a nearby module scope
|
||||
|
||||
error: a trait alias cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:54:5
|
||||
@ -253,12 +269,16 @@ error: trait alias is not supported in `extern` blocks
|
||||
|
|
||||
LL | default trait foo = Ord;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait alias out to a nearby module scope
|
||||
|
||||
error: implementation is not supported in `extern` blocks
|
||||
--> $DIR/default-on-wrong-item-kind.rs:56:5
|
||||
|
|
||||
LL | default impl foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the implementation out to a nearby module scope
|
||||
|
||||
error: an item macro invocation cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:60:5
|
||||
@ -289,6 +309,8 @@ error: macro definition is not supported in `extern` blocks
|
||||
|
|
||||
LL | default macro foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: a macro definition cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:64:5
|
||||
@ -303,6 +325,8 @@ error: macro definition is not supported in `extern` blocks
|
||||
|
|
||||
LL | default macro_rules! foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: an extern crate cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:70:5
|
||||
@ -317,6 +341,8 @@ error: extern crate is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default extern crate foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern crate out to a nearby module scope
|
||||
|
||||
error: a `use` import cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:72:5
|
||||
@ -331,6 +357,8 @@ error: `use` import is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default use foo;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the `use` import out to a nearby module scope
|
||||
|
||||
error: a static item cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:74:5
|
||||
@ -359,6 +387,8 @@ error: module is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default mod foo {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the module out to a nearby module scope
|
||||
|
||||
error: an extern block cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:80:5
|
||||
@ -373,6 +403,8 @@ error: extern block is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default extern "C" {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern block out to a nearby module scope
|
||||
|
||||
error: an enum cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:83:5
|
||||
@ -387,6 +419,8 @@ error: enum is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default enum foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
|
||||
error: a struct cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:85:5
|
||||
@ -401,6 +435,8 @@ error: struct is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default struct foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: a union cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:87:5
|
||||
@ -415,6 +451,8 @@ error: union is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default union foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the union out to a nearby module scope
|
||||
|
||||
error: a trait cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:89:5
|
||||
@ -429,6 +467,8 @@ error: trait is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default trait foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait out to a nearby module scope
|
||||
|
||||
error: a trait alias cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:91:5
|
||||
@ -443,12 +483,16 @@ error: trait alias is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default trait foo = Ord;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait alias out to a nearby module scope
|
||||
|
||||
error: implementation is not supported in `trait`s or `impl`s
|
||||
--> $DIR/default-on-wrong-item-kind.rs:93:5
|
||||
|
|
||||
LL | default impl foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the implementation out to a nearby module scope
|
||||
|
||||
error: an item macro invocation cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:97:5
|
||||
@ -479,6 +523,8 @@ error: macro definition is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default macro foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: a macro definition cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:101:5
|
||||
@ -493,6 +539,8 @@ error: macro definition is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default macro_rules! foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: an extern crate cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:107:5
|
||||
@ -507,6 +555,8 @@ error: extern crate is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default extern crate foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern crate out to a nearby module scope
|
||||
|
||||
error: a `use` import cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:109:5
|
||||
@ -521,6 +571,8 @@ error: `use` import is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default use foo;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the `use` import out to a nearby module scope
|
||||
|
||||
error: a static item cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:111:5
|
||||
@ -549,6 +601,8 @@ error: module is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default mod foo {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the module out to a nearby module scope
|
||||
|
||||
error: an extern block cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:117:5
|
||||
@ -563,6 +617,8 @@ error: extern block is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default extern "C" {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the extern block out to a nearby module scope
|
||||
|
||||
error: an enum cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:120:5
|
||||
@ -577,6 +633,8 @@ error: enum is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default enum foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
|
||||
error: a struct cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:122:5
|
||||
@ -591,6 +649,8 @@ error: struct is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default struct foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: a union cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:124:5
|
||||
@ -605,6 +665,8 @@ error: union is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default union foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the union out to a nearby module scope
|
||||
|
||||
error: a trait cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:126:5
|
||||
@ -619,6 +681,8 @@ error: trait is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default trait foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait out to a nearby module scope
|
||||
|
||||
error: a trait alias cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:128:5
|
||||
@ -633,12 +697,16 @@ error: trait alias is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default trait foo = Ord;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait alias out to a nearby module scope
|
||||
|
||||
error: implementation is not supported in `trait`s or `impl`s
|
||||
--> $DIR/default-on-wrong-item-kind.rs:130:5
|
||||
|
|
||||
LL | default impl foo {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the implementation out to a nearby module scope
|
||||
|
||||
error: an item macro invocation cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:134:5
|
||||
@ -669,6 +737,8 @@ error: macro definition is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default macro foo {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: a macro definition cannot be `default`
|
||||
--> $DIR/default-on-wrong-item-kind.rs:138:5
|
||||
@ -683,6 +753,8 @@ error: macro definition is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | default macro_rules! foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the macro definition out to a nearby module scope
|
||||
|
||||
error: aborting due to 95 previous errors
|
||||
|
||||
|
@ -3,6 +3,8 @@ error: struct is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | struct BadS;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: enum is not supported in `trait`s or `impl`s
|
||||
--> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
|
||||
@ -13,6 +15,7 @@ LL | enum BadE {}
|
||||
LL | expand_to_enum!();
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: struct is not supported in `trait`s or `impl`s
|
||||
@ -20,6 +23,8 @@ error: struct is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | struct BadS;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: enum is not supported in `trait`s or `impl`s
|
||||
--> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
|
||||
@ -30,6 +35,7 @@ LL | enum BadE {}
|
||||
LL | expand_to_enum!();
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: struct is not supported in `extern` blocks
|
||||
@ -37,6 +43,8 @@ error: struct is not supported in `extern` blocks
|
||||
|
|
||||
LL | struct BadS;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: enum is not supported in `extern` blocks
|
||||
--> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
|
||||
@ -47,6 +55,7 @@ LL | enum BadE {}
|
||||
LL | expand_to_enum!();
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= help: consider moving the enum out to a nearby module scope
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
@ -12,12 +12,16 @@ error: trait is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | trait T {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: consider moving the trait out to a nearby module scope
|
||||
|
||||
error: struct is not supported in `trait`s or `impl`s
|
||||
--> $DIR/missing-close-brace-in-impl-trait.rs:11:1
|
||||
|
|
||||
LL | pub(crate) struct Bar<T>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error[E0405]: cannot find trait `T` in this scope
|
||||
--> $DIR/missing-close-brace-in-impl-trait.rs:3:6
|
||||
|
@ -12,12 +12,16 @@ error: struct is not supported in `trait`s or `impl`s
|
||||
|
|
||||
LL | pub(crate) struct Bar<T>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the struct out to a nearby module scope
|
||||
|
||||
error: implementation is not supported in `trait`s or `impl`s
|
||||
--> $DIR/missing-close-brace-in-trait.rs:7:1
|
||||
|
|
||||
LL | impl T for Bar<usize> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider moving the implementation out to a nearby module scope
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user