mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #70351 - Centril:rollup-tveoq3w, r=Centril
Rollup of 8 pull requests Successful merges: - #68884 (Make the `type_of` return a generic type for generators) - #69788 (Fix sequence of Type and Trait in optin-builtin-traits in Unstable Book) - #70074 (Expand: nix all fatal errors) - #70077 (Store idents for `DefPathData` into crate metadata) - #70213 (traits/fulfill: allow `stalled_on` to track `ty::Const::Infer(_)` (unused yet).) - #70259 (Use Reveal::All in MIR optimizations) - #70284 (correctly handle const params in type_of) - #70289 (Refactor `codegen`) Failed merges: r? @ghost
This commit is contained in:
commit
9d0ae58d30
@ -16,7 +16,7 @@ has explicitly opted out via a negative impl.
|
|||||||
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
|
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
impl !Type for Trait
|
impl !Trait for Type
|
||||||
```
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
use rustc_ast::ast::{self, AttrItem, AttrStyle};
|
use rustc_ast::ast::{self, AttrItem, AttrStyle};
|
||||||
use rustc_ast::attr::mk_attr;
|
use rustc_ast::attr::mk_attr;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_expand::panictry;
|
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
|
|
||||||
@ -16,7 +15,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
|
|||||||
);
|
);
|
||||||
|
|
||||||
let start_span = parser.token.span;
|
let start_span = parser.token.span;
|
||||||
let AttrItem { path, args } = panictry!(parser.parse_attr_item());
|
let AttrItem { path, args } = match parser.parse_attr_item() {
|
||||||
|
Ok(ai) => ai,
|
||||||
|
Err(mut err) => {
|
||||||
|
err.emit();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
let end_span = parser.token.span;
|
let end_span = parser.token.span;
|
||||||
if parser.token != token::Eof {
|
if parser.token != token::Eof {
|
||||||
parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute");
|
parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute");
|
||||||
|
@ -5,7 +5,6 @@ use rustc_ast::tokenstream::TokenStream;
|
|||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_expand::base::{self, *};
|
use rustc_expand::base::{self, *};
|
||||||
use rustc_expand::module::DirectoryOwnership;
|
use rustc_expand::module::DirectoryOwnership;
|
||||||
use rustc_expand::panictry;
|
|
||||||
use rustc_parse::{self, new_parser_from_file, parser::Parser};
|
use rustc_parse::{self, new_parser_from_file, parser::Parser};
|
||||||
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
|
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
@ -126,7 +125,7 @@ pub fn expand_include<'cx>(
|
|||||||
}
|
}
|
||||||
impl<'a> base::MacResult for ExpandResult<'a> {
|
impl<'a> base::MacResult for ExpandResult<'a> {
|
||||||
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
|
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
|
||||||
let r = panictry!(self.p.parse_expr());
|
let r = base::parse_expr(&mut self.p)?;
|
||||||
if self.p.token != token::Eof {
|
if self.p.token != token::Eof {
|
||||||
self.p.sess.buffer_lint(
|
self.p.sess.buffer_lint(
|
||||||
&INCOMPLETE_INCLUDE,
|
&INCOMPLETE_INCLUDE,
|
||||||
@ -141,18 +140,17 @@ pub fn expand_include<'cx>(
|
|||||||
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
||||||
let mut ret = SmallVec::new();
|
let mut ret = SmallVec::new();
|
||||||
while self.p.token != token::Eof {
|
while self.p.token != token::Eof {
|
||||||
match panictry!(self.p.parse_item()) {
|
match self.p.parse_item() {
|
||||||
Some(item) => ret.push(item),
|
Err(mut err) => {
|
||||||
None => {
|
err.emit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(Some(item)) => ret.push(item),
|
||||||
|
Ok(None) => {
|
||||||
let token = pprust::token_to_string(&self.p.token);
|
let token = pprust::token_to_string(&self.p.token);
|
||||||
self.p
|
let msg = format!("expected item, found `{}`", token);
|
||||||
.sess
|
self.p.struct_span_err(self.p.token.span, &msg).emit();
|
||||||
.span_diagnostic
|
break;
|
||||||
.span_fatal(
|
|
||||||
self.p.token.span,
|
|
||||||
&format!("expected item, found `{}`", token),
|
|
||||||
)
|
|
||||||
.raise();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,16 +74,16 @@ pub fn expand_test_or_bench(
|
|||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = if let Annotatable::Item(i) = item {
|
let item = match item {
|
||||||
i
|
Annotatable::Item(i) => i,
|
||||||
} else {
|
other => {
|
||||||
cx.parse_sess
|
cx.struct_span_err(
|
||||||
.span_diagnostic
|
other.span(),
|
||||||
.span_fatal(
|
|
||||||
item.span(),
|
|
||||||
"`#[test]` attribute is only allowed on non associated functions",
|
"`#[test]` attribute is only allowed on non associated functions",
|
||||||
)
|
)
|
||||||
.raise();
|
.emit();
|
||||||
|
return vec![other];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ast::ItemKind::MacCall(_) = item.kind {
|
if let ast::ItemKind::MacCall(_) = item.kind {
|
||||||
|
@ -345,14 +345,14 @@ fn is_test_case(i: &ast::Item) -> bool {
|
|||||||
|
|
||||||
fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
|
fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
|
||||||
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
|
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
|
||||||
test_attr.meta_item_list().map(|meta_list| {
|
let meta_list = test_attr.meta_item_list()?;
|
||||||
if meta_list.len() != 1 {
|
let span = test_attr.span;
|
||||||
sd.span_fatal(test_attr.span, "`#![test_runner(..)]` accepts exactly 1 argument")
|
match &*meta_list {
|
||||||
.raise()
|
[single] => match single.meta_item() {
|
||||||
}
|
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
|
||||||
match meta_list[0].meta_item() {
|
_ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(),
|
||||||
Some(meta_item) if meta_item.is_word() => meta_item.path.clone(),
|
},
|
||||||
_ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise(),
|
_ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(),
|
||||||
}
|
}
|
||||||
})
|
None
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use crate::ModuleLlvm;
|
|||||||
use log::debug;
|
use log::debug;
|
||||||
use rustc::bug;
|
use rustc::bug;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, ModuleConfig};
|
use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
|
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
@ -634,30 +634,24 @@ pub(crate) unsafe fn codegen(
|
|||||||
f(cpm)
|
f(cpm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have the integrated assembler, then we need to emit asm
|
// Two things to note:
|
||||||
// from LLVM and use `gcc` to create the object file.
|
// - If object files are just LLVM bitcode we write bitcode, copy it to
|
||||||
let asm_to_obj = config.emit_obj && config.no_integrated_as;
|
// the .o file, and delete the bitcode if it wasn't otherwise
|
||||||
|
// requested.
|
||||||
// Change what we write and cleanup based on whether obj files are
|
// - If we don't have the integrated assembler then we need to emit
|
||||||
// just llvm bitcode. In that case write bitcode, and possibly
|
// asm from LLVM and use `gcc` to create the object file.
|
||||||
// delete the bitcode if it wasn't requested. Don't generate the
|
|
||||||
// machine code, instead copy the .o file from the .bc
|
|
||||||
let write_bc = config.emit_bc || config.obj_is_bitcode;
|
|
||||||
let rm_bc = !config.emit_bc && config.obj_is_bitcode;
|
|
||||||
let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj;
|
|
||||||
let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;
|
|
||||||
|
|
||||||
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
|
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
|
||||||
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
|
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
|
||||||
|
|
||||||
if write_bc || config.emit_bc_compressed || config.embed_bitcode {
|
if config.bitcode_needed() {
|
||||||
let _timer = cgcx
|
let _timer = cgcx
|
||||||
.prof
|
.prof
|
||||||
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]);
|
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]);
|
||||||
let thin = ThinBuffer::new(llmod);
|
let thin = ThinBuffer::new(llmod);
|
||||||
let data = thin.data();
|
let data = thin.data();
|
||||||
|
|
||||||
if write_bc {
|
if config.emit_bc || config.obj_is_bitcode {
|
||||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||||
"LLVM_module_codegen_emit_bitcode",
|
"LLVM_module_codegen_emit_bitcode",
|
||||||
&module.name[..],
|
&module.name[..],
|
||||||
@ -668,7 +662,7 @@ pub(crate) unsafe fn codegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.embed_bitcode {
|
if config.embed_bitcode == EmbedBitcode::Full {
|
||||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||||
"LLVM_module_codegen_embed_bitcode",
|
"LLVM_module_codegen_embed_bitcode",
|
||||||
&module.name[..],
|
&module.name[..],
|
||||||
@ -688,81 +682,75 @@ pub(crate) unsafe fn codegen(
|
|||||||
diag_handler.err(&msg);
|
diag_handler.err(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if config.embed_bitcode_marker {
|
} else if config.embed_bitcode == EmbedBitcode::Marker {
|
||||||
embed_bitcode(cgcx, llcx, llmod, None);
|
embed_bitcode(cgcx, llcx, llmod, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if config.emit_ir {
|
||||||
if config.emit_ir {
|
let _timer = cgcx
|
||||||
let _timer = cgcx
|
.prof
|
||||||
.prof
|
.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
|
||||||
.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
|
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
|
||||||
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
|
let out_c = path_to_c_string(&out);
|
||||||
let out_c = path_to_c_string(&out);
|
|
||||||
|
|
||||||
extern "C" fn demangle_callback(
|
extern "C" fn demangle_callback(
|
||||||
input_ptr: *const c_char,
|
input_ptr: *const c_char,
|
||||||
input_len: size_t,
|
input_len: size_t,
|
||||||
output_ptr: *mut c_char,
|
output_ptr: *mut c_char,
|
||||||
output_len: size_t,
|
output_len: size_t,
|
||||||
) -> size_t {
|
) -> size_t {
|
||||||
let input = unsafe {
|
let input =
|
||||||
slice::from_raw_parts(input_ptr as *const u8, input_len as usize)
|
unsafe { slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
|
||||||
};
|
|
||||||
|
|
||||||
let input = match str::from_utf8(input) {
|
let input = match str::from_utf8(input) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return 0,
|
Err(_) => return 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = unsafe {
|
let output = unsafe {
|
||||||
slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
|
slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
|
||||||
};
|
};
|
||||||
let mut cursor = io::Cursor::new(output);
|
let mut cursor = io::Cursor::new(output);
|
||||||
|
|
||||||
let demangled = match rustc_demangle::try_demangle(input) {
|
let demangled = match rustc_demangle::try_demangle(input) {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(_) => return 0,
|
Err(_) => return 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if write!(cursor, "{:#}", demangled).is_err() {
|
if write!(cursor, "{:#}", demangled).is_err() {
|
||||||
// Possible only if provided buffer is not big enough
|
// Possible only if provided buffer is not big enough
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
cursor.position() as size_t
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
|
cursor.position() as size_t
|
||||||
result.into_result().map_err(|()| {
|
|
||||||
let msg = format!("failed to write LLVM IR to {}", out.display());
|
|
||||||
llvm_err(diag_handler, &msg)
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.emit_asm || asm_to_obj {
|
let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
|
||||||
let _timer = cgcx
|
result.into_result().map_err(|()| {
|
||||||
.prof
|
let msg = format!("failed to write LLVM IR to {}", out.display());
|
||||||
.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
|
llvm_err(diag_handler, &msg)
|
||||||
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
// We can't use the same module for asm and binary output, because that triggers
|
let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
|
||||||
// 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 };
|
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
|
||||||
write_output_file(
|
|
||||||
diag_handler,
|
|
||||||
tm,
|
|
||||||
cpm,
|
|
||||||
llmod,
|
|
||||||
&path,
|
|
||||||
llvm::FileType::AssemblyFile,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if write_obj {
|
if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) {
|
||||||
|
let _timer = cgcx
|
||||||
|
.prof
|
||||||
|
.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
|
||||||
|
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
|
||||||
|
|
||||||
|
// 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 };
|
||||||
|
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
|
let _timer = cgcx
|
||||||
.prof
|
.prof
|
||||||
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
|
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
|
||||||
@ -776,7 +764,7 @@ pub(crate) unsafe fn codegen(
|
|||||||
llvm::FileType::ObjectFile,
|
llvm::FileType::ObjectFile,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
} else if asm_to_obj {
|
} else {
|
||||||
let _timer = cgcx
|
let _timer = cgcx
|
||||||
.prof
|
.prof
|
||||||
.generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
|
.generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
|
||||||
@ -789,17 +777,19 @@ pub(crate) unsafe fn codegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if copy_bc_to_obj {
|
if config.obj_is_bitcode {
|
||||||
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
|
if config.emit_obj {
|
||||||
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
|
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
|
||||||
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
|
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
|
||||||
|
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if rm_bc {
|
if !config.emit_bc {
|
||||||
debug!("removing_bitcode {:?}", bc_out);
|
debug!("removing_bitcode {:?}", bc_out);
|
||||||
if let Err(e) = fs::remove_file(&bc_out) {
|
if let Err(e) = fs::remove_file(&bc_out) {
|
||||||
diag_handler.err(&format!("failed to remove bitcode: {}", e));
|
diag_handler.err(&format!("failed to remove bitcode: {}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,14 @@ use std::thread;
|
|||||||
|
|
||||||
const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
|
const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
|
||||||
|
|
||||||
|
/// The kind of bitcode to embed in object files.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum EmbedBitcode {
|
||||||
|
None,
|
||||||
|
Marker,
|
||||||
|
Full,
|
||||||
|
}
|
||||||
|
|
||||||
/// Module-specific configuration for `optimize_and_codegen`.
|
/// Module-specific configuration for `optimize_and_codegen`.
|
||||||
pub struct ModuleConfig {
|
pub struct ModuleConfig {
|
||||||
/// Names of additional optimization passes to run.
|
/// Names of additional optimization passes to run.
|
||||||
@ -74,7 +82,6 @@ pub struct ModuleConfig {
|
|||||||
pub emit_no_opt_bc: bool,
|
pub emit_no_opt_bc: bool,
|
||||||
pub emit_bc: bool,
|
pub emit_bc: bool,
|
||||||
pub emit_bc_compressed: bool,
|
pub emit_bc_compressed: bool,
|
||||||
pub emit_lto_bc: bool,
|
|
||||||
pub emit_ir: bool,
|
pub emit_ir: bool,
|
||||||
pub emit_asm: bool,
|
pub emit_asm: bool,
|
||||||
pub emit_obj: bool,
|
pub emit_obj: bool,
|
||||||
@ -94,8 +101,7 @@ pub struct ModuleConfig {
|
|||||||
// emscripten's ecc compiler, when used as the linker.
|
// emscripten's ecc compiler, when used as the linker.
|
||||||
pub obj_is_bitcode: bool,
|
pub obj_is_bitcode: bool,
|
||||||
pub no_integrated_as: bool,
|
pub no_integrated_as: bool,
|
||||||
pub embed_bitcode: bool,
|
pub embed_bitcode: EmbedBitcode,
|
||||||
pub embed_bitcode_marker: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleConfig {
|
impl ModuleConfig {
|
||||||
@ -116,13 +122,11 @@ impl ModuleConfig {
|
|||||||
emit_pre_lto_bc: false,
|
emit_pre_lto_bc: false,
|
||||||
emit_bc: false,
|
emit_bc: false,
|
||||||
emit_bc_compressed: false,
|
emit_bc_compressed: false,
|
||||||
emit_lto_bc: false,
|
|
||||||
emit_ir: false,
|
emit_ir: false,
|
||||||
emit_asm: false,
|
emit_asm: false,
|
||||||
emit_obj: false,
|
emit_obj: false,
|
||||||
obj_is_bitcode: false,
|
obj_is_bitcode: false,
|
||||||
embed_bitcode: false,
|
embed_bitcode: EmbedBitcode::None,
|
||||||
embed_bitcode_marker: false,
|
|
||||||
no_integrated_as: false,
|
no_integrated_as: false,
|
||||||
|
|
||||||
verify_llvm_ir: false,
|
verify_llvm_ir: false,
|
||||||
@ -145,16 +149,15 @@ impl ModuleConfig {
|
|||||||
self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
|
self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
|
||||||
self.obj_is_bitcode =
|
self.obj_is_bitcode =
|
||||||
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
|
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
|
||||||
let embed_bitcode =
|
self.embed_bitcode =
|
||||||
sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode;
|
if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode {
|
||||||
if embed_bitcode {
|
match sess.opts.optimize {
|
||||||
match sess.opts.optimize {
|
config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
|
||||||
config::OptLevel::No | config::OptLevel::Less => {
|
_ => EmbedBitcode::Full,
|
||||||
self.embed_bitcode_marker = embed_bitcode;
|
|
||||||
}
|
}
|
||||||
_ => self.embed_bitcode = embed_bitcode,
|
} else {
|
||||||
}
|
EmbedBitcode::None
|
||||||
}
|
};
|
||||||
|
|
||||||
// Copy what clang does by turning on loop vectorization at O2 and
|
// Copy what clang does by turning on loop vectorization at O2 and
|
||||||
// slp vectorization at O3. Otherwise configure other optimization aspects
|
// slp vectorization at O3. Otherwise configure other optimization aspects
|
||||||
@ -190,7 +193,10 @@ impl ModuleConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitcode_needed(&self) -> bool {
|
pub fn bitcode_needed(&self) -> bool {
|
||||||
self.emit_bc || self.obj_is_bitcode || self.emit_bc_compressed || self.embed_bitcode
|
self.emit_bc
|
||||||
|
|| self.obj_is_bitcode
|
||||||
|
|| self.emit_bc_compressed
|
||||||
|
|| self.embed_bitcode == EmbedBitcode::Full
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +385,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
|
|||||||
modules_config.emit_no_opt_bc = true;
|
modules_config.emit_no_opt_bc = true;
|
||||||
modules_config.emit_pre_lto_bc = true;
|
modules_config.emit_pre_lto_bc = true;
|
||||||
modules_config.emit_bc = true;
|
modules_config.emit_bc = true;
|
||||||
modules_config.emit_lto_bc = true;
|
|
||||||
metadata_config.emit_bc = true;
|
metadata_config.emit_bc = true;
|
||||||
allocator_config.emit_bc = true;
|
allocator_config.emit_bc = true;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
|
|||||||
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
|
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::{self, Lrc};
|
use rustc_data_structures::sync::{self, Lrc};
|
||||||
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
|
use rustc_errors::{DiagnosticBuilder, ErrorReported};
|
||||||
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
|
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
@ -296,16 +296,26 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait ProcMacro {
|
pub trait ProcMacro {
|
||||||
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt<'_>, span: Span, ts: TokenStream) -> TokenStream;
|
fn expand<'cx>(
|
||||||
|
&self,
|
||||||
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
|
span: Span,
|
||||||
|
ts: TokenStream,
|
||||||
|
) -> Result<TokenStream, ErrorReported>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> ProcMacro for F
|
impl<F> ProcMacro for F
|
||||||
where
|
where
|
||||||
F: Fn(TokenStream) -> TokenStream,
|
F: Fn(TokenStream) -> TokenStream,
|
||||||
{
|
{
|
||||||
fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream {
|
fn expand<'cx>(
|
||||||
|
&self,
|
||||||
|
_ecx: &'cx mut ExtCtxt<'_>,
|
||||||
|
_span: Span,
|
||||||
|
ts: TokenStream,
|
||||||
|
) -> Result<TokenStream, ErrorReported> {
|
||||||
// FIXME setup implicit context in TLS before calling self.
|
// FIXME setup implicit context in TLS before calling self.
|
||||||
(*self)(ts)
|
Ok((*self)(ts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +326,7 @@ pub trait AttrProcMacro {
|
|||||||
span: Span,
|
span: Span,
|
||||||
annotation: TokenStream,
|
annotation: TokenStream,
|
||||||
annotated: TokenStream,
|
annotated: TokenStream,
|
||||||
) -> TokenStream;
|
) -> Result<TokenStream, ErrorReported>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> AttrProcMacro for F
|
impl<F> AttrProcMacro for F
|
||||||
@ -329,9 +339,9 @@ where
|
|||||||
_span: Span,
|
_span: Span,
|
||||||
annotation: TokenStream,
|
annotation: TokenStream,
|
||||||
annotated: TokenStream,
|
annotated: TokenStream,
|
||||||
) -> TokenStream {
|
) -> Result<TokenStream, ErrorReported> {
|
||||||
// FIXME setup implicit context in TLS before calling self.
|
// FIXME setup implicit context in TLS before calling self.
|
||||||
(*self)(annotation, annotated)
|
Ok((*self)(annotation, annotated))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,31 +1014,9 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
self.current_expansion.id.expansion_cause()
|
self.current_expansion.id.expansion_cause()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
|
|
||||||
self.parse_sess.span_diagnostic.struct_span_warn(sp, msg)
|
|
||||||
}
|
|
||||||
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
|
self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
|
||||||
}
|
}
|
||||||
pub fn struct_span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
|
|
||||||
self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit `msg` attached to `sp`, and stop compilation immediately.
|
|
||||||
///
|
|
||||||
/// `span_err` should be strongly preferred where-ever possible:
|
|
||||||
/// this should *only* be used when:
|
|
||||||
///
|
|
||||||
/// - continuing has a high risk of flow-on errors (e.g., errors in
|
|
||||||
/// declaring a macro would cause all uses of that macro to
|
|
||||||
/// complain about "undefined macro"), or
|
|
||||||
/// - there is literally nothing else that can be done (however,
|
|
||||||
/// in most cases one can construct a dummy expression/item to
|
|
||||||
/// substitute; we never hit resolve/type-checking so the dummy
|
|
||||||
/// value doesn't have to match anything)
|
|
||||||
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
|
|
||||||
self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit `msg` attached to `sp`, without immediately stopping
|
/// Emit `msg` attached to `sp`, without immediately stopping
|
||||||
/// compilation.
|
/// compilation.
|
||||||
@ -1038,9 +1026,6 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
self.parse_sess.span_diagnostic.span_err(sp, msg);
|
self.parse_sess.span_diagnostic.span_err(sp, msg);
|
||||||
}
|
}
|
||||||
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
|
|
||||||
self.parse_sess.span_diagnostic.span_err_with_code(sp, msg, code);
|
|
||||||
}
|
|
||||||
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
self.parse_sess.span_diagnostic.span_warn(sp, msg);
|
self.parse_sess.span_diagnostic.span_warn(sp, msg);
|
||||||
}
|
}
|
||||||
@ -1168,6 +1153,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`.
|
||||||
|
pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
|
||||||
|
match p.parse_expr() {
|
||||||
|
Ok(e) => return Some(e),
|
||||||
|
Err(mut err) => err.emit(),
|
||||||
|
}
|
||||||
|
while p.token != token::Eof {
|
||||||
|
p.bump();
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Interpreting `tts` as a comma-separated sequence of expressions,
|
/// Interpreting `tts` as a comma-separated sequence of expressions,
|
||||||
/// expect exactly one string literal, or emit an error and return `None`.
|
/// expect exactly one string literal, or emit an error and return `None`.
|
||||||
pub fn get_single_str_from_tts(
|
pub fn get_single_str_from_tts(
|
||||||
@ -1181,7 +1178,7 @@ pub fn get_single_str_from_tts(
|
|||||||
cx.span_err(sp, &format!("{} takes 1 argument", name));
|
cx.span_err(sp, &format!("{} takes 1 argument", name));
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let ret = panictry!(p.parse_expr());
|
let ret = parse_expr(&mut p)?;
|
||||||
let _ = p.eat(&token::Comma);
|
let _ = p.eat(&token::Comma);
|
||||||
|
|
||||||
if p.token != token::Eof {
|
if p.token != token::Eof {
|
||||||
@ -1190,8 +1187,8 @@ pub fn get_single_str_from_tts(
|
|||||||
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string())
|
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts comma-separated expressions from `tts`. If there is a
|
/// Extracts comma-separated expressions from `tts`.
|
||||||
/// parsing error, emit a non-fatal error and return `None`.
|
/// On error, emit it, and return `None`.
|
||||||
pub fn get_exprs_from_tts(
|
pub fn get_exprs_from_tts(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
@ -1200,7 +1197,7 @@ pub fn get_exprs_from_tts(
|
|||||||
let mut p = cx.new_parser_from_tts(tts);
|
let mut p = cx.new_parser_from_tts(tts);
|
||||||
let mut es = Vec::new();
|
let mut es = Vec::new();
|
||||||
while p.token != token::Eof {
|
while p.token != token::Eof {
|
||||||
let expr = panictry!(p.parse_expr());
|
let expr = parse_expr(&mut p)?;
|
||||||
|
|
||||||
// Perform eager expansion on the expression.
|
// Perform eager expansion on the expression.
|
||||||
// We want to be able to handle e.g., `concat!("foo", "bar")`.
|
// We want to be able to handle e.g., `concat!("foo", "bar")`.
|
||||||
|
@ -204,7 +204,7 @@ ast_fragments! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AstFragmentKind {
|
impl AstFragmentKind {
|
||||||
fn dummy(self, span: Span) -> AstFragment {
|
crate fn dummy(self, span: Span) -> AstFragment {
|
||||||
self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
|
self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
InvocationKind::Bang { mac, .. } => match ext {
|
InvocationKind::Bang { mac, .. } => match ext {
|
||||||
SyntaxExtensionKind::Bang(expander) => {
|
SyntaxExtensionKind::Bang(expander) => {
|
||||||
self.gate_proc_macro_expansion_kind(span, fragment_kind);
|
self.gate_proc_macro_expansion_kind(span, fragment_kind);
|
||||||
let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
|
let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
|
||||||
|
Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
|
||||||
|
Ok(ts) => ts,
|
||||||
|
};
|
||||||
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
|
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
|
||||||
}
|
}
|
||||||
SyntaxExtensionKind::LegacyBang(expander) => {
|
SyntaxExtensionKind::LegacyBang(expander) => {
|
||||||
@ -709,8 +712,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
if let MacArgs::Eq(..) = attr_item.args {
|
if let MacArgs::Eq(..) = attr_item.args {
|
||||||
self.cx.span_err(span, "key-value macro attributes are not supported");
|
self.cx.span_err(span, "key-value macro attributes are not supported");
|
||||||
}
|
}
|
||||||
let tok_result =
|
let inner_tokens = attr_item.args.inner_tokens();
|
||||||
expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens);
|
let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) {
|
||||||
|
Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
|
||||||
|
Ok(ts) => ts,
|
||||||
|
};
|
||||||
self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
|
self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
|
||||||
}
|
}
|
||||||
SyntaxExtensionKind::LegacyAttr(expander) => {
|
SyntaxExtensionKind::LegacyAttr(expander) => {
|
||||||
@ -1139,6 +1145,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||||||
// macros are expanded before any lint passes so this warning has to be hardcoded
|
// macros are expanded before any lint passes so this warning has to be hardcoded
|
||||||
if attr.has_name(sym::derive) {
|
if attr.has_name(sym::derive) {
|
||||||
self.cx
|
self.cx
|
||||||
|
.parse_sess()
|
||||||
|
.span_diagnostic
|
||||||
.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
|
.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
|
||||||
.note("this may become a hard error in a future release")
|
.note("this may become a hard error in a future release")
|
||||||
.emit();
|
.emit();
|
||||||
|
@ -9,25 +9,6 @@
|
|||||||
|
|
||||||
extern crate proc_macro as pm;
|
extern crate proc_macro as pm;
|
||||||
|
|
||||||
// A variant of 'try!' that panics on an Err. This is used as a crutch on the
|
|
||||||
// way towards a non-panic!-prone parser. It should be used for fatal parsing
|
|
||||||
// errors; eventually we plan to convert all code using panictry to just use
|
|
||||||
// normal try.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! panictry {
|
|
||||||
($e:expr) => {{
|
|
||||||
use rustc_errors::FatalError;
|
|
||||||
use std::result::Result::{Err, Ok};
|
|
||||||
match $e {
|
|
||||||
Ok(e) => e,
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
FatalError.raise()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod placeholders;
|
mod placeholders;
|
||||||
mod proc_macro_server;
|
mod proc_macro_server;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ use rustc_parse::parser::{FollowedByType, Parser, PathStyle};
|
|||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
|
||||||
|
|
||||||
use rustc_errors::{FatalError, PResult};
|
use rustc_errors::PResult;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
@ -271,6 +271,7 @@ crate enum ParseResult<T> {
|
|||||||
Failure(Token, &'static str),
|
Failure(Token, &'static str),
|
||||||
/// Fatal error (malformed macro?). Abort compilation.
|
/// Fatal error (malformed macro?). Abort compilation.
|
||||||
Error(rustc_span::Span, String),
|
Error(rustc_span::Span, String),
|
||||||
|
ErrorReported,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `ParseResult` where the `Success` variant contains a mapping of
|
/// A `ParseResult` where the `Success` variant contains a mapping of
|
||||||
@ -652,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
|||||||
Success(_) => {}
|
Success(_) => {}
|
||||||
Failure(token, msg) => return Failure(token, msg),
|
Failure(token, msg) => return Failure(token, msg),
|
||||||
Error(sp, msg) => return Error(sp, msg),
|
Error(sp, msg) => return Error(sp, msg),
|
||||||
|
ErrorReported => return ErrorReported,
|
||||||
}
|
}
|
||||||
|
|
||||||
// inner parse loop handled all cur_items, so it's empty
|
// inner parse loop handled all cur_items, so it's empty
|
||||||
@ -735,10 +737,11 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
|||||||
let mut item = bb_items.pop().unwrap();
|
let mut item = bb_items.pop().unwrap();
|
||||||
if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) {
|
if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) {
|
||||||
let match_cur = item.match_cur;
|
let match_cur = item.match_cur;
|
||||||
item.push_match(
|
let nt = match parse_nt(parser.to_mut(), span, ident.name) {
|
||||||
match_cur,
|
Err(()) => return ErrorReported,
|
||||||
MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))),
|
Ok(nt) => nt,
|
||||||
);
|
};
|
||||||
|
item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
|
||||||
item.idx += 1;
|
item.idx += 1;
|
||||||
item.match_cur += 1;
|
item.match_cur += 1;
|
||||||
} else {
|
} else {
|
||||||
@ -849,20 +852,16 @@ fn may_begin_with(token: &Token, name: Name) -> bool {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// The parsed non-terminal.
|
/// The parsed non-terminal.
|
||||||
fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal {
|
fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result<Nonterminal, ()> {
|
||||||
// FIXME(Centril): Consider moving this to `parser.rs` to make
|
// FIXME(Centril): Consider moving this to `parser.rs` to make
|
||||||
// the visibilities of the methods used below `pub(super)` at most.
|
// the visibilities of the methods used below `pub(super)` at most.
|
||||||
|
|
||||||
if name == sym::tt {
|
if name == sym::tt {
|
||||||
return token::NtTT(p.parse_token_tree());
|
return Ok(token::NtTT(p.parse_token_tree()));
|
||||||
}
|
|
||||||
match parse_nt_inner(p, sp, name) {
|
|
||||||
Ok(nt) => nt,
|
|
||||||
Err(mut err) => {
|
|
||||||
err.emit();
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
parse_nt_inner(p, sp, name).map_err(|mut err| {
|
||||||
|
err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name))
|
||||||
|
.emit()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> {
|
fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> {
|
||||||
|
@ -4,7 +4,7 @@ use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstF
|
|||||||
use crate::mbe;
|
use crate::mbe;
|
||||||
use crate::mbe::macro_check;
|
use crate::mbe::macro_check;
|
||||||
use crate::mbe::macro_parser::parse_tt;
|
use crate::mbe::macro_parser::parse_tt;
|
||||||
use crate::mbe::macro_parser::{Error, Failure, Success};
|
use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success};
|
||||||
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
|
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
|
||||||
use crate::mbe::transcribe::transcribe;
|
use crate::mbe::transcribe::transcribe;
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
|
|||||||
use rustc_attr::{self as attr, TransparencyError};
|
use rustc_attr::{self as attr, TransparencyError};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, DiagnosticBuilder, FatalError};
|
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||||
use rustc_feature::Features;
|
use rustc_feature::Features;
|
||||||
use rustc_parse::parser::Parser;
|
use rustc_parse::parser::Parser;
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
@ -83,41 +83,56 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_frag_parse_err(
|
||||||
|
mut e: DiagnosticBuilder<'_>,
|
||||||
|
parser: &Parser<'_>,
|
||||||
|
site_span: Span,
|
||||||
|
macro_ident: ast::Ident,
|
||||||
|
arm_span: Span,
|
||||||
|
kind: AstFragmentKind,
|
||||||
|
) {
|
||||||
|
if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
|
||||||
|
if !e.span.is_dummy() {
|
||||||
|
// early end of macro arm (#52866)
|
||||||
|
e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
|
||||||
|
}
|
||||||
|
let msg = &e.message[0];
|
||||||
|
e.message[0] = (
|
||||||
|
format!(
|
||||||
|
"macro expansion ends with an incomplete expression: {}",
|
||||||
|
msg.0.replace(", found `<eof>`", ""),
|
||||||
|
),
|
||||||
|
msg.1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if e.span.is_dummy() {
|
||||||
|
// Get around lack of span in error (#30128)
|
||||||
|
e.replace_span_with(site_span);
|
||||||
|
if !parser.sess.source_map().is_imported(arm_span) {
|
||||||
|
e.span_label(arm_span, "in this macro arm");
|
||||||
|
}
|
||||||
|
} else if parser.sess.source_map().is_imported(parser.token.span) {
|
||||||
|
e.span_label(site_span, "in this macro invocation");
|
||||||
|
}
|
||||||
|
match kind {
|
||||||
|
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
|
||||||
|
suggest_slice_pat(&mut e, site_span, parser);
|
||||||
|
}
|
||||||
|
_ => annotate_err_with_kind(&mut e, kind, site_span),
|
||||||
|
};
|
||||||
|
e.emit();
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ParserAnyMacro<'a> {
|
impl<'a> ParserAnyMacro<'a> {
|
||||||
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
|
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
|
||||||
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
|
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
|
||||||
let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| {
|
let fragment = match parse_ast_fragment(parser, kind) {
|
||||||
if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
|
Ok(f) => f,
|
||||||
if !e.span.is_dummy() {
|
Err(err) => {
|
||||||
// early end of macro arm (#52866)
|
emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
|
||||||
e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
|
return kind.dummy(site_span);
|
||||||
}
|
|
||||||
let msg = &e.message[0];
|
|
||||||
e.message[0] = (
|
|
||||||
format!(
|
|
||||||
"macro expansion ends with an incomplete expression: {}",
|
|
||||||
msg.0.replace(", found `<eof>`", ""),
|
|
||||||
),
|
|
||||||
msg.1,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if e.span.is_dummy() {
|
};
|
||||||
// Get around lack of span in error (#30128)
|
|
||||||
e.replace_span_with(site_span);
|
|
||||||
if !parser.sess.source_map().is_imported(arm_span) {
|
|
||||||
e.span_label(arm_span, "in this macro arm");
|
|
||||||
}
|
|
||||||
} else if parser.sess.source_map().is_imported(parser.token.span) {
|
|
||||||
e.span_label(site_span, "in this macro invocation");
|
|
||||||
}
|
|
||||||
match kind {
|
|
||||||
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
|
|
||||||
suggest_slice_pat(&mut e, site_span, parser);
|
|
||||||
}
|
|
||||||
_ => annotate_err_with_kind(&mut e, kind, site_span),
|
|
||||||
};
|
|
||||||
e
|
|
||||||
}));
|
|
||||||
|
|
||||||
// We allow semicolons at the end of expressions -- e.g., the semicolon in
|
// We allow semicolons at the end of expressions -- e.g., the semicolon in
|
||||||
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
|
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
|
||||||
@ -165,6 +180,14 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn macro_rules_dummy_expander<'cx>(
|
||||||
|
_: &'cx mut ExtCtxt<'_>,
|
||||||
|
span: Span,
|
||||||
|
_: TokenStream,
|
||||||
|
) -> Box<dyn MacResult + 'cx> {
|
||||||
|
DummyResult::any(span)
|
||||||
|
}
|
||||||
|
|
||||||
fn trace_macros_note(cx_expansions: &mut FxHashMap<Span, Vec<String>>, sp: Span, message: String) {
|
fn trace_macros_note(cx_expansions: &mut FxHashMap<Span, Vec<String>>, sp: Span, message: String) {
|
||||||
let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
|
let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
|
||||||
cx_expansions.entry(sp).or_default().push(message);
|
cx_expansions.entry(sp).or_default().push(message);
|
||||||
@ -240,7 +263,13 @@ fn generic_extension<'cx>(
|
|||||||
|
|
||||||
let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
|
let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
|
||||||
// rhs has holes ( `$id` and `$(...)` that need filled)
|
// rhs has holes ( `$id` and `$(...)` that need filled)
|
||||||
let mut tts = transcribe(cx, &named_matches, rhs, transparency);
|
let mut tts = match transcribe(cx, &named_matches, rhs, transparency) {
|
||||||
|
Ok(tts) => tts,
|
||||||
|
Err(mut err) => {
|
||||||
|
err.emit();
|
||||||
|
return DummyResult::any(arm_span);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
||||||
// proper positions in error reporting, while maintaining the macro_backtrace.
|
// proper positions in error reporting, while maintaining the macro_backtrace.
|
||||||
@ -278,7 +307,12 @@ fn generic_extension<'cx>(
|
|||||||
Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
|
Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
|
||||||
_ => best_failure = Some((token, msg)),
|
_ => best_failure = Some((token, msg)),
|
||||||
},
|
},
|
||||||
Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
|
Error(err_sp, ref msg) => {
|
||||||
|
let span = err_sp.substitute_dummy(sp);
|
||||||
|
cx.struct_span_err(span, &msg).emit();
|
||||||
|
return DummyResult::any(span);
|
||||||
|
}
|
||||||
|
ErrorReported => return DummyResult::any(sp),
|
||||||
}
|
}
|
||||||
|
|
||||||
// The matcher was not `Success(..)`ful.
|
// The matcher was not `Success(..)`ful.
|
||||||
@ -337,6 +371,18 @@ pub fn compile_declarative_macro(
|
|||||||
def: &ast::Item,
|
def: &ast::Item,
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
) -> SyntaxExtension {
|
) -> SyntaxExtension {
|
||||||
|
let mk_syn_ext = |expander| {
|
||||||
|
SyntaxExtension::new(
|
||||||
|
sess,
|
||||||
|
SyntaxExtensionKind::LegacyBang(expander),
|
||||||
|
def.span,
|
||||||
|
Vec::new(),
|
||||||
|
edition,
|
||||||
|
def.ident.name,
|
||||||
|
&def.attrs,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let diag = &sess.span_diagnostic;
|
let diag = &sess.span_diagnostic;
|
||||||
let lhs_nm = ast::Ident::new(sym::lhs, def.span);
|
let lhs_nm = ast::Ident::new(sym::lhs, def.span);
|
||||||
let rhs_nm = ast::Ident::new(sym::rhs, def.span);
|
let rhs_nm = ast::Ident::new(sym::rhs, def.span);
|
||||||
@ -391,13 +437,15 @@ pub fn compile_declarative_macro(
|
|||||||
Failure(token, msg) => {
|
Failure(token, msg) => {
|
||||||
let s = parse_failure_msg(&token);
|
let s = parse_failure_msg(&token);
|
||||||
let sp = token.span.substitute_dummy(def.span);
|
let sp = token.span.substitute_dummy(def.span);
|
||||||
let mut err = sess.span_diagnostic.struct_span_fatal(sp, &s);
|
sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
|
||||||
err.span_label(sp, msg);
|
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
|
||||||
err.emit();
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
}
|
||||||
Error(sp, s) => {
|
Error(sp, msg) => {
|
||||||
sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
|
sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit();
|
||||||
|
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
|
||||||
|
}
|
||||||
|
ErrorReported => {
|
||||||
|
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -460,24 +508,14 @@ pub fn compile_declarative_macro(
|
|||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let expander: Box<_> = Box::new(MacroRulesMacroExpander {
|
mk_syn_ext(Box::new(MacroRulesMacroExpander {
|
||||||
name: def.ident,
|
name: def.ident,
|
||||||
span: def.span,
|
span: def.span,
|
||||||
transparency,
|
transparency,
|
||||||
lhses,
|
lhses,
|
||||||
rhses,
|
rhses,
|
||||||
valid,
|
valid,
|
||||||
});
|
}))
|
||||||
|
|
||||||
SyntaxExtension::new(
|
|
||||||
sess,
|
|
||||||
SyntaxExtensionKind::LegacyBang(expander),
|
|
||||||
def.span,
|
|
||||||
Vec::new(),
|
|
||||||
edition,
|
|
||||||
def.ident.name,
|
|
||||||
&def.attrs,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_lhs_nt_follows(
|
fn check_lhs_nt_follows(
|
||||||
|
@ -8,7 +8,7 @@ use rustc_ast::token::{self, NtTT, Token};
|
|||||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
|
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::pluralize;
|
use rustc_errors::{pluralize, PResult};
|
||||||
use rustc_span::hygiene::{ExpnId, Transparency};
|
use rustc_span::hygiene::{ExpnId, Transparency};
|
||||||
use rustc_span::symbol::MacroRulesNormalizedIdent;
|
use rustc_span::symbol::MacroRulesNormalizedIdent;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
@ -80,15 +80,15 @@ impl Iterator for Frame {
|
|||||||
/// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
|
/// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
|
||||||
///
|
///
|
||||||
/// Along the way, we do some additional error checking.
|
/// Along the way, we do some additional error checking.
|
||||||
pub(super) fn transcribe(
|
pub(super) fn transcribe<'a>(
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'a>,
|
||||||
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
|
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
|
||||||
src: Vec<mbe::TokenTree>,
|
src: Vec<mbe::TokenTree>,
|
||||||
transparency: Transparency,
|
transparency: Transparency,
|
||||||
) -> TokenStream {
|
) -> PResult<'a, TokenStream> {
|
||||||
// Nothing for us to transcribe...
|
// Nothing for us to transcribe...
|
||||||
if src.is_empty() {
|
if src.is_empty() {
|
||||||
return TokenStream::default();
|
return Ok(TokenStream::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
|
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
|
||||||
@ -152,7 +152,7 @@ pub(super) fn transcribe(
|
|||||||
Frame::Delimited { forest, span, .. } => {
|
Frame::Delimited { forest, span, .. } => {
|
||||||
if result_stack.is_empty() {
|
if result_stack.is_empty() {
|
||||||
// No results left to compute! We are back at the top-level.
|
// No results left to compute! We are back at the top-level.
|
||||||
return TokenStream::new(result);
|
return Ok(TokenStream::new(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step back into the parent Delimited.
|
// Step back into the parent Delimited.
|
||||||
@ -173,11 +173,11 @@ pub(super) fn transcribe(
|
|||||||
seq @ mbe::TokenTree::Sequence(..) => {
|
seq @ mbe::TokenTree::Sequence(..) => {
|
||||||
match lockstep_iter_size(&seq, interp, &repeats) {
|
match lockstep_iter_size(&seq, interp, &repeats) {
|
||||||
LockstepIterSize::Unconstrained => {
|
LockstepIterSize::Unconstrained => {
|
||||||
cx.span_fatal(
|
return Err(cx.struct_span_err(
|
||||||
seq.span(), /* blame macro writer */
|
seq.span(), /* blame macro writer */
|
||||||
"attempted to repeat an expression containing no syntax variables \
|
"attempted to repeat an expression containing no syntax variables \
|
||||||
matched as repeating at this depth",
|
matched as repeating at this depth",
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
LockstepIterSize::Contradiction(ref msg) => {
|
LockstepIterSize::Contradiction(ref msg) => {
|
||||||
@ -185,7 +185,7 @@ pub(super) fn transcribe(
|
|||||||
// happens when two meta-variables are used in the same repetition in a
|
// happens when two meta-variables are used in the same repetition in a
|
||||||
// sequence, but they come from different sequence matchers and repeat
|
// sequence, but they come from different sequence matchers and repeat
|
||||||
// different amounts.
|
// different amounts.
|
||||||
cx.span_fatal(seq.span(), &msg[..]);
|
return Err(cx.struct_span_err(seq.span(), &msg[..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
LockstepIterSize::Constraint(len, _) => {
|
LockstepIterSize::Constraint(len, _) => {
|
||||||
@ -203,7 +203,10 @@ pub(super) fn transcribe(
|
|||||||
// FIXME: this really ought to be caught at macro definition
|
// FIXME: this really ought to be caught at macro definition
|
||||||
// time... It happens when the Kleene operator in the matcher and
|
// time... It happens when the Kleene operator in the matcher and
|
||||||
// the body for the same meta-variable do not match.
|
// the body for the same meta-variable do not match.
|
||||||
cx.span_fatal(sp.entire(), "this must repeat at least once");
|
return Err(cx.struct_span_err(
|
||||||
|
sp.entire(),
|
||||||
|
"this must repeat at least once",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 0 is the initial counter (we have done 0 repretitions so far). `len`
|
// 0 is the initial counter (we have done 0 repretitions so far). `len`
|
||||||
@ -242,10 +245,10 @@ pub(super) fn transcribe(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We were unable to descend far enough. This is an error.
|
// We were unable to descend far enough. This is an error.
|
||||||
cx.span_fatal(
|
return Err(cx.struct_span_err(
|
||||||
sp, /* blame the macro writer */
|
sp, /* blame the macro writer */
|
||||||
&format!("variable '{}' is still repeating at this depth", ident),
|
&format!("variable '{}' is still repeating at this depth", ident),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we aren't able to match the meta-var, we push it back into the result but
|
// If we aren't able to match the meta-var, we push it back into the result but
|
||||||
|
@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
|
|||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::tokenstream::{self, TokenStream};
|
use rustc_ast::tokenstream::{self, TokenStream};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, FatalError};
|
use rustc_errors::{Applicability, ErrorReported};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
@ -21,21 +21,16 @@ impl base::ProcMacro for BangProcMacro {
|
|||||||
ecx: &'cx mut ExtCtxt<'_>,
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
input: TokenStream,
|
input: TokenStream,
|
||||||
) -> TokenStream {
|
) -> Result<TokenStream, ErrorReported> {
|
||||||
let server = proc_macro_server::Rustc::new(ecx);
|
let server = proc_macro_server::Rustc::new(ecx);
|
||||||
match self.client.run(&EXEC_STRATEGY, server, input) {
|
self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| {
|
||||||
Ok(stream) => stream,
|
let mut err = ecx.struct_span_err(span, "proc macro panicked");
|
||||||
Err(e) => {
|
if let Some(s) = e.as_str() {
|
||||||
let msg = "proc macro panicked";
|
err.help(&format!("message: {}", s));
|
||||||
let mut err = ecx.struct_span_fatal(span, msg);
|
|
||||||
if let Some(s) = e.as_str() {
|
|
||||||
err.help(&format!("message: {}", s));
|
|
||||||
}
|
|
||||||
|
|
||||||
err.emit();
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
}
|
||||||
}
|
err.emit();
|
||||||
|
ErrorReported
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,21 +45,16 @@ impl base::AttrProcMacro for AttrProcMacro {
|
|||||||
span: Span,
|
span: Span,
|
||||||
annotation: TokenStream,
|
annotation: TokenStream,
|
||||||
annotated: TokenStream,
|
annotated: TokenStream,
|
||||||
) -> TokenStream {
|
) -> Result<TokenStream, ErrorReported> {
|
||||||
let server = proc_macro_server::Rustc::new(ecx);
|
let server = proc_macro_server::Rustc::new(ecx);
|
||||||
match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) {
|
self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| {
|
||||||
Ok(stream) => stream,
|
let mut err = ecx.struct_span_err(span, "custom attribute panicked");
|
||||||
Err(e) => {
|
if let Some(s) = e.as_str() {
|
||||||
let msg = "custom attribute panicked";
|
err.help(&format!("message: {}", s));
|
||||||
let mut err = ecx.struct_span_fatal(span, msg);
|
|
||||||
if let Some(s) = e.as_str() {
|
|
||||||
err.help(&format!("message: {}", s));
|
|
||||||
}
|
|
||||||
|
|
||||||
err.emit();
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
}
|
||||||
}
|
err.emit();
|
||||||
|
ErrorReported
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +86,7 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||||||
| Annotatable::Expr(_) => {
|
| Annotatable::Expr(_) => {
|
||||||
ecx.span_err(
|
ecx.span_err(
|
||||||
span,
|
span,
|
||||||
"proc-macro derives may only be \
|
"proc-macro derives may only be applied to a struct, enum, or union",
|
||||||
applied to a struct, enum, or union",
|
|
||||||
);
|
);
|
||||||
return ExpandResult::Ready(Vec::new());
|
return ExpandResult::Ready(Vec::new());
|
||||||
}
|
}
|
||||||
@ -107,8 +96,7 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||||||
_ => {
|
_ => {
|
||||||
ecx.span_err(
|
ecx.span_err(
|
||||||
span,
|
span,
|
||||||
"proc-macro derives may only be \
|
"proc-macro derives may only be applied to a struct, enum, or union",
|
||||||
applied to a struct, enum, or union",
|
|
||||||
);
|
);
|
||||||
return ExpandResult::Ready(Vec::new());
|
return ExpandResult::Ready(Vec::new());
|
||||||
}
|
}
|
||||||
@ -121,20 +109,16 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||||||
let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
|
let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
|
||||||
Ok(stream) => stream,
|
Ok(stream) => stream,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let msg = "proc-macro derive panicked";
|
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
|
||||||
let mut err = ecx.struct_span_fatal(span, msg);
|
|
||||||
if let Some(s) = e.as_str() {
|
if let Some(s) = e.as_str() {
|
||||||
err.help(&format!("message: {}", s));
|
err.help(&format!("message: {}", s));
|
||||||
}
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
FatalError.raise();
|
return ExpandResult::Ready(vec![]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
|
let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
|
||||||
let msg = "proc-macro derive produced unparseable tokens";
|
|
||||||
|
|
||||||
let mut parser =
|
let mut parser =
|
||||||
rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
|
rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
@ -144,18 +128,15 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||||||
Ok(None) => break,
|
Ok(None) => break,
|
||||||
Ok(Some(item)) => items.push(Annotatable::Item(item)),
|
Ok(Some(item)) => items.push(Annotatable::Item(item)),
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
// FIXME: handle this better
|
err.emit();
|
||||||
err.cancel();
|
break;
|
||||||
ecx.struct_span_fatal(span, msg).emit();
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail if there have been errors emitted
|
// fail if there have been errors emitted
|
||||||
if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
|
if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
|
||||||
ecx.struct_span_fatal(span, msg).emit();
|
ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit();
|
||||||
FatalError.raise();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandResult::Ready(items)
|
ExpandResult::Ready(items)
|
||||||
|
@ -159,6 +159,7 @@ impl DefKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The resolution of a path or export.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum Res<Id = hir::HirId> {
|
pub enum Res<Id = hir::HirId> {
|
||||||
|
@ -19,7 +19,7 @@ use rustc::traits::select;
|
|||||||
use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||||
use rustc::ty::fold::{TypeFoldable, TypeFolder};
|
use rustc::ty::fold::{TypeFoldable, TypeFolder};
|
||||||
use rustc::ty::relate::RelateResult;
|
use rustc::ty::relate::RelateResult;
|
||||||
use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
|
use rustc::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
|
||||||
pub use rustc::ty::IntVarValue;
|
pub use rustc::ty::IntVarValue;
|
||||||
use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
|
use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
|
||||||
use rustc::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
use rustc::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
||||||
@ -501,6 +501,7 @@ impl NLLRegionVariableOrigin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum FixupError<'tcx> {
|
pub enum FixupError<'tcx> {
|
||||||
UnresolvedIntTy(IntVid),
|
UnresolvedIntTy(IntVid),
|
||||||
@ -1347,8 +1348,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let mut r = ShallowResolver::new(self);
|
value.fold_with(&mut ShallowResolver { infcx: self })
|
||||||
value.fold_with(&mut r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
||||||
@ -1551,22 +1551,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
// variables, thus we don't need to substitute back the original values.
|
// variables, thus we don't need to substitute back the original values.
|
||||||
self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
|
self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ShallowResolver<'a, 'tcx> {
|
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
|
|
||||||
ShallowResolver { infcx }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If `typ` is a type variable of some kind, resolve it one level
|
/// If `typ` is a type variable of some kind, resolve it one level
|
||||||
/// (but do not resolve types found in the result). If `typ` is
|
/// (but do not resolve types found in the result). If `typ` is
|
||||||
/// not a type variable, just return it unmodified.
|
/// not a type variable, just return it unmodified.
|
||||||
pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
// FIXME(eddyb) inline into `ShallowResolver::visit_ty`.
|
||||||
|
fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match typ.kind {
|
match typ.kind {
|
||||||
ty::Infer(ty::TyVar(v)) => {
|
ty::Infer(ty::TyVar(v)) => {
|
||||||
// Not entirely obvious: if `typ` is a type variable,
|
// Not entirely obvious: if `typ` is a type variable,
|
||||||
@ -1580,78 +1570,142 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
|
|||||||
// depth.
|
// depth.
|
||||||
//
|
//
|
||||||
// Note: if these two lines are combined into one we get
|
// Note: if these two lines are combined into one we get
|
||||||
// dynamic borrow errors on `self.infcx.inner`.
|
// dynamic borrow errors on `self.inner`.
|
||||||
let known = self.infcx.inner.borrow_mut().type_variables.probe(v).known();
|
let known = self.inner.borrow_mut().type_variables.probe(v).known();
|
||||||
known.map(|t| self.fold_ty(t)).unwrap_or(typ)
|
known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Infer(ty::IntVar(v)) => self
|
ty::Infer(ty::IntVar(v)) => self
|
||||||
.infcx
|
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.int_unification_table
|
.int_unification_table
|
||||||
.probe_value(v)
|
.probe_value(v)
|
||||||
.map(|v| v.to_type(self.infcx.tcx))
|
.map(|v| v.to_type(self.tcx))
|
||||||
.unwrap_or(typ),
|
.unwrap_or(typ),
|
||||||
|
|
||||||
ty::Infer(ty::FloatVar(v)) => self
|
ty::Infer(ty::FloatVar(v)) => self
|
||||||
.infcx
|
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.float_unification_table
|
.float_unification_table
|
||||||
.probe_value(v)
|
.probe_value(v)
|
||||||
.map(|v| v.to_type(self.infcx.tcx))
|
.map(|v| v.to_type(self.tcx))
|
||||||
.unwrap_or(typ),
|
.unwrap_or(typ),
|
||||||
|
|
||||||
_ => typ,
|
_ => typ,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `resolver.shallow_resolve_changed(ty)` is equivalent to
|
/// `ty_or_const_infer_var_changed` is equivalent to one of these two:
|
||||||
// `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
|
/// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
|
||||||
// inlined, despite being large, because it has only two call sites that
|
/// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
|
||||||
// are extremely hot.
|
///
|
||||||
|
/// However, `ty_or_const_infer_var_changed` is more efficient. It's always
|
||||||
|
/// inlined, despite being large, because it has only two call sites that
|
||||||
|
/// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on`
|
||||||
|
/// inference variables), and it handles both `Ty` and `ty::Const` without
|
||||||
|
/// having to resort to storing full `GenericArg`s in `stalled_on`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool {
|
pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool {
|
||||||
match infer {
|
match infer_var {
|
||||||
ty::TyVar(v) => {
|
TyOrConstInferVar::Ty(v) => {
|
||||||
use self::type_variable::TypeVariableValue;
|
use self::type_variable::TypeVariableValue;
|
||||||
|
|
||||||
// If `inlined_probe` returns a `Known` value its `kind` never
|
// If `inlined_probe` returns a `Known` value, it never equals
|
||||||
// matches `infer`.
|
// `ty::Infer(ty::TyVar(v))`.
|
||||||
match self.infcx.inner.borrow_mut().type_variables.inlined_probe(v) {
|
match self.inner.borrow_mut().type_variables.inlined_probe(v) {
|
||||||
TypeVariableValue::Unknown { .. } => false,
|
TypeVariableValue::Unknown { .. } => false,
|
||||||
TypeVariableValue::Known { .. } => true,
|
TypeVariableValue::Known { .. } => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::IntVar(v) => {
|
TyOrConstInferVar::TyInt(v) => {
|
||||||
// If inlined_probe_value returns a value it's always a
|
// If `inlined_probe_value` returns a value it's always a
|
||||||
// `ty::Int(_)` or `ty::UInt(_)`, which never matches a
|
// `ty::Int(_)` or `ty::UInt(_)`, which never matches a
|
||||||
// `ty::Infer(_)`.
|
// `ty::Infer(_)`.
|
||||||
self.infcx.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
|
self.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FloatVar(v) => {
|
TyOrConstInferVar::TyFloat(v) => {
|
||||||
// If inlined_probe_value returns a value it's always a
|
// If `probe_value` returns a value it's always a
|
||||||
// `ty::Float(_)`, which never matches a `ty::Infer(_)`.
|
// `ty::Float(_)`, which never matches a `ty::Infer(_)`.
|
||||||
//
|
//
|
||||||
// Not `inlined_probe_value(v)` because this call site is colder.
|
// Not `inlined_probe_value(v)` because this call site is colder.
|
||||||
self.infcx.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
|
self.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => unreachable!(),
|
TyOrConstInferVar::Const(v) => {
|
||||||
|
// If `probe_value` returns a `Known` value, it never equals
|
||||||
|
// `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
|
||||||
|
//
|
||||||
|
// Not `inlined_probe_value(v)` because this call site is colder.
|
||||||
|
match self.inner.borrow_mut().const_unification_table.probe_value(v).val {
|
||||||
|
ConstVariableValue::Unknown { .. } => false,
|
||||||
|
ConstVariableValue::Known { .. } => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently
|
||||||
|
/// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum TyOrConstInferVar<'tcx> {
|
||||||
|
/// Equivalent to `ty::Infer(ty::TyVar(_))`.
|
||||||
|
Ty(TyVid),
|
||||||
|
/// Equivalent to `ty::Infer(ty::IntVar(_))`.
|
||||||
|
TyInt(IntVid),
|
||||||
|
/// Equivalent to `ty::Infer(ty::FloatVar(_))`.
|
||||||
|
TyFloat(FloatVid),
|
||||||
|
|
||||||
|
/// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
|
||||||
|
Const(ConstVid<'tcx>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TyOrConstInferVar<'tcx> {
|
||||||
|
/// Tries to extract an inference variable from a type or a constant, returns `None`
|
||||||
|
/// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
|
||||||
|
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
|
||||||
|
pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option<Self> {
|
||||||
|
match arg.unpack() {
|
||||||
|
GenericArgKind::Type(ty) => Self::maybe_from_ty(ty),
|
||||||
|
GenericArgKind::Const(ct) => Self::maybe_from_const(ct),
|
||||||
|
GenericArgKind::Lifetime(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to extract an inference variable from a type, returns `None`
|
||||||
|
/// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`).
|
||||||
|
pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option<Self> {
|
||||||
|
match ty.kind {
|
||||||
|
ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)),
|
||||||
|
ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)),
|
||||||
|
ty::Infer(ty::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to extract an inference variable from a constant, returns `None`
|
||||||
|
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
|
||||||
|
pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self> {
|
||||||
|
match ct.val {
|
||||||
|
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ShallowResolver<'a, 'tcx> {
|
||||||
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
self.shallow_resolve(ty)
|
self.infcx.shallow_resolve_ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
|
@ -509,14 +509,6 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
|
|
||||||
fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
|
|
||||||
// FIXME(jseyfried): intercrate hygiene
|
|
||||||
|
|
||||||
Ok(Ident::with_dummy_span(Symbol::decode(self)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
|
||||||
Fingerprint::decode_opaque(&mut self.opaque)
|
Fingerprint::decode_opaque(&mut self.opaque)
|
||||||
@ -663,15 +655,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
&self.raw_proc_macros.unwrap()[pos]
|
&self.raw_proc_macros.unwrap()[pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_name(&self, item_index: DefIndex) -> Symbol {
|
fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident {
|
||||||
if !self.is_proc_macro(item_index) {
|
if !self.is_proc_macro(item_index) {
|
||||||
self.def_key(item_index)
|
let name = self
|
||||||
|
.def_key(item_index)
|
||||||
.disambiguated_data
|
.disambiguated_data
|
||||||
.data
|
.data
|
||||||
.get_opt_name()
|
.get_opt_name()
|
||||||
.expect("no name in item_name")
|
.expect("no name in item_ident");
|
||||||
|
let span = self
|
||||||
|
.root
|
||||||
|
.per_def
|
||||||
|
.ident_span
|
||||||
|
.get(self, item_index)
|
||||||
|
.map(|data| data.decode((self, sess)))
|
||||||
|
.unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index));
|
||||||
|
Ident::new(name, span)
|
||||||
} else {
|
} else {
|
||||||
Symbol::intern(self.raw_proc_macro(item_index).name())
|
Ident::new(
|
||||||
|
Symbol::intern(self.raw_proc_macro(item_index).name()),
|
||||||
|
self.get_span(item_index, sess),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,6 +754,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
kind: &EntryKind,
|
kind: &EntryKind,
|
||||||
index: DefIndex,
|
index: DefIndex,
|
||||||
parent_did: DefId,
|
parent_did: DefId,
|
||||||
|
sess: &Session,
|
||||||
) -> ty::VariantDef {
|
) -> ty::VariantDef {
|
||||||
let data = match kind {
|
let data = match kind {
|
||||||
EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
|
EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
|
||||||
@ -771,7 +776,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
|
|
||||||
ty::VariantDef::new(
|
ty::VariantDef::new(
|
||||||
tcx,
|
tcx,
|
||||||
Ident::with_dummy_span(self.item_name(index)),
|
self.item_ident(index, sess),
|
||||||
variant_did,
|
variant_did,
|
||||||
ctor_did,
|
ctor_did,
|
||||||
data.discr,
|
data.discr,
|
||||||
@ -783,7 +788,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
.decode(self)
|
.decode(self)
|
||||||
.map(|index| ty::FieldDef {
|
.map(|index| ty::FieldDef {
|
||||||
did: self.local_def_id(index),
|
did: self.local_def_id(index),
|
||||||
ident: Ident::with_dummy_span(self.item_name(index)),
|
ident: self.item_ident(index, sess),
|
||||||
vis: self.get_visibility(index),
|
vis: self.get_visibility(index),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -812,10 +817,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
.get(self, item_id)
|
.get(self, item_id)
|
||||||
.unwrap_or(Lazy::empty())
|
.unwrap_or(Lazy::empty())
|
||||||
.decode(self)
|
.decode(self)
|
||||||
.map(|index| self.get_variant(tcx, &self.kind(index), index, did))
|
.map(|index| self.get_variant(tcx, &self.kind(index), index, did, tcx.sess))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
std::iter::once(self.get_variant(tcx, &kind, item_id, did)).collect()
|
std::iter::once(self.get_variant(tcx, &kind, item_id, did, tcx.sess)).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
tcx.alloc_adt_def(did, adt_kind, variants, repr)
|
tcx.alloc_adt_def(did, adt_kind, variants, repr)
|
||||||
@ -1007,7 +1012,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
if let Some(kind) = self.def_kind(child_index) {
|
if let Some(kind) = self.def_kind(child_index) {
|
||||||
callback(Export {
|
callback(Export {
|
||||||
res: Res::Def(kind, self.local_def_id(child_index)),
|
res: Res::Def(kind, self.local_def_id(child_index)),
|
||||||
ident: Ident::with_dummy_span(self.item_name(child_index)),
|
ident: self.item_ident(child_index, sess),
|
||||||
vis: self.get_visibility(child_index),
|
vis: self.get_visibility(child_index),
|
||||||
span: self
|
span: self
|
||||||
.root
|
.root
|
||||||
@ -1028,10 +1033,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
|
|
||||||
let def_key = self.def_key(child_index);
|
let def_key = self.def_key(child_index);
|
||||||
let span = self.get_span(child_index, sess);
|
let span = self.get_span(child_index, sess);
|
||||||
if let (Some(kind), Some(name)) =
|
if let (Some(kind), true) = (
|
||||||
(self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name())
|
self.def_kind(child_index),
|
||||||
{
|
def_key.disambiguated_data.data.get_opt_name().is_some(),
|
||||||
let ident = Ident::with_dummy_span(name);
|
) {
|
||||||
|
let ident = self.item_ident(child_index, sess);
|
||||||
let vis = self.get_visibility(child_index);
|
let vis = self.get_visibility(child_index);
|
||||||
let def_id = self.local_def_id(child_index);
|
let def_id = self.local_def_id(child_index);
|
||||||
let res = Res::Def(kind, def_id);
|
let res = Res::Def(kind, def_id);
|
||||||
@ -1138,10 +1144,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
|
fn get_associated_item(&self, id: DefIndex, sess: &Session) -> ty::AssocItem {
|
||||||
let def_key = self.def_key(id);
|
let def_key = self.def_key(id);
|
||||||
let parent = self.local_def_id(def_key.parent.unwrap());
|
let parent = self.local_def_id(def_key.parent.unwrap());
|
||||||
let name = def_key.disambiguated_data.data.get_opt_name().unwrap();
|
let ident = self.item_ident(id, sess);
|
||||||
|
|
||||||
let (kind, container, has_self) = match self.kind(id) {
|
let (kind, container, has_self) = match self.kind(id) {
|
||||||
EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
|
EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
|
||||||
@ -1155,7 +1161,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ty::AssocItem {
|
ty::AssocItem {
|
||||||
ident: Ident::with_dummy_span(name),
|
ident,
|
||||||
kind,
|
kind,
|
||||||
vis: self.get_visibility(id),
|
vis: self.get_visibility(id),
|
||||||
defaultness: container.defaultness(),
|
defaultness: container.defaultness(),
|
||||||
@ -1219,7 +1225,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
.get(self, id)
|
.get(self, id)
|
||||||
.unwrap_or(Lazy::empty())
|
.unwrap_or(Lazy::empty())
|
||||||
.decode(self)
|
.decode(self)
|
||||||
.map(|index| respan(self.get_span(index, sess), self.item_name(index)))
|
.map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||||||
|child| result.push(child.res.def_id()), tcx.sess);
|
|child| result.push(child.res.def_id()), tcx.sess);
|
||||||
tcx.arena.alloc_slice(&result)
|
tcx.arena.alloc_slice(&result)
|
||||||
}
|
}
|
||||||
associated_item => { cdata.get_associated_item(def_id.index) }
|
associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
|
||||||
impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
|
impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
|
||||||
impl_polarity => { cdata.get_impl_polarity(def_id.index) }
|
impl_polarity => { cdata.get_impl_polarity(def_id.index) }
|
||||||
coerce_unsized_info => {
|
coerce_unsized_info => {
|
||||||
@ -442,8 +442,8 @@ impl CStore {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
|
pub fn associated_item_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::AssocItem {
|
||||||
self.get_crate_data(def.krate).get_associated_item(def.index)
|
self.get_crate_data(def.krate).get_associated_item(def.index, sess)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
|
pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
|
||||||
|
@ -12,7 +12,7 @@ use rustc::traits::specialization_graph;
|
|||||||
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
||||||
use rustc::ty::layout::VariantIdx;
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::ty::{self, SymbolName, Ty, TyCtxt};
|
use rustc::ty::{self, SymbolName, Ty, TyCtxt};
|
||||||
use rustc_ast::ast;
|
use rustc_ast::ast::{self, Ident};
|
||||||
use rustc_ast::attr;
|
use rustc_ast::attr;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
@ -30,7 +30,7 @@ use rustc_index::vec::Idx;
|
|||||||
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
|
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
|
||||||
use rustc_session::config::{self, CrateType};
|
use rustc_session::config::{self, CrateType};
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span};
|
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
@ -220,13 +220,6 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
|
|
||||||
fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
|
|
||||||
// FIXME(jseyfried): intercrate hygiene
|
|
||||||
ident.name.encode(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
|
impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
|
||||||
@ -633,6 +626,7 @@ impl EncodeContext<'tcx> {
|
|||||||
assert!(f.did.is_local());
|
assert!(f.did.is_local());
|
||||||
f.did.index
|
f.did.index
|
||||||
}));
|
}));
|
||||||
|
self.encode_ident_span(def_id, variant.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
@ -735,6 +729,7 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.visibility[def_id] <- field.vis);
|
record!(self.per_def.visibility[def_id] <- field.vis);
|
||||||
record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
|
record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
|
||||||
record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs);
|
record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs);
|
||||||
|
self.encode_ident_span(def_id, field.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
@ -869,6 +864,7 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.visibility[def_id] <- trait_item.vis);
|
record!(self.per_def.visibility[def_id] <- trait_item.vis);
|
||||||
record!(self.per_def.span[def_id] <- ast_item.span);
|
record!(self.per_def.span[def_id] <- ast_item.span);
|
||||||
record!(self.per_def.attributes[def_id] <- ast_item.attrs);
|
record!(self.per_def.attributes[def_id] <- ast_item.attrs);
|
||||||
|
self.encode_ident_span(def_id, ast_item.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_const_stability(def_id);
|
self.encode_const_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
@ -952,6 +948,7 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.visibility[def_id] <- impl_item.vis);
|
record!(self.per_def.visibility[def_id] <- impl_item.vis);
|
||||||
record!(self.per_def.span[def_id] <- ast_item.span);
|
record!(self.per_def.span[def_id] <- ast_item.span);
|
||||||
record!(self.per_def.attributes[def_id] <- ast_item.attrs);
|
record!(self.per_def.attributes[def_id] <- ast_item.attrs);
|
||||||
|
self.encode_ident_span(def_id, impl_item.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_const_stability(def_id);
|
self.encode_const_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
@ -1058,6 +1055,8 @@ impl EncodeContext<'tcx> {
|
|||||||
|
|
||||||
debug!("EncodeContext::encode_info_for_item({:?})", def_id);
|
debug!("EncodeContext::encode_info_for_item({:?})", def_id);
|
||||||
|
|
||||||
|
self.encode_ident_span(def_id, item.ident);
|
||||||
|
|
||||||
record!(self.per_def.kind[def_id] <- match item.kind {
|
record!(self.per_def.kind[def_id] <- match item.kind {
|
||||||
hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
|
hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
|
||||||
hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic,
|
hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic,
|
||||||
@ -1284,6 +1283,7 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
|
record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
|
||||||
record!(self.per_def.span[def_id] <- macro_def.span);
|
record!(self.per_def.span[def_id] <- macro_def.span);
|
||||||
record!(self.per_def.attributes[def_id] <- macro_def.attrs);
|
record!(self.per_def.attributes[def_id] <- macro_def.attrs);
|
||||||
|
self.encode_ident_span(def_id, macro_def.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
}
|
}
|
||||||
@ -1528,6 +1528,7 @@ impl EncodeContext<'tcx> {
|
|||||||
ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
|
ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
|
||||||
record!(self.per_def.span[def_id] <- nitem.span);
|
record!(self.per_def.span[def_id] <- nitem.span);
|
||||||
record!(self.per_def.attributes[def_id] <- nitem.attrs);
|
record!(self.per_def.attributes[def_id] <- nitem.attrs);
|
||||||
|
self.encode_ident_span(def_id, nitem.ident);
|
||||||
self.encode_stability(def_id);
|
self.encode_stability(def_id);
|
||||||
self.encode_const_stability(def_id);
|
self.encode_const_stability(def_id);
|
||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
@ -1622,6 +1623,10 @@ impl EncodeContext<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) {
|
||||||
|
record!(self.per_def.ident_span[def_id] <- ident.span);
|
||||||
|
}
|
||||||
|
|
||||||
/// In some cases, along with the item itself, we also
|
/// In some cases, along with the item itself, we also
|
||||||
/// encode some sub-items. Usually we want some info from the item
|
/// encode some sub-items. Usually we want some info from the item
|
||||||
/// so it's easier to do that here then to wait until we would encounter
|
/// so it's easier to do that here then to wait until we would encounter
|
||||||
|
@ -256,6 +256,7 @@ define_per_def_tables! {
|
|||||||
kind: Table<DefIndex, Lazy<EntryKind>>,
|
kind: Table<DefIndex, Lazy<EntryKind>>,
|
||||||
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
|
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
|
||||||
span: Table<DefIndex, Lazy<Span>>,
|
span: Table<DefIndex, Lazy<Span>>,
|
||||||
|
ident_span: Table<DefIndex, Lazy<Span>>,
|
||||||
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
|
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
|
||||||
children: Table<DefIndex, Lazy<[DefIndex]>>,
|
children: Table<DefIndex, Lazy<[DefIndex]>>,
|
||||||
stability: Table<DefIndex, Lazy<attr::Stability>>,
|
stability: Table<DefIndex, Lazy<attr::Stability>>,
|
||||||
|
@ -337,14 +337,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||||||
) -> ConstPropagator<'mir, 'tcx> {
|
) -> ConstPropagator<'mir, 'tcx> {
|
||||||
let def_id = source.def_id();
|
let def_id = source.def_id();
|
||||||
let substs = &InternalSubsts::identity_for_item(tcx, def_id);
|
let substs = &InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
let mut param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id).with_reveal_all();
|
||||||
|
|
||||||
// If we're evaluating inside a monomorphic function, then use `Reveal::All` because
|
|
||||||
// we want to see the same instances that codegen will see. This allows us to `resolve()`
|
|
||||||
// specializations.
|
|
||||||
if !substs.needs_subst() {
|
|
||||||
param_env = param_env.with_reveal_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());
|
let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc::mir::visit::*;
|
use rustc::mir::visit::*;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
|
use rustc::ty::subst::{Subst, SubstsRef};
|
||||||
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
@ -66,14 +66,7 @@ impl Inliner<'tcx> {
|
|||||||
|
|
||||||
let mut callsites = VecDeque::new();
|
let mut callsites = VecDeque::new();
|
||||||
|
|
||||||
let mut param_env = self.tcx.param_env(self.source.def_id());
|
let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all();
|
||||||
|
|
||||||
let substs = &InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
|
|
||||||
|
|
||||||
// For monomorphic functions, we can use `Reveal::All` to resolve specialized instances.
|
|
||||||
if !substs.needs_subst() {
|
|
||||||
param_env = param_env.with_reveal_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only do inlining into fn bodies.
|
// Only do inlining into fn bodies.
|
||||||
let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();
|
let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();
|
||||||
|
@ -139,7 +139,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
|||||||
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
|
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
|
||||||
|
|
||||||
let (yield_ty, return_ty) = if body.generator_kind.is_some() {
|
let (yield_ty, return_ty) = if body.generator_kind.is_some() {
|
||||||
let gen_sig = match ty.kind {
|
let gen_ty = tcx.body_tables(body_id).node_type(id);
|
||||||
|
let gen_sig = match gen_ty.kind {
|
||||||
ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
|
ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
|
||||||
_ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
|
_ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
|
||||||
};
|
};
|
||||||
|
@ -904,7 +904,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||||||
self.insert_field_names(def_id, field_names);
|
self.insert_field_names(def_id, field_names);
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::AssocFn, def_id) => {
|
Res::Def(DefKind::AssocFn, def_id) => {
|
||||||
if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
|
if cstore
|
||||||
|
.associated_item_cloned_untracked(def_id, self.r.session)
|
||||||
|
.method_has_self_argument
|
||||||
|
{
|
||||||
self.r.has_self.insert(def_id);
|
self.r.has_self.insert(def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::infer::{InferCtxt, ShallowResolver};
|
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
||||||
use rustc::ty::error::ExpectedFound;
|
use rustc::ty::error::ExpectedFound;
|
||||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
|
use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
|
||||||
use rustc_data_structures::obligation_forest::ProcessResult;
|
use rustc_data_structures::obligation_forest::ProcessResult;
|
||||||
@ -73,7 +73,10 @@ pub struct FulfillmentContext<'tcx> {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PendingPredicateObligation<'tcx> {
|
pub struct PendingPredicateObligation<'tcx> {
|
||||||
pub obligation: PredicateObligation<'tcx>,
|
pub obligation: PredicateObligation<'tcx>,
|
||||||
pub stalled_on: Vec<ty::InferTy>,
|
// FIXME(eddyb) look into whether this could be a `SmallVec`.
|
||||||
|
// Judging by the comment in `process_obligation`, the 1-element case
|
||||||
|
// is common so this could be a `SmallVec<[TyOrConstInferVar<'tcx>; 1]>`.
|
||||||
|
pub stalled_on: Vec<TyOrConstInferVar<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
@ -266,8 +269,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
// Match arms are in order of frequency, which matters because this
|
// Match arms are in order of frequency, which matters because this
|
||||||
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
|
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
|
||||||
1 => {
|
1 => {
|
||||||
let infer = pending_obligation.stalled_on[0];
|
let infer_var = pending_obligation.stalled_on[0];
|
||||||
ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer)
|
self.selcx.infcx().ty_or_const_infer_var_changed(infer_var)
|
||||||
}
|
}
|
||||||
0 => {
|
0 => {
|
||||||
// In this case we haven't changed, but wish to make a change.
|
// In this case we haven't changed, but wish to make a change.
|
||||||
@ -277,8 +280,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
// This `for` loop was once a call to `all()`, but this lower-level
|
// This `for` loop was once a call to `all()`, but this lower-level
|
||||||
// form was a perf win. See #64545 for details.
|
// form was a perf win. See #64545 for details.
|
||||||
(|| {
|
(|| {
|
||||||
for &infer in &pending_obligation.stalled_on {
|
for &infer_var in &pending_obligation.stalled_on {
|
||||||
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) {
|
if self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,13 +312,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
|
|
||||||
debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause);
|
debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause);
|
||||||
|
|
||||||
fn infer_ty(ty: Ty<'tcx>) -> ty::InferTy {
|
|
||||||
match ty.kind {
|
|
||||||
ty::Infer(infer) => infer,
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match obligation.predicate {
|
match obligation.predicate {
|
||||||
ty::Predicate::Trait(ref data, _) => {
|
ty::Predicate::Trait(ref data, _) => {
|
||||||
let trait_obligation = obligation.with(data.clone());
|
let trait_obligation = obligation.with(data.clone());
|
||||||
@ -467,7 +463,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
) {
|
) {
|
||||||
None => {
|
None => {
|
||||||
pending_obligation.stalled_on = vec![infer_ty(ty)];
|
pending_obligation.stalled_on =
|
||||||
|
vec![TyOrConstInferVar::maybe_from_ty(ty).unwrap()];
|
||||||
ProcessResult::Unchanged
|
ProcessResult::Unchanged
|
||||||
}
|
}
|
||||||
Some(os) => ProcessResult::Changed(mk_pending(os)),
|
Some(os) => ProcessResult::Changed(mk_pending(os)),
|
||||||
@ -483,8 +480,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
None => {
|
None => {
|
||||||
// None means that both are unresolved.
|
// None means that both are unresolved.
|
||||||
pending_obligation.stalled_on = vec![
|
pending_obligation.stalled_on = vec![
|
||||||
infer_ty(subtype.skip_binder().a),
|
TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().a).unwrap(),
|
||||||
infer_ty(subtype.skip_binder().b),
|
TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().b).unwrap(),
|
||||||
];
|
];
|
||||||
ProcessResult::Unchanged
|
ProcessResult::Unchanged
|
||||||
}
|
}
|
||||||
@ -534,20 +531,23 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of type variables contained in a trait ref
|
/// Returns the set of type inference variables contained in a trait ref.
|
||||||
fn trait_ref_type_vars<'a, 'tcx>(
|
fn trait_ref_type_vars<'a, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'a, 'tcx>,
|
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||||
t: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Vec<ty::InferTy> {
|
) -> Vec<TyOrConstInferVar<'tcx>> {
|
||||||
t.skip_binder() // ok b/c this check doesn't care about regions
|
trait_ref
|
||||||
|
.skip_binder() // ok b/c this check doesn't care about regions
|
||||||
|
// FIXME(eddyb) walk over `GenericArg` to support const infer vars.
|
||||||
.input_types()
|
.input_types()
|
||||||
.map(|t| selcx.infcx().resolve_vars_if_possible(&t))
|
.map(|ty| selcx.infcx().resolve_vars_if_possible(&ty))
|
||||||
.filter(|t| t.has_infer_types())
|
// FIXME(eddyb) try using `maybe_walk` to skip *all* subtrees that
|
||||||
.flat_map(|t| t.walk())
|
// don't contain inference variables, not just the outermost level.
|
||||||
.filter_map(|t| match t.kind {
|
// FIXME(eddyb) use `has_infer_types_or_const`.
|
||||||
ty::Infer(infer) => Some(infer),
|
.filter(|ty| ty.has_infer_types())
|
||||||
_ => None,
|
.flat_map(|ty| ty.walk())
|
||||||
})
|
// FIXME(eddyb) use `TyOrConstInferVar::maybe_from_generic_arg`.
|
||||||
|
.filter_map(TyOrConstInferVar::maybe_from_ty)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,12 +188,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
Node::Field(field) => icx.to_ty(&field.ty),
|
Node::Field(field) => icx.to_ty(&field.ty),
|
||||||
|
|
||||||
Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
|
Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
|
||||||
if gen.is_some() {
|
|
||||||
return tcx.typeck_tables_of(def_id).node_type(hir_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_closure(def_id, substs)
|
if let Some(movability) = gen {
|
||||||
|
tcx.mk_generator(def_id, substs, movability)
|
||||||
|
} else {
|
||||||
|
tcx.mk_closure(def_id, substs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::AnonConst(_) => {
|
Node::AnonConst(_) => {
|
||||||
@ -235,29 +235,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
let arg_index = path
|
// We've encountered an `AnonConst` in some path, so we need to
|
||||||
|
// figure out which generic parameter it corresponds to and return
|
||||||
|
// the relevant type.
|
||||||
|
|
||||||
|
let (arg_index, segment) = path
|
||||||
.segments
|
.segments
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|seg| seg.args.as_ref())
|
.filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
|
||||||
.map(|generic_args| generic_args.args)
|
.find_map(|(args, seg)| {
|
||||||
.find_map(|args| {
|
|
||||||
args.iter()
|
args.iter()
|
||||||
.filter(|arg| arg.is_const())
|
.filter(|arg| arg.is_const())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, arg)| arg.id() == hir_id)
|
.filter(|(_, arg)| arg.id() == hir_id)
|
||||||
.map(|(index, _)| index)
|
.map(|(index, _)| (index, seg))
|
||||||
.next()
|
.next()
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
bug!("no arg matching AnonConst in path");
|
bug!("no arg matching AnonConst in path");
|
||||||
});
|
});
|
||||||
|
|
||||||
// We've encountered an `AnonConst` in some path, so we need to
|
// Try to use the segment resolution if it is valid, otherwise we
|
||||||
// figure out which generic parameter it corresponds to and return
|
// default to the path resolution.
|
||||||
// the relevant type.
|
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
|
||||||
let generics = match path.res {
|
let generics = match res {
|
||||||
Res::Def(DefKind::Ctor(..), def_id)
|
Res::Def(DefKind::Ctor(..), def_id) => {
|
||||||
| Res::Def(DefKind::AssocTy, def_id) => {
|
|
||||||
tcx.generics_of(tcx.parent(def_id).unwrap())
|
tcx.generics_of(tcx.parent(def_id).unwrap())
|
||||||
}
|
}
|
||||||
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
||||||
@ -265,8 +267,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
&format!(
|
&format!(
|
||||||
"unexpected const parent path def, parent: {:?}, def: {:?}",
|
"unexpected anon const res {:?} in path: {:?}",
|
||||||
parent_node, res
|
res, path,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return tcx.types.err;
|
return tcx.types.err;
|
||||||
@ -291,8 +293,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
&format!(
|
&format!(
|
||||||
"missing generic parameter for `AnonConst`, parent {:?}",
|
"missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
|
||||||
parent_node
|
parent_node, res
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
tcx.types.err
|
tcx.types.err
|
||||||
|
@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
|
|||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
|
#![feature(or_patterns)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
|
64
src/test/mir-opt/const_prop/control-flow-simplification.rs
Normal file
64
src/test/mir-opt/const_prop/control-flow-simplification.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// compile-flags: -Zmir-opt-level=1
|
||||||
|
|
||||||
|
trait NeedsDrop:Sized{
|
||||||
|
const NEEDS:bool=std::mem::needs_drop::<Self>();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<This> NeedsDrop for This{}
|
||||||
|
|
||||||
|
fn hello<T>(){
|
||||||
|
if <bool>::NEEDS {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
hello::<()>();
|
||||||
|
hello::<Vec<()>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// END RUST SOURCE
|
||||||
|
// START rustc.hello.ConstProp.before.mir
|
||||||
|
// let mut _0: ();
|
||||||
|
// let mut _1: bool;
|
||||||
|
// let mut _2: !;
|
||||||
|
// bb0: {
|
||||||
|
// StorageLive(_1);
|
||||||
|
// _1 = const <bool as NeedsDrop>::NEEDS;
|
||||||
|
// switchInt(_1) -> [false: bb1, otherwise: bb2];
|
||||||
|
// }
|
||||||
|
// bb1: {
|
||||||
|
// _0 = ();
|
||||||
|
// StorageDead(_1);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// bb2: {
|
||||||
|
// StorageLive(_2);
|
||||||
|
// const std::rt::begin_panic::<&str>(const "explicit panic");
|
||||||
|
// }
|
||||||
|
// END rustc.hello.ConstProp.before.mir
|
||||||
|
// START rustc.hello.ConstProp.after.mir
|
||||||
|
// let mut _0: ();
|
||||||
|
// let mut _1: bool;
|
||||||
|
// let mut _2: !;
|
||||||
|
// bb0: {
|
||||||
|
// StorageLive(_1);
|
||||||
|
// _1 = const false;
|
||||||
|
// switchInt(const false) -> [false: bb1, otherwise: bb2];
|
||||||
|
// }
|
||||||
|
// bb1: {
|
||||||
|
// _0 = ();
|
||||||
|
// StorageDead(_1);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// bb2: {
|
||||||
|
// StorageLive(_2);
|
||||||
|
// const std::rt::begin_panic::<&str>(const "explicit panic");
|
||||||
|
// }
|
||||||
|
// END rustc.hello.ConstProp.after.mir
|
||||||
|
// START rustc.hello.PreCodegen.before.mir
|
||||||
|
// let mut _0: ();
|
||||||
|
// bb0: {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// END rustc.hello.PreCodegen.before.mir
|
@ -18,22 +18,6 @@ LL | | break 0u8;
|
|||||||
LL | | };
|
LL | | };
|
||||||
| |_________- enclosing `async` block
|
| |_________- enclosing `async` block
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/async-block-control-flow-static-semantics.rs:13:43
|
|
||||||
|
|
|
||||||
LL | fn return_targets_async_block_not_fn() -> u8 {
|
|
||||||
| --------------------------------- ^^ expected `u8`, found `()`
|
|
||||||
| |
|
|
||||||
| implicitly returns `()` as its body has no tail or `return` expression
|
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
|
|
||||||
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
|
|
||||||
|
|
|
||||||
LL | let _: &dyn Future<Output = ()> = █
|
|
||||||
| ^^^^^^ expected `()`, found `u8`
|
|
||||||
|
|
|
||||||
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/async-block-control-flow-static-semantics.rs:22:58
|
--> $DIR/async-block-control-flow-static-semantics.rs:22:58
|
||||||
|
|
|
|
||||||
@ -55,6 +39,22 @@ LL | let _: &dyn Future<Output = ()> = █
|
|||||||
|
|
|
|
||||||
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
|
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/async-block-control-flow-static-semantics.rs:13:43
|
||||||
|
|
|
||||||
|
LL | fn return_targets_async_block_not_fn() -> u8 {
|
||||||
|
| --------------------------------- ^^ expected `u8`, found `()`
|
||||||
|
| |
|
||||||
|
| implicitly returns `()` as its body has no tail or `return` expression
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
|
||||||
|
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
|
||||||
|
|
|
||||||
|
LL | let _: &dyn Future<Output = ()> = █
|
||||||
|
| ^^^^^^ expected `()`, found `u8`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/async-block-control-flow-static-semantics.rs:48:44
|
--> $DIR/async-block-control-flow-static-semantics.rs:48:44
|
||||||
|
|
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
fn get_future() -> impl Future<Output = ()> {
|
fn get_future() -> impl Future<Output = ()> {
|
||||||
|
//~^ ERROR the trait bound `(): std::future::Future` is not satisfied
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
|
error[E0277]: the trait bound `(): std::future::Future` is not satisfied
|
||||||
|
--> $DIR/async-error-span.rs:7:20
|
||||||
|
|
|
||||||
|
LL | fn get_future() -> impl Future<Output = ()> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
|
||||||
|
LL |
|
||||||
|
LL | panic!()
|
||||||
|
| -------- this returned value is of type `!`
|
||||||
|
|
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error[E0698]: type inside `async fn` body must be known in this context
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
--> $DIR/async-error-span.rs:12:9
|
--> $DIR/async-error-span.rs:13:9
|
||||||
|
|
|
|
||||||
LL | let a;
|
LL | let a;
|
||||||
| ^ cannot infer type
|
| ^ cannot infer type
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/async-error-span.rs:13:5
|
--> $DIR/async-error-span.rs:14:5
|
||||||
|
|
|
|
||||||
LL | get_future().await;
|
LL | get_future().await;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0698`.
|
Some errors have detailed explanations: E0277, E0698.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
@ -62,6 +62,7 @@ fn foo10() -> Result<(), ()> {
|
|||||||
fn foo11() -> Result<(), ()> {
|
fn foo11() -> Result<(), ()> {
|
||||||
let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
|
let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
//~^ ERROR incorrect use of `await`
|
//~^ ERROR incorrect use of `await`
|
||||||
|
//~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn foo12() -> Result<(), ()> {
|
fn foo12() -> Result<(), ()> {
|
||||||
|
@ -71,49 +71,49 @@ LL | let _ = await bar()?;
|
|||||||
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
|
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:68:14
|
--> $DIR/incorrect-syntax-suggestions.rs:69:14
|
||||||
|
|
|
|
||||||
LL | let _ = (await bar())?;
|
LL | let _ = (await bar())?;
|
||||||
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:73:24
|
--> $DIR/incorrect-syntax-suggestions.rs:74:24
|
||||||
|
|
|
|
||||||
LL | let _ = bar().await();
|
LL | let _ = bar().await();
|
||||||
| ^^ help: `await` is not a method call, remove the parentheses
|
| ^^ help: `await` is not a method call, remove the parentheses
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:78:24
|
--> $DIR/incorrect-syntax-suggestions.rs:79:24
|
||||||
|
|
|
|
||||||
LL | let _ = bar().await()?;
|
LL | let _ = bar().await()?;
|
||||||
| ^^ help: `await` is not a method call, remove the parentheses
|
| ^^ help: `await` is not a method call, remove the parentheses
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:106:13
|
--> $DIR/incorrect-syntax-suggestions.rs:107:13
|
||||||
|
|
|
|
||||||
LL | let _ = await!(bar());
|
LL | let _ = await!(bar());
|
||||||
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:110:13
|
--> $DIR/incorrect-syntax-suggestions.rs:111:13
|
||||||
|
|
|
|
||||||
LL | let _ = await!(bar())?;
|
LL | let _ = await!(bar())?;
|
||||||
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:115:17
|
--> $DIR/incorrect-syntax-suggestions.rs:116:17
|
||||||
|
|
|
|
||||||
LL | let _ = await!(bar())?;
|
LL | let _ = await!(bar())?;
|
||||||
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:123:17
|
--> $DIR/incorrect-syntax-suggestions.rs:124:17
|
||||||
|
|
|
|
||||||
LL | let _ = await!(bar())?;
|
LL | let _ = await!(bar())?;
|
||||||
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
|
||||||
|
|
||||||
error: expected expression, found `=>`
|
error: expected expression, found `=>`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:131:25
|
--> $DIR/incorrect-syntax-suggestions.rs:132:25
|
||||||
|
|
|
|
||||||
LL | match await { await => () }
|
LL | match await { await => () }
|
||||||
| ----- ^^ expected expression
|
| ----- ^^ expected expression
|
||||||
@ -121,13 +121,13 @@ LL | match await { await => () }
|
|||||||
| while parsing this incorrect await expression
|
| while parsing this incorrect await expression
|
||||||
|
|
||||||
error: incorrect use of `await`
|
error: incorrect use of `await`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:131:11
|
--> $DIR/incorrect-syntax-suggestions.rs:132:11
|
||||||
|
|
|
|
||||||
LL | match await { await => () }
|
LL | match await { await => () }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
|
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
|
||||||
|
|
||||||
error: expected one of `.`, `?`, `{`, or an operator, found `}`
|
error: expected one of `.`, `?`, `{`, or an operator, found `}`
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:134:1
|
--> $DIR/incorrect-syntax-suggestions.rs:135:1
|
||||||
|
|
|
|
||||||
LL | match await { await => () }
|
LL | match await { await => () }
|
||||||
| ----- - expected one of `.`, `?`, `{`, or an operator
|
| ----- - expected one of `.`, `?`, `{`, or an operator
|
||||||
@ -162,7 +162,7 @@ LL | let _ = await bar()?;
|
|||||||
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:68:14
|
--> $DIR/incorrect-syntax-suggestions.rs:69:14
|
||||||
|
|
|
|
||||||
LL | fn foo12() -> Result<(), ()> {
|
LL | fn foo12() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
@ -170,7 +170,7 @@ LL | let _ = (await bar())?;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:73:13
|
--> $DIR/incorrect-syntax-suggestions.rs:74:13
|
||||||
|
|
|
|
||||||
LL | fn foo13() -> Result<(), ()> {
|
LL | fn foo13() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
@ -178,7 +178,7 @@ LL | let _ = bar().await();
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:78:13
|
--> $DIR/incorrect-syntax-suggestions.rs:79:13
|
||||||
|
|
|
|
||||||
LL | fn foo14() -> Result<(), ()> {
|
LL | fn foo14() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
@ -186,7 +186,7 @@ LL | let _ = bar().await()?;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:83:13
|
--> $DIR/incorrect-syntax-suggestions.rs:84:13
|
||||||
|
|
|
|
||||||
LL | fn foo15() -> Result<(), ()> {
|
LL | fn foo15() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
@ -194,7 +194,7 @@ LL | let _ = bar().await;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:87:13
|
--> $DIR/incorrect-syntax-suggestions.rs:88:13
|
||||||
|
|
|
|
||||||
LL | fn foo16() -> Result<(), ()> {
|
LL | fn foo16() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
@ -202,7 +202,7 @@ LL | let _ = bar().await?;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:92:17
|
--> $DIR/incorrect-syntax-suggestions.rs:93:17
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Result<(), ()> {
|
LL | fn foo() -> Result<(), ()> {
|
||||||
| --- this is not `async`
|
| --- this is not `async`
|
||||||
@ -210,7 +210,7 @@ LL | let _ = bar().await?;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:99:17
|
--> $DIR/incorrect-syntax-suggestions.rs:100:17
|
||||||
|
|
|
|
||||||
LL | let foo = || {
|
LL | let foo = || {
|
||||||
| -- this is not `async`
|
| -- this is not `async`
|
||||||
@ -218,7 +218,7 @@ LL | let _ = bar().await?;
|
|||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:115:17
|
--> $DIR/incorrect-syntax-suggestions.rs:116:17
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Result<(), ()> {
|
LL | fn foo() -> Result<(), ()> {
|
||||||
| --- this is not `async`
|
| --- this is not `async`
|
||||||
@ -226,7 +226,7 @@ LL | let _ = await!(bar())?;
|
|||||||
| ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:123:17
|
--> $DIR/incorrect-syntax-suggestions.rs:124:17
|
||||||
|
|
|
|
||||||
LL | let foo = || {
|
LL | let foo = || {
|
||||||
| -- this is not `async`
|
| -- this is not `async`
|
||||||
@ -242,7 +242,16 @@ LL | let _ = await bar()?;
|
|||||||
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
|
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
|
||||||
= note: required by `std::ops::Try::into_result`
|
= note: required by `std::ops::Try::into_result`
|
||||||
|
|
||||||
error: aborting due to 35 previous errors
|
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
|
||||||
|
--> $DIR/incorrect-syntax-suggestions.rs:63:19
|
||||||
|
|
|
||||||
|
LL | let _ = await bar()?;
|
||||||
|
| ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
|
||||||
|
|
|
||||||
|
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
|
||||||
|
= note: required by `std::ops::Try::into_result`
|
||||||
|
|
||||||
|
error: aborting due to 36 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0728.
|
Some errors have detailed explanations: E0277, E0728.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
20
src/test/ui/async-await/issue-67651.rs
Normal file
20
src/test/ui/async-await/issue-67651.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// edition:2018
|
||||||
|
|
||||||
|
trait From {
|
||||||
|
fn from();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From for () {
|
||||||
|
fn from() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From for () {
|
||||||
|
//~^ ERROR conflicting implementations of trait
|
||||||
|
fn from() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() -> impl core::future::Future<Output = ()> {
|
||||||
|
async move { From::from() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/async-await/issue-67651.stderr
Normal file
12
src/test/ui/async-await/issue-67651.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0119]: conflicting implementations of trait `From` for type `()`:
|
||||||
|
--> $DIR/issue-67651.rs:11:1
|
||||||
|
|
|
||||||
|
LL | impl From for () {
|
||||||
|
| ---------------- first implementation here
|
||||||
|
...
|
||||||
|
LL | impl From for () {
|
||||||
|
| ^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
@ -1,13 +0,0 @@
|
|||||||
error[E0106]: missing lifetime specifier
|
|
||||||
--> $DIR/issue-63388-2.rs:12:10
|
|
||||||
|
|
|
||||||
LL | foo: &dyn Foo, bar: &'a dyn Foo
|
|
||||||
| -------- -----------
|
|
||||||
LL | ) -> &dyn Foo
|
|
||||||
| ^ help: consider using the named lifetime: `&'a`
|
|
||||||
|
|
|
||||||
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0106`.
|
|
@ -8,7 +8,7 @@ trait Foo {}
|
|||||||
|
|
||||||
impl Xyz {
|
impl Xyz {
|
||||||
async fn do_sth<'a>(
|
async fn do_sth<'a>(
|
||||||
foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer
|
foo: &dyn Foo, bar: &'a dyn Foo
|
||||||
) -> &dyn Foo //~ ERROR missing lifetime specifier
|
) -> &dyn Foo //~ ERROR missing lifetime specifier
|
||||||
{
|
{
|
||||||
foo
|
foo
|
||||||
|
@ -8,21 +8,6 @@ LL | ) -> &dyn Foo
|
|||||||
|
|
|
|
||||||
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
|
||||||
|
|
||||||
error: cannot infer an appropriate lifetime
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-63388-2.rs:11:9
|
|
||||||
|
|
|
||||||
LL | foo: &dyn Foo, bar: &'a dyn Foo
|
|
||||||
| ^^^ ...but this borrow...
|
|
||||||
...
|
|
||||||
LL | foo
|
|
||||||
| --- this return type evaluates to the `'static` lifetime...
|
|
||||||
|
|
|
||||||
note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14
|
|
||||||
--> $DIR/issue-63388-2.rs:11:14
|
|
||||||
|
|
|
||||||
LL | foo: &dyn Foo, bar: &'a dyn Foo
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0106`.
|
For more information about this error, try `rustc --explain E0106`.
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
|
async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
|
//~^ type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1
|
|||||||
LL | async fn copy() -> Result<()>
|
LL | async fn copy() -> Result<()>
|
||||||
| ^^^^^^^^^^ expected 2 type arguments
|
| ^^^^^^^^^^ expected 2 type arguments
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/issue-65159.rs:7:5
|
||||||
|
|
|
||||||
|
LL | Ok(())
|
||||||
|
| ^^ cannot infer type for type parameter `E` declared on the enum `Result`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0107`.
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0107, E0282.
|
||||||
|
For more information about an error, try `rustc --explain E0107`.
|
||||||
|
@ -9,6 +9,9 @@ impl<T> Trait<'_, '_> for T { }
|
|||||||
async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||||
//~^ ERROR ambiguous lifetime bound
|
//~^ ERROR ambiguous lifetime bound
|
||||||
//~| ERROR ambiguous lifetime bound
|
//~| ERROR ambiguous lifetime bound
|
||||||
|
//~| ERROR ambiguous lifetime bound
|
||||||
|
//~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
|
//~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
(a, b)
|
(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,5 +14,42 @@ LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'
|
|||||||
|
|
|
|
||||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: ambiguous lifetime bound in `impl Trait`
|
||||||
|
--> $DIR/ret-impl-trait-no-fg.rs:9:64
|
||||||
|
|
|
||||||
|
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another
|
||||||
|
|
|
||||||
|
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
|
--> $DIR/ret-impl-trait-no-fg.rs:9:1
|
||||||
|
|
|
||||||
|
LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
... |
|
||||||
|
LL | | (a, b)
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: hidden type `(&u8, &u8)` captures lifetime '_#4r
|
||||||
|
|
||||||
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
|
--> $DIR/ret-impl-trait-no-fg.rs:9:1
|
||||||
|
|
|
||||||
|
LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
... |
|
||||||
|
LL | | (a, b)
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: hidden type `(&u8, &u8)` captures lifetime '_#5r
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0700`.
|
||||||
|
17
src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
Normal file
17
src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(const_generics)]
|
||||||
|
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
|
||||||
|
trait T<const A: usize> {
|
||||||
|
fn f();
|
||||||
|
}
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl T<0usize> for S {
|
||||||
|
fn f() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _err = <S as T<0usize>>::f();
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/issue70273-assoc-fn.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(const_generics)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
21
src/test/ui/const-generics/type_of_anon_const.rs
Normal file
21
src/test/ui/const-generics/type_of_anon_const.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![feature(const_generics)]
|
||||||
|
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
|
||||||
|
trait T<const A: usize> {
|
||||||
|
fn l<const N: bool>() -> usize;
|
||||||
|
fn r<const N: bool>() -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl<const N: usize> T<N> for S {
|
||||||
|
fn l<const M: bool>() -> usize { N }
|
||||||
|
fn r<const M: bool>() -> bool { M }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(<S as T<123>>::l::<true>(), 123);
|
||||||
|
assert!(<S as T<123>>::r::<true>());
|
||||||
|
}
|
8
src/test/ui/const-generics/type_of_anon_const.stderr
Normal file
8
src/test/ui/const-generics/type_of_anon_const.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/type_of_anon_const.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(const_generics)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Foo {
|
struct Foo {
|
||||||
i: isize,
|
i: isize,
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
error[E0599]: no method named `clone` found for struct `Foo` in the current scope
|
error[E0599]: no method named `clone` found for struct `Foo` in the current scope
|
||||||
--> $DIR/copy-a-resource.rs:18:16
|
--> $DIR/copy-a-resource.rs:23:16
|
||||||
|
|
|
|
||||||
LL | struct Foo {
|
LL | struct Foo {
|
||||||
| ---------- method `clone` not found for this
|
| ---------- method `clone` not found for this
|
||||||
...
|
...
|
||||||
LL | let _y = x.clone();
|
LL | let _y = x.clone();
|
||||||
| ^^^^^ method not found in `Foo`
|
| ^^^^^ method not found in `Foo`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<Foo>` here
|
||||||
|
| the method is available for `std::rc::Rc<Foo>` here
|
||||||
|
|
|
|
||||||
= help: items from traits can only be used if the trait is implemented and in scope
|
= help: items from traits can only be used if the trait is implemented and in scope
|
||||||
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
type X;
|
type X;
|
||||||
fn method(&self) {}
|
fn method(&self) {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0599]: no method named `clone` found for struct `Bar<NotClone>` in the current scope
|
error[E0599]: no method named `clone` found for struct `Bar<NotClone>` in the current scope
|
||||||
--> $DIR/derive-assoc-type-not-impl.rs:18:30
|
--> $DIR/derive-assoc-type-not-impl.rs:23:30
|
||||||
|
|
|
|
||||||
LL | struct Bar<T: Foo> {
|
LL | struct Bar<T: Foo> {
|
||||||
| ------------------
|
| ------------------
|
||||||
@ -12,6 +12,14 @@ LL | struct NotClone;
|
|||||||
...
|
...
|
||||||
LL | Bar::<NotClone> { x: 1 }.clone();
|
LL | Bar::<NotClone> { x: 1 }.clone();
|
||||||
| ^^^^^ method not found in `Bar<NotClone>`
|
| ^^^^^ method not found in `Bar<NotClone>`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<Bar<NotClone>>` here
|
||||||
|
| the method is available for `std::rc::Rc<Bar<NotClone>>` here
|
||||||
|
|
|
|
||||||
= note: the method `clone` exists but the following trait bounds were not satisfied:
|
= note: the method `clone` exists but the following trait bounds were not satisfied:
|
||||||
`NotClone: std::clone::Clone`
|
`NotClone: std::clone::Clone`
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
// edition:2018
|
// edition:2018
|
||||||
// aux-build:edition-kw-macro-2015.rs
|
// aux-build:edition-kw-macro-2015.rs
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate edition_kw_macro_2015;
|
extern crate edition_kw_macro_2015;
|
||||||
|
|
||||||
|
mod module {
|
||||||
|
pub fn r#async() {}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_async() {
|
pub fn check_async() {
|
||||||
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
|
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
|
||||||
let mut r#async = 1; // OK
|
let mut r#async = 1; // OK
|
||||||
@ -17,4 +25,6 @@ pub fn check_async() {
|
|||||||
if passes_ident!(r#async) == 1 {} // OK
|
if passes_ident!(r#async) == 1 {} // OK
|
||||||
module::async(); //~ ERROR expected identifier, found keyword `async`
|
module::async(); //~ ERROR expected identifier, found keyword `async`
|
||||||
module::r#async(); // OK
|
module::r#async(); // OK
|
||||||
|
|
||||||
|
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: expected identifier, found keyword `async`
|
error: expected identifier, found keyword `async`
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:8:13
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:16:13
|
||||||
|
|
|
|
||||||
LL | let mut async = 1;
|
LL | let mut async = 1;
|
||||||
| ^^^^^ expected identifier, found keyword
|
| ^^^^^ expected identifier, found keyword
|
||||||
@ -10,7 +10,7 @@ LL | let mut r#async = 1;
|
|||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected identifier, found keyword `async`
|
error: expected identifier, found keyword `async`
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:18:13
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:26:13
|
||||||
|
|
|
|
||||||
LL | module::async();
|
LL | module::async();
|
||||||
| ^^^^^ expected identifier, found keyword
|
| ^^^^^ expected identifier, found keyword
|
||||||
@ -21,13 +21,13 @@ LL | module::r#async();
|
|||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: no rules expected the token `r#async`
|
error: no rules expected the token `r#async`
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:12:31
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:20:31
|
||||||
|
|
|
|
||||||
LL | r#async = consumes_async!(r#async);
|
LL | r#async = consumes_async!(r#async);
|
||||||
| ^^^^^^^ no rules expected this token in macro call
|
| ^^^^^^^ no rules expected this token in macro call
|
||||||
|
|
||||||
error: no rules expected the token `async`
|
error: no rules expected the token `async`
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:13:35
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
|
||||||
|
|
|
|
||||||
LL | r#async = consumes_async_raw!(async);
|
LL | r#async = consumes_async_raw!(async);
|
||||||
| ^^^^^ no rules expected this token in macro call
|
| ^^^^^ no rules expected this token in macro call
|
||||||
@ -38,10 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move
|
|||||||
LL | ($i: ident) => ($i)
|
LL | ($i: ident) => ($i)
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `|`, or `||`
|
||||||
|
|
|
|
||||||
::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8
|
::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8
|
||||||
|
|
|
|
||||||
LL | if passes_ident!(async) == 1 {}
|
LL | if passes_ident!(async) == 1 {}
|
||||||
| -------------------- in this macro invocation
|
| -------------------- in this macro invocation
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
|
||||||
|
|
|
||||||
|
LL | let _recovery_witness: () = 0;
|
||||||
|
| -- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
// edition:2018
|
// edition:2018
|
||||||
// aux-build:edition-kw-macro-2018.rs
|
// aux-build:edition-kw-macro-2018.rs
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate edition_kw_macro_2018;
|
extern crate edition_kw_macro_2018;
|
||||||
|
|
||||||
|
mod module {
|
||||||
|
pub fn r#async() {}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_async() {
|
pub fn check_async() {
|
||||||
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
|
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
|
||||||
let mut r#async = 1; // OK
|
let mut r#async = 1; // OK
|
||||||
@ -17,4 +25,6 @@ pub fn check_async() {
|
|||||||
if passes_ident!(r#async) == 1 {} // OK
|
if passes_ident!(r#async) == 1 {} // OK
|
||||||
module::async(); //~ ERROR expected identifier, found keyword `async`
|
module::async(); //~ ERROR expected identifier, found keyword `async`
|
||||||
module::r#async(); // OK
|
module::r#async(); // OK
|
||||||
|
|
||||||
|
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: expected identifier, found keyword `async`
|
error: expected identifier, found keyword `async`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:8:13
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:16:13
|
||||||
|
|
|
|
||||||
LL | let mut async = 1;
|
LL | let mut async = 1;
|
||||||
| ^^^^^ expected identifier, found keyword
|
| ^^^^^ expected identifier, found keyword
|
||||||
@ -10,7 +10,7 @@ LL | let mut r#async = 1;
|
|||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected identifier, found keyword `async`
|
error: expected identifier, found keyword `async`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:18:13
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:26:13
|
||||||
|
|
|
|
||||||
LL | module::async();
|
LL | module::async();
|
||||||
| ^^^^^ expected identifier, found keyword
|
| ^^^^^ expected identifier, found keyword
|
||||||
@ -21,13 +21,13 @@ LL | module::r#async();
|
|||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: no rules expected the token `r#async`
|
error: no rules expected the token `r#async`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:12:31
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:20:31
|
||||||
|
|
|
|
||||||
LL | r#async = consumes_async!(r#async);
|
LL | r#async = consumes_async!(r#async);
|
||||||
| ^^^^^^^ no rules expected this token in macro call
|
| ^^^^^^^ no rules expected this token in macro call
|
||||||
|
|
||||||
error: no rules expected the token `async`
|
error: no rules expected the token `async`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:13:35
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
|
||||||
|
|
|
|
||||||
LL | r#async = consumes_async_raw!(async);
|
LL | r#async = consumes_async_raw!(async);
|
||||||
| ^^^^^ no rules expected this token in macro call
|
| ^^^^^ no rules expected this token in macro call
|
||||||
@ -38,10 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move
|
|||||||
LL | ($i: ident) => ($i)
|
LL | ($i: ident) => ($i)
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `|`, or `||`
|
||||||
|
|
|
|
||||||
::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8
|
::: $DIR/edition-keywords-2018-2018-parsing.rs:24:8
|
||||||
|
|
|
|
||||||
LL | if passes_ident!(async) == 1 {}
|
LL | if passes_ident!(async) == 1 {}
|
||||||
| -------------------- in this macro invocation
|
| -------------------- in this macro invocation
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:29:33
|
||||||
|
|
|
||||||
|
LL | let _recovery_witness: () = 0;
|
||||||
|
| -- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = Some(1);
|
let x = Some(1);
|
||||||
|
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
|
error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
|
||||||
--> $DIR/E0004-2.rs:4:11
|
--> $DIR/E0004-2.rs:9:11
|
||||||
|
|
|
|
||||||
LL | match x { }
|
LL | match x { }
|
||||||
| ^ patterns `None` and `Some(_)` not covered
|
| ^ patterns `None` and `Some(_)` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | None,
|
||||||
|
| ---- not covered
|
||||||
|
...
|
||||||
|
LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||||
|
| ---- not covered
|
||||||
|
|
|
|
||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = Some(1);
|
let x = Some(1);
|
||||||
let Some(y) = x; //~ ERROR E0005
|
let Some(y) = x; //~ ERROR E0005
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
error[E0005]: refutable pattern in local binding: `None` not covered
|
error[E0005]: refutable pattern in local binding: `None` not covered
|
||||||
--> $DIR/E0005.rs:3:9
|
--> $DIR/E0005.rs:8:9
|
||||||
|
|
|
|
||||||
LL | let Some(y) = x;
|
LL | let Some(y) = x;
|
||||||
| ^^^^^^^ pattern `None` not covered
|
| ^^^^^^^ pattern `None` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | None,
|
||||||
|
| ---- not covered
|
||||||
|
|
|
|
||||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let xs : Vec<Option<i32>> = vec![Some(1), None];
|
let xs : Vec<Option<i32>> = vec![Some(1), None];
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
error[E0005]: refutable pattern in `for` loop binding: `None` not covered
|
error[E0005]: refutable pattern in `for` loop binding: `None` not covered
|
||||||
--> $DIR/E0297.rs:4:9
|
--> $DIR/E0297.rs:9:9
|
||||||
|
|
|
|
||||||
LL | for Some(x) in xs {}
|
LL | for Some(x) in xs {}
|
||||||
| ^^^^^^^ pattern `None` not covered
|
| ^^^^^^^ pattern `None` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | None,
|
||||||
|
| ---- not covered
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
|
||||||
fn foo() -> Result<u32, !> {
|
fn foo() -> Result<u32, !> {
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
|
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
|
||||||
--> $DIR/feature-gate-exhaustive-patterns.rs:8:9
|
--> $DIR/feature-gate-exhaustive-patterns.rs:13:9
|
||||||
|
|
|
|
||||||
LL | let Ok(_x) = foo();
|
LL | let Ok(_x) = foo();
|
||||||
| ^^^^^^ pattern `Err(_)` not covered
|
| ^^^^^^ pattern `Err(_)` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/result.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E),
|
||||||
|
| --- not covered
|
||||||
|
|
|
|
||||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
|
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
|
||||||
--> $DIR/iterable.rs:15:5
|
--> $DIR/iterable.rs:20:5
|
||||||
|
|
|
|
||||||
LL | impl<T> Iterable for Vec<T> {
|
LL | impl<T> Iterable for Vec<T> {
|
||||||
| --------------------------- in this `impl` item
|
| --------------------------- in this `impl` item
|
||||||
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Item;
|
||||||
|
| ---- associated type defined here
|
||||||
|
|
|
|
||||||
= note: expected reference `&T`
|
= note: expected reference `&T`
|
||||||
found associated type `<std::vec::Vec<T> as Iterable>::Item<'_>`
|
found associated type `<std::vec::Vec<T> as Iterable>::Item<'_>`
|
||||||
@ -12,12 +17,17 @@ LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item
|
|||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
|
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
|
||||||
--> $DIR/iterable.rs:27:5
|
--> $DIR/iterable.rs:32:5
|
||||||
|
|
|
|
||||||
LL | impl<T> Iterable for [T] {
|
LL | impl<T> Iterable for [T] {
|
||||||
| ------------------------ in this `impl` item
|
| ------------------------ in this `impl` item
|
||||||
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Item;
|
||||||
|
| ---- associated type defined here
|
||||||
|
|
|
|
||||||
= note: expected reference `&T`
|
= note: expected reference `&T`
|
||||||
found associated type `<[T] as Iterable>::Item<'_>`
|
found associated type `<[T] as Iterable>::Item<'_>`
|
||||||
@ -25,7 +35,7 @@ LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item
|
|||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
|
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
|
||||||
--> $DIR/iterable.rs:19:30
|
--> $DIR/iterable.rs:24:30
|
||||||
|
|
|
|
||||||
LL | trait Iterable {
|
LL | trait Iterable {
|
||||||
| -------------- required by `Iterable`
|
| -------------- required by `Iterable`
|
||||||
@ -39,7 +49,7 @@ LL | fn iter<'a>(&'a self) -> Self::Iter<'a> {
|
|||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
|
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
|
||||||
--> $DIR/iterable.rs:31:30
|
--> $DIR/iterable.rs:36:30
|
||||||
|
|
|
|
||||||
LL | trait Iterable {
|
LL | trait Iterable {
|
||||||
| -------------- required by `Iterable`
|
| -------------- required by `Iterable`
|
||||||
|
@ -83,6 +83,16 @@ error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::b
|
|||||||
|
|
|
|
||||||
LL | std::rc::Rc::new(&mut Box::new(&1i32)).method();
|
LL | std::rc::Rc::new(&mut Box::new(&1i32)).method();
|
||||||
| ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>`
|
| ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>`
|
||||||
|
|
|
||||||
|
::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12
|
||||||
|
|
|
||||||
|
LL | fn method(&self) {}
|
||||||
|
| ------
|
||||||
|
| |
|
||||||
|
| the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
|
||||||
|
| the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
|
||||||
|
| the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
|
||||||
|
| the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
|
||||||
|
|
|
|
||||||
= help: items from traits can only be used if the trait is in scope
|
= 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:
|
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
struct C {
|
struct C {
|
||||||
x: isize,
|
x: isize,
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
error[E0599]: no method named `clone` found for struct `C` in the current scope
|
error[E0599]: no method named `clone` found for struct `C` in the current scope
|
||||||
--> $DIR/issue-2823.rs:13:16
|
--> $DIR/issue-2823.rs:18:16
|
||||||
|
|
|
|
||||||
LL | struct C {
|
LL | struct C {
|
||||||
| -------- method `clone` not found for this
|
| -------- method `clone` not found for this
|
||||||
...
|
...
|
||||||
LL | let _d = c.clone();
|
LL | let _d = c.clone();
|
||||||
| ^^^^^ method not found in `C`
|
| ^^^^^ method not found in `C`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<C>` here
|
||||||
|
| the method is available for `std::rc::Rc<C>` here
|
||||||
|
|
|
|
||||||
= help: items from traits can only be used if the trait is implemented and in scope
|
= help: items from traits can only be used if the trait is implemented and in scope
|
||||||
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
// aux-build:issue-69725.rs
|
// aux-build:issue-69725.rs
|
||||||
|
|
||||||
extern crate issue_69725;
|
extern crate issue_69725;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0599]: no method named `clone` found for struct `issue_69725::Struct<A>` in the current scope
|
error[E0599]: no method named `clone` found for struct `issue_69725::Struct<A>` in the current scope
|
||||||
--> $DIR/issue-69725.rs:7:32
|
--> $DIR/issue-69725.rs:12:32
|
||||||
|
|
|
|
||||||
LL | let _ = Struct::<A>::new().clone();
|
LL | let _ = Struct::<A>::new().clone();
|
||||||
| ^^^^^ method not found in `issue_69725::Struct<A>`
|
| ^^^^^ method not found in `issue_69725::Struct<A>`
|
||||||
@ -8,6 +8,14 @@ LL | let _ = Struct::<A>::new().clone();
|
|||||||
|
|
|
|
||||||
LL | pub struct Struct<A>(A);
|
LL | pub struct Struct<A>(A);
|
||||||
| ------------------------ doesn't satisfy `issue_69725::Struct<A>: std::clone::Clone`
|
| ------------------------ doesn't satisfy `issue_69725::Struct<A>: std::clone::Clone`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<issue_69725::Struct<A>>` here
|
||||||
|
| the method is available for `std::rc::Rc<issue_69725::Struct<A>>` here
|
||||||
|
|
|
|
||||||
= note: the method `clone` exists but the following trait bounds were not satisfied:
|
= note: the method `clone` exists but the following trait bounds were not satisfied:
|
||||||
`A: std::clone::Clone`
|
`A: std::clone::Clone`
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
// Regression test for issue #61033.
|
// Regression test for issue #61033.
|
||||||
|
|
||||||
macro_rules! test1 {
|
macro_rules! test1 {
|
||||||
($x:ident, $($tt:tt)*) => { $($tt)+ } //~ERROR this must repeat at least once
|
($x:ident, $($tt:tt)*) => { $($tt)+ } //~ ERROR this must repeat at least once
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test1!(x,);
|
test1!(x,);
|
||||||
|
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,14 @@ error: this must repeat at least once
|
|||||||
LL | ($x:ident, $($tt:tt)*) => { $($tt)+ }
|
LL | ($x:ident, $($tt:tt)*) => { $($tt)+ }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-61033-1.rs:9:33
|
||||||
|
|
|
||||||
|
LL | let _recovery_witness: () = 0;
|
||||||
|
| -- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
@ -5,7 +5,9 @@ macro_rules! test2 {
|
|||||||
$(* $id1:ident)*
|
$(* $id1:ident)*
|
||||||
$(+ $id2:ident)*
|
$(+ $id2:ident)*
|
||||||
) => {
|
) => {
|
||||||
$( //~ERROR meta-variable `id1` repeats 2 times
|
$(
|
||||||
|
//~^ ERROR meta-variable `id1` repeats 2 times
|
||||||
|
//~| ERROR meta-variable `id1` repeats 2 times
|
||||||
$id1 + $id2 // $id1 and $id2 may repeat different numbers of times
|
$id1 + $id2 // $id1 and $id2 may repeat different numbers of times
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
@ -16,4 +18,8 @@ fn main() {
|
|||||||
* a * b
|
* a * b
|
||||||
+ a + b + c
|
+ a + b + c
|
||||||
}
|
}
|
||||||
|
test2! {
|
||||||
|
* a * b
|
||||||
|
+ a + b + c + d
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,22 @@ error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times
|
|||||||
|
|
|
|
||||||
LL | $(
|
LL | $(
|
||||||
| __________^
|
| __________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
|
LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
|
||||||
LL | | )*
|
LL | | )*
|
||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: meta-variable `id1` repeats 2 times, but `id2` repeats 4 times
|
||||||
|
--> $DIR/issue-61033-2.rs:8:10
|
||||||
|
|
|
||||||
|
LL | $(
|
||||||
|
| __________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
|
||||||
|
LL | | )*
|
||||||
|
| |_________^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
fn main() {}
|
||||||
|
|
||||||
|
macro_rules! ambiguity {
|
||||||
|
($($i:ident)* $j:ident) => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ambiguity!(error); //~ ERROR local ambiguity
|
||||||
|
ambiguity!(error); //~ ERROR local ambiguity
|
@ -0,0 +1,14 @@
|
|||||||
|
error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
|
||||||
|
--> $DIR/local-ambiguity-multiple-parsing-options.rs:7:12
|
||||||
|
|
|
||||||
|
LL | ambiguity!(error);
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
|
||||||
|
--> $DIR/local-ambiguity-multiple-parsing-options.rs:8:12
|
||||||
|
|
|
||||||
|
LL | ambiguity!(error);
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -4,6 +4,8 @@ macro_rules! m {
|
|||||||
//~| ERROR macro expansion ignores token `typeof`
|
//~| ERROR macro expansion ignores token `typeof`
|
||||||
//~| ERROR macro expansion ignores token `;`
|
//~| ERROR macro expansion ignores token `;`
|
||||||
//~| ERROR macro expansion ignores token `;`
|
//~| ERROR macro expansion ignores token `;`
|
||||||
|
//~| ERROR cannot find type `i` in this scope
|
||||||
|
//~| ERROR cannot find value `i` in this scope
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -42,5 +42,29 @@ LL | m!();
|
|||||||
|
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error[E0412]: cannot find type `i` in this scope
|
||||||
|
--> $DIR/macro-context.rs:3:13
|
||||||
|
|
|
||||||
|
LL | () => ( i ; typeof );
|
||||||
|
| ^ help: a builtin type with a similar name exists: `i8`
|
||||||
|
...
|
||||||
|
LL | let a: m!();
|
||||||
|
| ---- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `i` in this scope
|
||||||
|
--> $DIR/macro-context.rs:3:13
|
||||||
|
|
|
||||||
|
LL | () => ( i ; typeof );
|
||||||
|
| ^ help: a local variable with a similar name exists: `a`
|
||||||
|
...
|
||||||
|
LL | let i = m!();
|
||||||
|
| ---- in this macro invocation
|
||||||
|
|
|
||||||
|
= 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
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0412, E0425.
|
||||||
|
For more information about an error, try `rustc --explain E0412`.
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
macro_rules! test { ($a, $b) => (()); } //~ ERROR missing fragment
|
macro_rules! test {
|
||||||
|
($a, $b) => {
|
||||||
|
//~^ ERROR missing fragment
|
||||||
|
//~| ERROR missing fragment
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test!()
|
test!()
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
error: missing fragment specifier
|
error: missing fragment specifier
|
||||||
--> $DIR/macro-match-nonterminal.rs:1:24
|
--> $DIR/macro-match-nonterminal.rs:2:8
|
||||||
|
|
|
|
||||||
LL | macro_rules! test { ($a, $b) => (()); }
|
LL | ($a, $b) => {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: missing fragment specifier
|
||||||
|
--> $DIR/macro-match-nonterminal.rs:2:10
|
||||||
|
|
|
||||||
|
LL | ($a, $b) => {
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
= note: `#[deny(missing_fragment_specifier)]` on by default
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// compile-flags: -Z trace-macros
|
// compile-flags: -Z trace-macros
|
||||||
|
|
||||||
#![recursion_limit="4"]
|
#![recursion_limit = "4"]
|
||||||
|
|
||||||
macro_rules! my_faulty_macro {
|
macro_rules! my_faulty_macro {
|
||||||
() => {
|
() => {
|
||||||
@ -24,9 +24,7 @@ macro_rules! my_recursive_macro {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! my_macro {
|
macro_rules! my_macro {
|
||||||
() => {
|
() => {};
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -39,7 +37,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[my_macro]
|
#[my_macro]
|
||||||
fn use_bang_macro_as_attr(){}
|
fn use_bang_macro_as_attr() {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)] //~ ERROR `derive` may only be applied to structs
|
||||||
fn use_derive_macro_as_attr(){}
|
fn use_derive_macro_as_attr() {}
|
||||||
|
@ -13,7 +13,7 @@ LL | my_faulty_macro!();
|
|||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
note: trace_macro
|
note: trace_macro
|
||||||
--> $DIR/trace_faulty_macros.rs:33:5
|
--> $DIR/trace_faulty_macros.rs:31:5
|
||||||
|
|
|
|
||||||
LL | my_faulty_macro!();
|
LL | my_faulty_macro!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
@ -35,7 +35,7 @@ LL | my_recursive_macro!();
|
|||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
note: trace_macro
|
note: trace_macro
|
||||||
--> $DIR/trace_faulty_macros.rs:34:5
|
--> $DIR/trace_faulty_macros.rs:32:5
|
||||||
|
|
|
|
||||||
LL | my_recursive_macro!();
|
LL | my_recursive_macro!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -60,5 +60,22 @@ LL | let a = pat_macro!();
|
|||||||
|
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: `derive` may only be applied to structs, enums and unions
|
||||||
|
--> $DIR/trace_faulty_macros.rs:42:1
|
||||||
|
|
|
||||||
|
LL | #[derive(Debug)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
note: trace_macro
|
||||||
|
--> $DIR/trace_faulty_macros.rs:36:13
|
||||||
|
|
|
||||||
|
LL | let a = pat_macro!();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: expanding `pat_macro! { }`
|
||||||
|
= note: to `pat_macro ! (A { a : a, b : 0, c : _, .. }) ;`
|
||||||
|
= note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }`
|
||||||
|
= note: to `A { a: a, b: 0, c: _, .. }`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
// ignore-wasm32-bare no libc to test ffi with
|
// ignore-wasm32-bare no libc to test ffi with
|
||||||
|
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope
|
error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope
|
||||||
--> $DIR/non-copyable-void.rs:11:23
|
--> $DIR/non-copyable-void.rs:16:23
|
||||||
|
|
|
|
||||||
LL | let _z = (*y).clone();
|
LL | let _z = (*y).clone();
|
||||||
| ^^^^^ method not found in `libc::c_void`
|
| ^^^^^ method not found in `libc::c_void`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<libc::c_void>` here
|
||||||
|
| the method is available for `std::rc::Rc<libc::c_void>` here
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
// Test that a class with a non-copyable field can't be
|
// Test that a class with a non-copyable field can't be
|
||||||
// copied
|
// copied
|
||||||
|
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
error[E0599]: no method named `clone` found for struct `Foo` in the current scope
|
error[E0599]: no method named `clone` found for struct `Foo` in the current scope
|
||||||
--> $DIR/noncopyable-class.rs:34:16
|
--> $DIR/noncopyable-class.rs:39:16
|
||||||
|
|
|
|
||||||
LL | struct Foo {
|
LL | struct Foo {
|
||||||
| ---------- method `clone` not found for this
|
| ---------- method `clone` not found for this
|
||||||
...
|
...
|
||||||
LL | let _y = x.clone();
|
LL | let _y = x.clone();
|
||||||
| ^^^^^ method not found in `Foo`
|
| ^^^^^ method not found in `Foo`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/clone.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn clone(&self) -> Self;
|
||||||
|
| -----
|
||||||
|
| |
|
||||||
|
| the method is available for `std::sync::Arc<Foo>` here
|
||||||
|
| the method is available for `std::rc::Rc<Foo>` here
|
||||||
|
|
|
|
||||||
= help: items from traits can only be used if the trait is implemented and in scope
|
= help: items from traits can only be used if the trait is implemented and in scope
|
||||||
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
// Regression test for #62894, shouldn't crash.
|
// Regression test for #62894, shouldn't crash.
|
||||||
// error-pattern: this file contains an unclosed delimiter
|
// error-pattern: this file contains an unclosed delimiter
|
||||||
// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`
|
// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: this file contains an unclosed delimiter
|
error: this file contains an unclosed delimiter
|
||||||
--> $DIR/issue-62894.rs:7:14
|
--> $DIR/issue-62894.rs:12:14
|
||||||
|
|
|
|
||||||
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
||||||
| - - - unclosed delimiter
|
| - - - unclosed delimiter
|
||||||
@ -11,7 +11,7 @@ LL | fn main() {}
|
|||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: this file contains an unclosed delimiter
|
error: this file contains an unclosed delimiter
|
||||||
--> $DIR/issue-62894.rs:7:14
|
--> $DIR/issue-62894.rs:12:14
|
||||||
|
|
|
|
||||||
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
||||||
| - - - unclosed delimiter
|
| - - - unclosed delimiter
|
||||||
@ -23,7 +23,7 @@ LL | fn main() {}
|
|||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: this file contains an unclosed delimiter
|
error: this file contains an unclosed delimiter
|
||||||
--> $DIR/issue-62894.rs:7:14
|
--> $DIR/issue-62894.rs:12:14
|
||||||
|
|
|
|
||||||
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
||||||
| - - - unclosed delimiter
|
| - - - unclosed delimiter
|
||||||
@ -35,13 +35,18 @@ LL | fn main() {}
|
|||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: expected one of `(`, `[`, or `{`, found keyword `fn`
|
error: expected one of `(`, `[`, or `{`, found keyword `fn`
|
||||||
--> $DIR/issue-62894.rs:7:1
|
--> $DIR/issue-62894.rs:12:1
|
||||||
|
|
|
|
||||||
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
|
||||||
| - expected one of `(`, `[`, or `{`
|
| - expected one of `(`, `[`, or `{`
|
||||||
LL |
|
LL |
|
||||||
LL | fn main() {}
|
LL | fn main() {}
|
||||||
| ^^ unexpected token
|
| ^^ unexpected token
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | ($left:expr, $right:expr) => ({
|
||||||
|
| ---------- while parsing argument for this `expr` macro fragment
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -6,3 +6,5 @@ macro_rules! foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foo!();
|
foo!();
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
macro_rules! mac {
|
macro_rules! mac {
|
||||||
( $($v:tt)* ) => (
|
( $($v:tt)* ) => {
|
||||||
$v //~ ERROR still repeating at this depth
|
$v
|
||||||
)
|
//~^ ERROR still repeating at this depth
|
||||||
|
//~| ERROR still repeating at this depth
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
mac!(0);
|
mac!(0);
|
||||||
|
mac!(1);
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,11 @@ error: variable 'v' is still repeating at this depth
|
|||||||
LL | $v
|
LL | $v
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: variable 'v' is still repeating at this depth
|
||||||
|
--> $DIR/macro-repeat.rs:3:9
|
||||||
|
|
|
||||||
|
LL | $v
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
10
src/test/ui/parser/nt-parsing-has-recovery.rs
Normal file
10
src/test/ui/parser/nt-parsing-has-recovery.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
macro_rules! foo {
|
||||||
|
($e:expr) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
foo!(1 + @); //~ ERROR expected expression, found `@`
|
||||||
|
foo!(1 + @); //~ ERROR expected expression, found `@`
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||||
|
}
|
29
src/test/ui/parser/nt-parsing-has-recovery.stderr
Normal file
29
src/test/ui/parser/nt-parsing-has-recovery.stderr
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
error: expected expression, found `@`
|
||||||
|
--> $DIR/nt-parsing-has-recovery.rs:5:10
|
||||||
|
|
|
||||||
|
LL | ($e:expr) => {}
|
||||||
|
| ------- while parsing argument for this `expr` macro fragment
|
||||||
|
...
|
||||||
|
LL | foo!(1 + @);
|
||||||
|
| ^ expected expression
|
||||||
|
|
||||||
|
error: expected expression, found `@`
|
||||||
|
--> $DIR/nt-parsing-has-recovery.rs:6:10
|
||||||
|
|
|
||||||
|
LL | ($e:expr) => {}
|
||||||
|
| ------- while parsing argument for this `expr` macro fragment
|
||||||
|
...
|
||||||
|
LL | foo!(1 + @);
|
||||||
|
| ^ expected expression
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nt-parsing-has-recovery.rs:9:33
|
||||||
|
|
|
||||||
|
LL | let _recovery_witness: () = 0;
|
||||||
|
| -- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
use self::Direction::{North, East, South, West};
|
use self::Direction::{North, East, South, West};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0004]: non-exhaustive patterns: `(true, false)` not covered
|
error[E0004]: non-exhaustive patterns: `(true, false)` not covered
|
||||||
--> $DIR/match-arm-statics-2.rs:17:11
|
--> $DIR/match-arm-statics-2.rs:22:11
|
||||||
|
|
|
|
||||||
LL | match (true, false) {
|
LL | match (true, false) {
|
||||||
| ^^^^^^^^^^^^^ pattern `(true, false)` not covered
|
| ^^^^^^^^^^^^^ pattern `(true, false)` not covered
|
||||||
@ -7,15 +7,23 @@ LL | match (true, false) {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
|
error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
|
||||||
--> $DIR/match-arm-statics-2.rs:29:11
|
--> $DIR/match-arm-statics-2.rs:34:11
|
||||||
|
|
|
|
||||||
LL | match Some(Some(North)) {
|
LL | match Some(Some(North)) {
|
||||||
| ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
|
| ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||||
|
| ----
|
||||||
|
| |
|
||||||
|
| not covered
|
||||||
|
| not covered
|
||||||
|
|
|
|
||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
|
error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
|
||||||
--> $DIR/match-arm-statics-2.rs:48:11
|
--> $DIR/match-arm-statics-2.rs:53:11
|
||||||
|
|
|
|
||||||
LL | / struct Foo {
|
LL | / struct Foo {
|
||||||
LL | | bar: Option<Direction>,
|
LL | | bar: Option<Direction>,
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
|
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
|
||||||
--> $DIR/match-privately-empty.rs:13:11
|
--> $DIR/match-privately-empty.rs:18:11
|
||||||
|
|
|
|
||||||
LL | match private::DATA {
|
LL | match private::DATA {
|
||||||
| ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
|
| ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||||
|
| ---- not covered
|
||||||
|
|
|
|
||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// FIXME: missing sysroot spans (#53081)
|
||||||
|
// ignore-i586-unknown-linux-gnu
|
||||||
|
// ignore-i586-unknown-linux-musl
|
||||||
|
// ignore-i686-unknown-linux-musl
|
||||||
|
|
||||||
#![allow(illegal_floating_point_literal_pattern)]
|
#![allow(illegal_floating_point_literal_pattern)]
|
||||||
|
|
||||||
enum T { A, B }
|
enum T { A, B }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0004]: non-exhaustive patterns: `A` not covered
|
error[E0004]: non-exhaustive patterns: `A` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:7:11
|
--> $DIR/non-exhaustive-match.rs:12:11
|
||||||
|
|
|
|
||||||
LL | enum T { A, B }
|
LL | enum T { A, B }
|
||||||
| ---------------
|
| ---------------
|
||||||
@ -13,7 +13,7 @@ LL | match x { T::B => { } }
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `false` not covered
|
error[E0004]: non-exhaustive patterns: `false` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:8:11
|
--> $DIR/non-exhaustive-match.rs:13:11
|
||||||
|
|
|
|
||||||
LL | match true {
|
LL | match true {
|
||||||
| ^^^^ pattern `false` not covered
|
| ^^^^ pattern `false` not covered
|
||||||
@ -21,15 +21,20 @@ LL | match true {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:11:11
|
--> $DIR/non-exhaustive-match.rs:16:11
|
||||||
|
|
|
|
||||||
LL | match Some(10) {
|
LL | match Some(10) {
|
||||||
| ^^^^^^^^ pattern `Some(_)` not covered
|
| ^^^^^^^^ pattern `Some(_)` not covered
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||||
|
| ---- not covered
|
||||||
|
|
|
|
||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
|
error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:14:11
|
--> $DIR/non-exhaustive-match.rs:19:11
|
||||||
|
|
|
|
||||||
LL | match (2, 3, 4) {
|
LL | match (2, 3, 4) {
|
||||||
| ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
|
| ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
|
||||||
@ -37,7 +42,7 @@ LL | match (2, 3, 4) {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `(A, A)` not covered
|
error[E0004]: non-exhaustive patterns: `(A, A)` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:18:11
|
--> $DIR/non-exhaustive-match.rs:23:11
|
||||||
|
|
|
|
||||||
LL | match (T::A, T::A) {
|
LL | match (T::A, T::A) {
|
||||||
| ^^^^^^^^^^^^ pattern `(A, A)` not covered
|
| ^^^^^^^^^^^^ pattern `(A, A)` not covered
|
||||||
@ -45,7 +50,7 @@ LL | match (T::A, T::A) {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `B` not covered
|
error[E0004]: non-exhaustive patterns: `B` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:22:11
|
--> $DIR/non-exhaustive-match.rs:27:11
|
||||||
|
|
|
|
||||||
LL | enum T { A, B }
|
LL | enum T { A, B }
|
||||||
| ---------------
|
| ---------------
|
||||||
@ -59,7 +64,7 @@ LL | match T::A {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `[]` not covered
|
error[E0004]: non-exhaustive patterns: `[]` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:33:11
|
--> $DIR/non-exhaustive-match.rs:38:11
|
||||||
|
|
|
|
||||||
LL | match *vec {
|
LL | match *vec {
|
||||||
| ^^^^ pattern `[]` not covered
|
| ^^^^ pattern `[]` not covered
|
||||||
@ -67,7 +72,7 @@ LL | match *vec {
|
|||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
|
error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
|
||||||
--> $DIR/non-exhaustive-match.rs:46:11
|
--> $DIR/non-exhaustive-match.rs:51:11
|
||||||
|
|
|
|
||||||
LL | match *vec {
|
LL | match *vec {
|
||||||
| ^^^^ pattern `[_, _, _, _, ..]` not covered
|
| ^^^^ pattern `[_, _, _, _, ..]` not covered
|
||||||
|
@ -3,11 +3,9 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate derive_bad;
|
extern crate derive_bad;
|
||||||
|
|
||||||
#[derive(
|
#[derive(A)]
|
||||||
A
|
//~^ ERROR proc-macro derive produced unparseable tokens
|
||||||
)]
|
|
||||||
//~^^ ERROR proc-macro derive produced unparseable tokens
|
|
||||||
//~| ERROR expected `:`, found `}`
|
//~| ERROR expected `:`, found `}`
|
||||||
struct A;
|
struct A; //~ ERROR the name `A` is defined multiple times
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,16 +1,28 @@
|
|||||||
error: expected `:`, found `}`
|
error: expected `:`, found `}`
|
||||||
--> $DIR/derive-bad.rs:7:5
|
--> $DIR/derive-bad.rs:6:10
|
||||||
|
|
|
|
||||||
LL | A
|
LL | #[derive(A)]
|
||||||
| ^ expected `:`
|
| ^ expected `:`
|
||||||
|
|
|
|
||||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: proc-macro derive produced unparseable tokens
|
error: proc-macro derive produced unparseable tokens
|
||||||
--> $DIR/derive-bad.rs:7:5
|
--> $DIR/derive-bad.rs:6:10
|
||||||
|
|
|
|
||||||
LL | A
|
LL | #[derive(A)]
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error[E0428]: the name `A` is defined multiple times
|
||||||
|
--> $DIR/derive-bad.rs:9:1
|
||||||
|
|
|
||||||
|
LL | #[derive(A)]
|
||||||
|
| - previous definition of the type `A` here
|
||||||
|
...
|
||||||
|
LL | struct A;
|
||||||
|
| ^^^^^^^^^ `A` redefined here
|
||||||
|
|
|
||||||
|
= note: `A` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0428`.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user