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:
bors 2020-03-24 06:14:41 +00:00
commit 9d0ae58d30
126 changed files with 1522 additions and 649 deletions

View File

@ -16,7 +16,7 @@ has explicitly opted out via a negative impl.
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
```rust,ignore
impl !Type for Trait
impl !Trait for Type
```
Example:

View File

@ -3,7 +3,6 @@
use rustc_ast::ast::{self, AttrItem, AttrStyle};
use rustc_ast::attr::mk_attr;
use rustc_ast::token;
use rustc_expand::panictry;
use rustc_session::parse::ParseSess;
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 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;
if parser.token != token::Eof {
parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute");

View File

@ -5,7 +5,6 @@ use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_expand::base::{self, *};
use rustc_expand::module::DirectoryOwnership;
use rustc_expand::panictry;
use rustc_parse::{self, new_parser_from_file, parser::Parser};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
use rustc_span::symbol::Symbol;
@ -126,7 +125,7 @@ pub fn expand_include<'cx>(
}
impl<'a> base::MacResult for ExpandResult<'a> {
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 {
self.p.sess.buffer_lint(
&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]>> {
let mut ret = SmallVec::new();
while self.p.token != token::Eof {
match panictry!(self.p.parse_item()) {
Some(item) => ret.push(item),
None => {
match self.p.parse_item() {
Err(mut err) => {
err.emit();
break;
}
Ok(Some(item)) => ret.push(item),
Ok(None) => {
let token = pprust::token_to_string(&self.p.token);
self.p
.sess
.span_diagnostic
.span_fatal(
self.p.token.span,
&format!("expected item, found `{}`", token),
)
.raise();
let msg = format!("expected item, found `{}`", token);
self.p.struct_span_err(self.p.token.span, &msg).emit();
break;
}
}
}

View File

@ -74,16 +74,16 @@ pub fn expand_test_or_bench(
return vec![];
}
let item = if let Annotatable::Item(i) = item {
i
} else {
cx.parse_sess
.span_diagnostic
.span_fatal(
item.span(),
let item = match item {
Annotatable::Item(i) => i,
other => {
cx.struct_span_err(
other.span(),
"`#[test]` attribute is only allowed on non associated functions",
)
.raise();
.emit();
return vec![other];
}
};
if let ast::ItemKind::MacCall(_) = item.kind {

View File

@ -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> {
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
test_attr.meta_item_list().map(|meta_list| {
if meta_list.len() != 1 {
sd.span_fatal(test_attr.span, "`#![test_runner(..)]` accepts exactly 1 argument")
.raise()
}
match meta_list[0].meta_item() {
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(),
}
})
let meta_list = test_attr.meta_item_list()?;
let span = test_attr.span;
match &*meta_list {
[single] => match single.meta_item() {
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
_ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(),
},
_ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(),
}
None
}

View File

@ -16,7 +16,7 @@ use crate::ModuleLlvm;
use log::debug;
use rustc::bug;
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::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
use rustc_data_structures::small_c_str::SmallCStr;
@ -634,30 +634,24 @@ pub(crate) unsafe fn codegen(
f(cpm)
}
// If we don't have the integrated assembler, then we need to emit asm
// from LLVM and use `gcc` to create the object file.
let asm_to_obj = config.emit_obj && config.no_integrated_as;
// Change what we write and cleanup based on whether obj files are
// just llvm bitcode. In that case write bitcode, and possibly
// 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;
// Two things to note:
// - If object files are just LLVM bitcode we write bitcode, copy it to
// the .o file, and delete the bitcode if it wasn't otherwise
// requested.
// - If we don't have the integrated assembler then we need to emit
// asm from LLVM and use `gcc` to create the object file.
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, 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
.prof
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]);
let thin = ThinBuffer::new(llmod);
let data = thin.data();
if write_bc {
if config.emit_bc || config.obj_is_bitcode {
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_bitcode",
&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(
"LLVM_module_codegen_embed_bitcode",
&module.name[..],
@ -688,81 +682,75 @@ pub(crate) unsafe fn codegen(
diag_handler.err(&msg);
}
}
} else if config.embed_bitcode_marker {
} else if config.embed_bitcode == EmbedBitcode::Marker {
embed_bitcode(cgcx, llcx, llmod, None);
}
{
if config.emit_ir {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
let out_c = path_to_c_string(&out);
if config.emit_ir {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
let out_c = path_to_c_string(&out);
extern "C" fn demangle_callback(
input_ptr: *const c_char,
input_len: size_t,
output_ptr: *mut c_char,
output_len: size_t,
) -> size_t {
let input = unsafe {
slice::from_raw_parts(input_ptr as *const u8, input_len as usize)
};
extern "C" fn demangle_callback(
input_ptr: *const c_char,
input_len: size_t,
output_ptr: *mut c_char,
output_len: size_t,
) -> size_t {
let input =
unsafe { slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
let input = match str::from_utf8(input) {
Ok(s) => s,
Err(_) => return 0,
};
let input = match str::from_utf8(input) {
Ok(s) => s,
Err(_) => return 0,
};
let output = unsafe {
slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
};
let mut cursor = io::Cursor::new(output);
let output = unsafe {
slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
};
let mut cursor = io::Cursor::new(output);
let demangled = match rustc_demangle::try_demangle(input) {
Ok(d) => d,
Err(_) => return 0,
};
let demangled = match rustc_demangle::try_demangle(input) {
Ok(d) => d,
Err(_) => return 0,
};
if write!(cursor, "{:#}", demangled).is_err() {
// Possible only if provided buffer is not big enough
return 0;
}
cursor.position() as size_t
if write!(cursor, "{:#}", demangled).is_err() {
// Possible only if provided buffer is not big enough
return 0;
}
let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
result.into_result().map_err(|()| {
let msg = format!("failed to write LLVM IR to {}", out.display());
llvm_err(diag_handler, &msg)
})?;
cursor.position() as size_t
}
if config.emit_asm || asm_to_obj {
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);
let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
result.into_result().map_err(|()| {
let msg = format!("failed to write LLVM IR to {}", out.display());
llvm_err(diag_handler, &msg)
})?;
}
// 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,
)
})?;
}
let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
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
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
@ -776,7 +764,7 @@ pub(crate) unsafe fn codegen(
llvm::FileType::ObjectFile,
)
})?;
} else if asm_to_obj {
} else {
let _timer = cgcx
.prof
.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 {
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
if config.obj_is_bitcode {
if config.emit_obj {
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
}
}
}
if rm_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
diag_handler.err(&format!("failed to remove bitcode: {}", e));
if !config.emit_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
diag_handler.err(&format!("failed to remove bitcode: {}", e));
}
}
}

View File

@ -51,6 +51,14 @@ use std::thread;
const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
/// The kind of bitcode to embed in object files.
#[derive(PartialEq)]
pub enum EmbedBitcode {
None,
Marker,
Full,
}
/// Module-specific configuration for `optimize_and_codegen`.
pub struct ModuleConfig {
/// Names of additional optimization passes to run.
@ -74,7 +82,6 @@ pub struct ModuleConfig {
pub emit_no_opt_bc: bool,
pub emit_bc: bool,
pub emit_bc_compressed: bool,
pub emit_lto_bc: bool,
pub emit_ir: bool,
pub emit_asm: bool,
pub emit_obj: bool,
@ -94,8 +101,7 @@ pub struct ModuleConfig {
// emscripten's ecc compiler, when used as the linker.
pub obj_is_bitcode: bool,
pub no_integrated_as: bool,
pub embed_bitcode: bool,
pub embed_bitcode_marker: bool,
pub embed_bitcode: EmbedBitcode,
}
impl ModuleConfig {
@ -116,13 +122,11 @@ impl ModuleConfig {
emit_pre_lto_bc: false,
emit_bc: false,
emit_bc_compressed: false,
emit_lto_bc: false,
emit_ir: false,
emit_asm: false,
emit_obj: false,
obj_is_bitcode: false,
embed_bitcode: false,
embed_bitcode_marker: false,
embed_bitcode: EmbedBitcode::None,
no_integrated_as: 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.obj_is_bitcode =
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
let embed_bitcode =
sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode;
if embed_bitcode {
match sess.opts.optimize {
config::OptLevel::No | config::OptLevel::Less => {
self.embed_bitcode_marker = embed_bitcode;
self.embed_bitcode =
if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode {
match sess.opts.optimize {
config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
_ => EmbedBitcode::Full,
}
_ => self.embed_bitcode = embed_bitcode,
}
}
} else {
EmbedBitcode::None
};
// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3. Otherwise configure other optimization aspects
@ -190,7 +193,10 @@ impl ModuleConfig {
}
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_pre_lto_bc = true;
modules_config.emit_bc = true;
modules_config.emit_lto_bc = true;
metadata_config.emit_bc = true;
allocator_config.emit_bc = true;
}

View File

@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
use rustc_data_structures::fx::FxHashMap;
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_session::parse::ParseSess;
use rustc_span::edition::Edition;
@ -296,16 +296,26 @@ where
}
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
where
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.
(*self)(ts)
Ok((*self)(ts))
}
}
@ -316,7 +326,7 @@ pub trait AttrProcMacro {
span: Span,
annotation: TokenStream,
annotated: TokenStream,
) -> TokenStream;
) -> Result<TokenStream, ErrorReported>;
}
impl<F> AttrProcMacro for F
@ -329,9 +339,9 @@ where
_span: Span,
annotation: TokenStream,
annotated: TokenStream,
) -> TokenStream {
) -> Result<TokenStream, ErrorReported> {
// 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()
}
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> {
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
/// compilation.
@ -1038,9 +1026,6 @@ impl<'a> ExtCtxt<'a> {
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
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) {
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,
/// expect exactly one string literal, or emit an error and return `None`.
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));
return None;
}
let ret = panictry!(p.parse_expr());
let ret = parse_expr(&mut p)?;
let _ = p.eat(&token::Comma);
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())
}
/// Extracts comma-separated expressions from `tts`. If there is a
/// parsing error, emit a non-fatal error and return `None`.
/// Extracts comma-separated expressions from `tts`.
/// On error, emit it, and return `None`.
pub fn get_exprs_from_tts(
cx: &mut ExtCtxt<'_>,
sp: Span,
@ -1200,7 +1197,7 @@ pub fn get_exprs_from_tts(
let mut p = cx.new_parser_from_tts(tts);
let mut es = Vec::new();
while p.token != token::Eof {
let expr = panictry!(p.parse_expr());
let expr = parse_expr(&mut p)?;
// Perform eager expansion on the expression.
// We want to be able to handle e.g., `concat!("foo", "bar")`.

View File

@ -204,7 +204,7 @@ ast_fragments! {
}
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")
}
@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
InvocationKind::Bang { mac, .. } => match ext {
SyntaxExtensionKind::Bang(expander) => {
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)
}
SyntaxExtensionKind::LegacyBang(expander) => {
@ -709,8 +712,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
if let MacArgs::Eq(..) = attr_item.args {
self.cx.span_err(span, "key-value macro attributes are not supported");
}
let tok_result =
expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens);
let inner_tokens = attr_item.args.inner_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)
}
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
if attr.has_name(sym::derive) {
self.cx
.parse_sess()
.span_diagnostic
.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
.note("this may become a hard error in a future release")
.emit();

View File

@ -9,25 +9,6 @@
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 proc_macro_server;

View File

@ -84,7 +84,7 @@ use rustc_parse::parser::{FollowedByType, Parser, PathStyle};
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
use rustc_errors::{FatalError, PResult};
use rustc_errors::PResult;
use rustc_span::Span;
use smallvec::{smallvec, SmallVec};
@ -271,6 +271,7 @@ crate enum ParseResult<T> {
Failure(Token, &'static str),
/// Fatal error (malformed macro?). Abort compilation.
Error(rustc_span::Span, String),
ErrorReported,
}
/// 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(_) => {}
Failure(token, msg) => return Failure(token, msg),
Error(sp, msg) => return Error(sp, msg),
ErrorReported => return ErrorReported,
}
// 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();
if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) {
let match_cur = item.match_cur;
item.push_match(
match_cur,
MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))),
);
let nt = match parse_nt(parser.to_mut(), span, ident.name) {
Err(()) => return ErrorReported,
Ok(nt) => nt,
};
item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
item.idx += 1;
item.match_cur += 1;
} else {
@ -849,20 +852,16 @@ fn may_begin_with(token: &Token, name: Name) -> bool {
/// # Returns
///
/// 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
// the visibilities of the methods used below `pub(super)` at most.
if name == sym::tt {
return token::NtTT(p.parse_token_tree());
}
match parse_nt_inner(p, sp, name) {
Ok(nt) => nt,
Err(mut err) => {
err.emit();
FatalError.raise();
}
return Ok(token::NtTT(p.parse_token_tree()));
}
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> {

View File

@ -4,7 +4,7 @@ use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstF
use crate::mbe;
use crate::mbe::macro_check;
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::transcribe::transcribe;
@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, TransparencyError};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder, FatalError};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_feature::Features;
use rustc_parse::parser::Parser;
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> {
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| {
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,
);
let fragment = match parse_ast_fragment(parser, kind) {
Ok(f) => f,
Err(err) => {
emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
return kind.dummy(site_span);
}
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
// `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) {
let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
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<_>>();
// 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
// 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() => {}
_ => 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.
@ -337,6 +371,18 @@ pub fn compile_declarative_macro(
def: &ast::Item,
edition: Edition,
) -> 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 lhs_nm = ast::Ident::new(sym::lhs, def.span);
let rhs_nm = ast::Ident::new(sym::rhs, def.span);
@ -391,13 +437,15 @@ pub fn compile_declarative_macro(
Failure(token, msg) => {
let s = parse_failure_msg(&token);
let sp = token.span.substitute_dummy(def.span);
let mut err = sess.span_diagnostic.struct_span_fatal(sp, &s);
err.span_label(sp, msg);
err.emit();
FatalError.raise();
sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
}
Error(sp, s) => {
sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
Error(sp, msg) => {
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 => {}
}
let expander: Box<_> = Box::new(MacroRulesMacroExpander {
mk_syn_ext(Box::new(MacroRulesMacroExpander {
name: def.ident,
span: def.span,
transparency,
lhses,
rhses,
valid,
});
SyntaxExtension::new(
sess,
SyntaxExtensionKind::LegacyBang(expander),
def.span,
Vec::new(),
edition,
def.ident.name,
&def.attrs,
)
}))
}
fn check_lhs_nt_follows(

View File

@ -8,7 +8,7 @@ use rustc_ast::token::{self, NtTT, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::pluralize;
use rustc_errors::{pluralize, PResult};
use rustc_span::hygiene::{ExpnId, Transparency};
use rustc_span::symbol::MacroRulesNormalizedIdent;
use rustc_span::Span;
@ -80,15 +80,15 @@ impl Iterator for Frame {
/// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
///
/// Along the way, we do some additional error checking.
pub(super) fn transcribe(
cx: &ExtCtxt<'_>,
pub(super) fn transcribe<'a>(
cx: &ExtCtxt<'a>,
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
src: Vec<mbe::TokenTree>,
transparency: Transparency,
) -> TokenStream {
) -> PResult<'a, TokenStream> {
// Nothing for us to transcribe...
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
@ -152,7 +152,7 @@ pub(super) fn transcribe(
Frame::Delimited { forest, span, .. } => {
if result_stack.is_empty() {
// 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.
@ -173,11 +173,11 @@ pub(super) fn transcribe(
seq @ mbe::TokenTree::Sequence(..) => {
match lockstep_iter_size(&seq, interp, &repeats) {
LockstepIterSize::Unconstrained => {
cx.span_fatal(
return Err(cx.struct_span_err(
seq.span(), /* blame macro writer */
"attempted to repeat an expression containing no syntax variables \
matched as repeating at this depth",
);
));
}
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
// sequence, but they come from different sequence matchers and repeat
// different amounts.
cx.span_fatal(seq.span(), &msg[..]);
return Err(cx.struct_span_err(seq.span(), &msg[..]));
}
LockstepIterSize::Constraint(len, _) => {
@ -203,7 +203,10 @@ pub(super) fn transcribe(
// FIXME: this really ought to be caught at macro definition
// time... It happens when the Kleene operator in the matcher and
// 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 {
// 0 is the initial counter (we have done 0 repretitions so far). `len`
@ -242,10 +245,10 @@ pub(super) fn transcribe(
}
} else {
// 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 */
&format!("variable '{}' is still repeating at this depth", ident),
);
));
}
} else {
// If we aren't able to match the meta-var, we push it back into the result but

View File

@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
use rustc_ast::token;
use rustc_ast::tokenstream::{self, TokenStream};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, FatalError};
use rustc_errors::{Applicability, ErrorReported};
use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
@ -21,21 +21,16 @@ impl base::ProcMacro for BangProcMacro {
ecx: &'cx mut ExtCtxt<'_>,
span: Span,
input: TokenStream,
) -> TokenStream {
) -> Result<TokenStream, ErrorReported> {
let server = proc_macro_server::Rustc::new(ecx);
match self.client.run(&EXEC_STRATEGY, server, input) {
Ok(stream) => stream,
Err(e) => {
let msg = "proc macro panicked";
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();
self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| {
let mut err = ecx.struct_span_err(span, "proc macro panicked");
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
}
err.emit();
ErrorReported
})
}
}
@ -50,21 +45,16 @@ impl base::AttrProcMacro for AttrProcMacro {
span: Span,
annotation: TokenStream,
annotated: TokenStream,
) -> TokenStream {
) -> Result<TokenStream, ErrorReported> {
let server = proc_macro_server::Rustc::new(ecx);
match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) {
Ok(stream) => stream,
Err(e) => {
let msg = "custom attribute panicked";
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();
self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| {
let mut err = ecx.struct_span_err(span, "custom attribute panicked");
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
}
err.emit();
ErrorReported
})
}
}
@ -96,8 +86,7 @@ impl MultiItemModifier for ProcMacroDerive {
| Annotatable::Expr(_) => {
ecx.span_err(
span,
"proc-macro derives may only be \
applied to a struct, enum, or union",
"proc-macro derives may only be applied to a struct, enum, or union",
);
return ExpandResult::Ready(Vec::new());
}
@ -107,8 +96,7 @@ impl MultiItemModifier for ProcMacroDerive {
_ => {
ecx.span_err(
span,
"proc-macro derives may only be \
applied to a struct, enum, or union",
"proc-macro derives may only be applied to a struct, enum, or union",
);
return ExpandResult::Ready(Vec::new());
}
@ -121,20 +109,16 @@ impl MultiItemModifier for ProcMacroDerive {
let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
Ok(stream) => stream,
Err(e) => {
let msg = "proc-macro derive panicked";
let mut err = ecx.struct_span_fatal(span, msg);
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
err.emit();
FatalError.raise();
return ExpandResult::Ready(vec![]);
}
};
let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
let msg = "proc-macro derive produced unparseable tokens";
let mut parser =
rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
let mut items = vec![];
@ -144,18 +128,15 @@ impl MultiItemModifier for ProcMacroDerive {
Ok(None) => break,
Ok(Some(item)) => items.push(Annotatable::Item(item)),
Err(mut err) => {
// FIXME: handle this better
err.cancel();
ecx.struct_span_fatal(span, msg).emit();
FatalError.raise();
err.emit();
break;
}
}
}
// fail if there have been errors emitted
if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
ecx.struct_span_fatal(span, msg).emit();
FatalError.raise();
ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit();
}
ExpandResult::Ready(items)

View File

@ -159,6 +159,7 @@ impl DefKind {
}
}
/// The resolution of a path or export.
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(HashStable_Generic)]
pub enum Res<Id = hir::HirId> {

View File

@ -19,7 +19,7 @@ use rustc::traits::select;
use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use rustc::ty::fold::{TypeFoldable, TypeFolder};
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;
use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
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)]
pub enum FixupError<'tcx> {
UnresolvedIntTy(IntVid),
@ -1347,8 +1348,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
where
T: TypeFoldable<'tcx>,
{
let mut r = ShallowResolver::new(self);
value.fold_with(&mut r)
value.fold_with(&mut ShallowResolver { infcx: self })
}
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.
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
/// (but do not resolve types found in the result). If `typ` is
/// 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 {
ty::Infer(ty::TyVar(v)) => {
// Not entirely obvious: if `typ` is a type variable,
@ -1580,78 +1570,142 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
// depth.
//
// Note: if these two lines are combined into one we get
// dynamic borrow errors on `self.infcx.inner`.
let known = self.infcx.inner.borrow_mut().type_variables.probe(v).known();
known.map(|t| self.fold_ty(t)).unwrap_or(typ)
// dynamic borrow errors on `self.inner`.
let known = self.inner.borrow_mut().type_variables.probe(v).known();
known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ)
}
ty::Infer(ty::IntVar(v)) => self
.infcx
.inner
.borrow_mut()
.int_unification_table
.probe_value(v)
.map(|v| v.to_type(self.infcx.tcx))
.map(|v| v.to_type(self.tcx))
.unwrap_or(typ),
ty::Infer(ty::FloatVar(v)) => self
.infcx
.inner
.borrow_mut()
.float_unification_table
.probe_value(v)
.map(|v| v.to_type(self.infcx.tcx))
.map(|v| v.to_type(self.tcx))
.unwrap_or(typ),
_ => typ,
}
}
// `resolver.shallow_resolve_changed(ty)` is equivalent to
// `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
// inlined, despite being large, because it has only two call sites that
// are extremely hot.
/// `ty_or_const_infer_var_changed` is equivalent to one of these two:
/// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
/// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
///
/// 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)]
pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool {
match infer {
ty::TyVar(v) => {
pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool {
match infer_var {
TyOrConstInferVar::Ty(v) => {
use self::type_variable::TypeVariableValue;
// If `inlined_probe` returns a `Known` value its `kind` never
// matches `infer`.
match self.infcx.inner.borrow_mut().type_variables.inlined_probe(v) {
// If `inlined_probe` returns a `Known` value, it never equals
// `ty::Infer(ty::TyVar(v))`.
match self.inner.borrow_mut().type_variables.inlined_probe(v) {
TypeVariableValue::Unknown { .. } => false,
TypeVariableValue::Known { .. } => true,
}
}
ty::IntVar(v) => {
// If inlined_probe_value returns a value it's always a
TyOrConstInferVar::TyInt(v) => {
// If `inlined_probe_value` returns a value it's always a
// `ty::Int(_)` or `ty::UInt(_)`, which never matches a
// `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) => {
// If inlined_probe_value returns a value it's always a
TyOrConstInferVar::TyFloat(v) => {
// If `probe_value` returns a value it's always a
// `ty::Float(_)`, which never matches a `ty::Infer(_)`.
//
// 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> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.infcx.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> {

View File

@ -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> {
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
Fingerprint::decode_opaque(&mut self.opaque)
@ -663,15 +655,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
&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) {
self.def_key(item_index)
let name = self
.def_key(item_index)
.disambiguated_data
.data
.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 {
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,
index: DefIndex,
parent_did: DefId,
sess: &Session,
) -> ty::VariantDef {
let data = match kind {
EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
@ -771,7 +776,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
ty::VariantDef::new(
tcx,
Ident::with_dummy_span(self.item_name(index)),
self.item_ident(index, sess),
variant_did,
ctor_did,
data.discr,
@ -783,7 +788,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode(self)
.map(|index| ty::FieldDef {
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),
})
.collect(),
@ -812,10 +817,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.get(self, item_id)
.unwrap_or(Lazy::empty())
.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()
} 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)
@ -1007,7 +1012,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
if let Some(kind) = self.def_kind(child_index) {
callback(Export {
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),
span: self
.root
@ -1028,10 +1033,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let def_key = self.def_key(child_index);
let span = self.get_span(child_index, sess);
if let (Some(kind), Some(name)) =
(self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name())
{
let ident = Ident::with_dummy_span(name);
if let (Some(kind), true) = (
self.def_kind(child_index),
def_key.disambiguated_data.data.get_opt_name().is_some(),
) {
let ident = self.item_ident(child_index, sess);
let vis = self.get_visibility(child_index);
let def_id = self.local_def_id(child_index);
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 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) {
EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
@ -1155,7 +1161,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
};
ty::AssocItem {
ident: Ident::with_dummy_span(name),
ident,
kind,
vis: self.get_visibility(id),
defaultness: container.defaultness(),
@ -1219,7 +1225,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.get(self, id)
.unwrap_or(Lazy::empty())
.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()
}

View File

@ -110,7 +110,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|child| result.push(child.res.def_id()), tcx.sess);
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_polarity => { cdata.get_impl_polarity(def_id.index) }
coerce_unsized_info => {
@ -442,8 +442,8 @@ impl CStore {
)
}
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
self.get_crate_data(def.krate).get_associated_item(def.index)
pub fn associated_item_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::AssocItem {
self.get_crate_data(def.krate).get_associated_item(def.index, sess)
}
pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {

View File

@ -12,7 +12,7 @@ use rustc::traits::specialization_graph;
use rustc::ty::codec::{self as ty_codec, TyEncoder};
use rustc::ty::layout::VariantIdx;
use rustc::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_ast::ast;
use rustc_ast::ast::{self, Ident};
use rustc_ast::attr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
@ -30,7 +30,7 @@ use rustc_index::vec::Idx;
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
use rustc_session::config::{self, CrateType};
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 std::hash::Hash;
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> {
#[inline]
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
@ -633,6 +626,7 @@ impl EncodeContext<'tcx> {
assert!(f.did.is_local());
f.did.index
}));
self.encode_ident_span(def_id, variant.ident);
self.encode_stability(def_id);
self.encode_deprecation(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.span[def_id] <- self.tcx.def_span(def_id));
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_deprecation(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.span[def_id] <- ast_item.span);
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_const_stability(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.span[def_id] <- ast_item.span);
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_const_stability(def_id);
self.encode_deprecation(def_id);
@ -1058,6 +1055,8 @@ impl EncodeContext<'tcx> {
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 {
hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
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.span[def_id] <- macro_def.span);
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_deprecation(def_id);
}
@ -1528,6 +1528,7 @@ impl EncodeContext<'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.attributes[def_id] <- nitem.attrs);
self.encode_ident_span(def_id, nitem.ident);
self.encode_stability(def_id);
self.encode_const_stability(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
/// 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

View File

@ -256,6 +256,7 @@ define_per_def_tables! {
kind: Table<DefIndex, Lazy<EntryKind>>,
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
span: Table<DefIndex, Lazy<Span>>,
ident_span: Table<DefIndex, Lazy<Span>>,
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
children: Table<DefIndex, Lazy<[DefIndex]>>,
stability: Table<DefIndex, Lazy<attr::Stability>>,

View File

@ -337,14 +337,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
) -> ConstPropagator<'mir, 'tcx> {
let def_id = source.def_id();
let substs = &InternalSubsts::identity_for_item(tcx, def_id);
let mut param_env = tcx.param_env(def_id);
// 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 param_env = tcx.param_env(def_id).with_reveal_all();
let span = tcx.def_span(def_id);
let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());

View File

@ -3,8 +3,8 @@
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc::mir::visit::*;
use rustc::mir::*;
use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc::ty::subst::{Subst, SubstsRef};
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_attr as attr;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet;
@ -66,14 +66,7 @@ impl Inliner<'tcx> {
let mut callsites = VecDeque::new();
let mut param_env = self.tcx.param_env(self.source.def_id());
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();
}
let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all();
// Only do inlining into fn bodies.
let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();

View File

@ -139,7 +139,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
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(),
_ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
};

View File

@ -904,7 +904,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.insert_field_names(def_id, field_names);
}
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);
}
}

View File

@ -1,4 +1,4 @@
use crate::infer::{InferCtxt, ShallowResolver};
use crate::infer::{InferCtxt, TyOrConstInferVar};
use rustc::ty::error::ExpectedFound;
use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
use rustc_data_structures::obligation_forest::ProcessResult;
@ -73,7 +73,10 @@ pub struct FulfillmentContext<'tcx> {
#[derive(Clone, Debug)]
pub struct PendingPredicateObligation<'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.
@ -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
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
1 => {
let infer = pending_obligation.stalled_on[0];
ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer)
let infer_var = pending_obligation.stalled_on[0];
self.selcx.infcx().ty_or_const_infer_var_changed(infer_var)
}
0 => {
// 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
// form was a perf win. See #64545 for details.
(|| {
for &infer in &pending_obligation.stalled_on {
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) {
for &infer_var in &pending_obligation.stalled_on {
if self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) {
return true;
}
}
@ -309,13 +312,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
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 {
ty::Predicate::Trait(ref data, _) => {
let trait_obligation = obligation.with(data.clone());
@ -467,7 +463,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
obligation.cause.span,
) {
None => {
pending_obligation.stalled_on = vec![infer_ty(ty)];
pending_obligation.stalled_on =
vec![TyOrConstInferVar::maybe_from_ty(ty).unwrap()];
ProcessResult::Unchanged
}
Some(os) => ProcessResult::Changed(mk_pending(os)),
@ -483,8 +480,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
None => {
// None means that both are unresolved.
pending_obligation.stalled_on = vec![
infer_ty(subtype.skip_binder().a),
infer_ty(subtype.skip_binder().b),
TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().a).unwrap(),
TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().b).unwrap(),
];
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>(
selcx: &mut SelectionContext<'a, 'tcx>,
t: ty::PolyTraitRef<'tcx>,
) -> Vec<ty::InferTy> {
t.skip_binder() // ok b/c this check doesn't care about regions
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Vec<TyOrConstInferVar<'tcx>> {
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()
.map(|t| selcx.infcx().resolve_vars_if_possible(&t))
.filter(|t| t.has_infer_types())
.flat_map(|t| t.walk())
.filter_map(|t| match t.kind {
ty::Infer(infer) => Some(infer),
_ => None,
})
.map(|ty| selcx.infcx().resolve_vars_if_possible(&ty))
// FIXME(eddyb) try using `maybe_walk` to skip *all* subtrees that
// don't contain inference variables, not just the outermost level.
// FIXME(eddyb) use `has_infer_types_or_const`.
.filter(|ty| ty.has_infer_types())
.flat_map(|ty| ty.walk())
// FIXME(eddyb) use `TyOrConstInferVar::maybe_from_generic_arg`.
.filter_map(TyOrConstInferVar::maybe_from_ty)
.collect()
}

View File

@ -188,12 +188,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::Field(field) => icx.to_ty(&field.ty),
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);
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(_) => {
@ -235,29 +235,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
};
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
.iter()
.filter_map(|seg| seg.args.as_ref())
.map(|generic_args| generic_args.args)
.find_map(|args| {
.filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
.find_map(|(args, seg)| {
args.iter()
.filter(|arg| arg.is_const())
.enumerate()
.filter(|(_, arg)| arg.id() == hir_id)
.map(|(index, _)| index)
.map(|(index, _)| (index, seg))
.next()
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in 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 generics = match path.res {
Res::Def(DefKind::Ctor(..), def_id)
| Res::Def(DefKind::AssocTy, def_id) => {
// Try to use the segment resolution if it is valid, otherwise we
// default to the path resolution.
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
let generics = match res {
Res::Def(DefKind::Ctor(..), def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap())
}
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(
DUMMY_SP,
&format!(
"unexpected const parent path def, parent: {:?}, def: {:?}",
parent_node, res
"unexpected anon const res {:?} in path: {:?}",
res, path,
),
);
return tcx.types.err;
@ -291,8 +293,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
"missing generic parameter for `AnonConst`, parent {:?}",
parent_node
"missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
parent_node, res
),
);
tcx.types.err

View File

@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(or_patterns)]
#![feature(try_blocks)]
#![feature(never_type)]
#![feature(slice_partition_dedup)]

View 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

View File

@ -18,22 +18,6 @@ LL | | break 0u8;
LL | | };
| |_________- 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 = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= 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:22:58
|
@ -55,6 +39,22 @@ LL | let _: &dyn Future<Output = ()> = &block;
|
= 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 = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= 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:48:44
|

View File

@ -5,6 +5,7 @@
use std::future::Future;
fn get_future() -> impl Future<Output = ()> {
//~^ ERROR the trait bound `(): std::future::Future` is not satisfied
panic!()
}

View File

@ -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
--> $DIR/async-error-span.rs:12:9
--> $DIR/async-error-span.rs:13:9
|
LL | let a;
| ^ cannot infer type
|
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;
| ^^^^^^^^^^^^^^^^^^
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`.

View File

@ -62,6 +62,7 @@ fn foo10() -> Result<(), ()> {
fn foo11() -> Result<(), ()> {
let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
//~^ ERROR incorrect use of `await`
//~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
Ok(())
}
fn foo12() -> Result<(), ()> {

View File

@ -71,49 +71,49 @@ LL | let _ = await bar()?;
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:68:14
--> $DIR/incorrect-syntax-suggestions.rs:69:14
|
LL | let _ = (await bar())?;
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:73:24
--> $DIR/incorrect-syntax-suggestions.rs:74:24
|
LL | let _ = bar().await();
| ^^ help: `await` is not a method call, remove the parentheses
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:78:24
--> $DIR/incorrect-syntax-suggestions.rs:79:24
|
LL | let _ = bar().await()?;
| ^^ help: `await` is not a method call, remove the parentheses
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:106:13
--> $DIR/incorrect-syntax-suggestions.rs:107:13
|
LL | let _ = await!(bar());
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:110:13
--> $DIR/incorrect-syntax-suggestions.rs:111:13
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:115:17
--> $DIR/incorrect-syntax-suggestions.rs:116:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:123:17
--> $DIR/incorrect-syntax-suggestions.rs:124:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
error: expected expression, found `=>`
--> $DIR/incorrect-syntax-suggestions.rs:131:25
--> $DIR/incorrect-syntax-suggestions.rs:132:25
|
LL | match await { await => () }
| ----- ^^ expected expression
@ -121,13 +121,13 @@ LL | match await { await => () }
| while parsing this incorrect await expression
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:131:11
--> $DIR/incorrect-syntax-suggestions.rs:132:11
|
LL | match await { await => () }
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
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 => () }
| ----- - expected one of `.`, `?`, `{`, or an operator
@ -162,7 +162,7 @@ LL | let _ = await bar()?;
| ^^^^^^^^^^^^ 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<(), ()> {
| ----- this is not `async`
@ -170,7 +170,7 @@ LL | let _ = (await bar())?;
| ^^^^^^^^^^^ 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<(), ()> {
| ----- this is not `async`
@ -178,7 +178,7 @@ LL | let _ = bar().await();
| ^^^^^^^^^^^ 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<(), ()> {
| ----- this is not `async`
@ -186,7 +186,7 @@ LL | let _ = bar().await()?;
| ^^^^^^^^^^^ 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<(), ()> {
| ----- this is not `async`
@ -194,7 +194,7 @@ LL | let _ = bar().await;
| ^^^^^^^^^^^ 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<(), ()> {
| ----- this is not `async`
@ -202,7 +202,7 @@ LL | let _ = bar().await?;
| ^^^^^^^^^^^ 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<(), ()> {
| --- this is not `async`
@ -210,7 +210,7 @@ LL | let _ = bar().await?;
| ^^^^^^^^^^^ 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 = || {
| -- this is not `async`
@ -218,7 +218,7 @@ LL | let _ = bar().await?;
| ^^^^^^^^^^^ 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<(), ()> {
| --- this is not `async`
@ -226,7 +226,7 @@ LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ 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 = || {
| -- 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`
= 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.
For more information about an error, try `rustc --explain E0277`.

View 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() {}

View 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`.

View File

@ -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`.

View File

@ -8,7 +8,7 @@ trait Foo {}
impl Xyz {
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
{
foo

View File

@ -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`
error: cannot infer an appropriate lifetime
--> $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
error: aborting due to previous error
For more information about this error, try `rustc --explain E0106`.

View File

@ -5,6 +5,7 @@
async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
{
Ok(())
//~^ type annotations needed
}
fn main() { }

View File

@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1
LL | async fn copy() -> Result<()>
| ^^^^^^^^^^ 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`.

View File

@ -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> {
//~^ 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)
}

View File

@ -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
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`.

View 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();
}

View File

@ -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

View 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>());
}

View 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

View File

@ -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)]
struct Foo {
i: isize,

View File

@ -1,11 +1,19 @@
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 {
| ---------- method `clone` not found for this
...
LL | let _y = x.clone();
| ^^^^^ 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
= note: the following trait defines an item `clone`, perhaps you need to implement it:

View File

@ -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 {
type X;
fn method(&self) {}

View File

@ -1,5 +1,5 @@
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> {
| ------------------
@ -12,6 +12,14 @@ LL | struct NotClone;
...
LL | Bar::<NotClone> { x: 1 }.clone();
| ^^^^^ 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:
`NotClone: std::clone::Clone`

View File

@ -1,9 +1,17 @@
// edition:2018
// aux-build:edition-kw-macro-2015.rs
#![feature(async_closure)]
fn main() {}
#[macro_use]
extern crate edition_kw_macro_2015;
mod module {
pub fn r#async() {}
}
pub fn check_async() {
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
let mut r#async = 1; // OK
@ -17,4 +25,6 @@ pub fn check_async() {
if passes_ident!(r#async) == 1 {} // OK
module::async(); //~ ERROR expected identifier, found keyword `async`
module::r#async(); // OK
let _recovery_witness: () = 0; //~ ERROR mismatched types
}

View File

@ -1,5 +1,5 @@
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;
| ^^^^^ expected identifier, found keyword
@ -10,7 +10,7 @@ LL | let mut r#async = 1;
| ^^^^^^^
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();
| ^^^^^ expected identifier, found keyword
@ -21,13 +21,13 @@ LL | module::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);
| ^^^^^^^ no rules expected this token in macro call
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);
| ^^^^^ 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)
| ^ 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 {}
| -------------------- 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`.

View File

@ -1,9 +1,17 @@
// edition:2018
// aux-build:edition-kw-macro-2018.rs
#![feature(async_closure)]
fn main() {}
#[macro_use]
extern crate edition_kw_macro_2018;
mod module {
pub fn r#async() {}
}
pub fn check_async() {
let mut async = 1; //~ ERROR expected identifier, found keyword `async`
let mut r#async = 1; // OK
@ -17,4 +25,6 @@ pub fn check_async() {
if passes_ident!(r#async) == 1 {} // OK
module::async(); //~ ERROR expected identifier, found keyword `async`
module::r#async(); // OK
let _recovery_witness: () = 0; //~ ERROR mismatched types
}

View File

@ -1,5 +1,5 @@
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;
| ^^^^^ expected identifier, found keyword
@ -10,7 +10,7 @@ LL | let mut r#async = 1;
| ^^^^^^^
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();
| ^^^^^ expected identifier, found keyword
@ -21,13 +21,13 @@ LL | module::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);
| ^^^^^^^ no rules expected this token in macro call
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);
| ^^^^^ 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)
| ^ 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 {}
| -------------------- 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`.

View File

@ -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() {
let x = Some(1);

View File

@ -1,8 +1,16 @@
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 { }
| ^ 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

View File

@ -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() {
let x = Some(1);
let Some(y) = x; //~ ERROR E0005

View File

@ -1,8 +1,13 @@
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;
| ^^^^^^^ 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: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html

View File

@ -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() {
let xs : Vec<Option<i32>> = vec![Some(1), None];

View File

@ -1,8 +1,13 @@
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 {}
| ^^^^^^^ pattern `None` not covered
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
LL | None,
| ---- not covered
error: aborting due to previous error

View File

@ -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)]
fn foo() -> Result<u32, !> {

View File

@ -1,8 +1,13 @@
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();
| ^^^^^^ 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: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html

View File

@ -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)]
#![feature(generic_associated_types)]

View File

@ -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>`
--> $DIR/iterable.rs:15:5
--> $DIR/iterable.rs:20:5
|
LL | impl<T> Iterable for Vec<T> {
| --------------------------- in this `impl` item
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`
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
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] {
| ------------------------ in this `impl` item
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`
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
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 {
| -------------- 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
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 {
| -------------- required by `Iterable`

View File

@ -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();
| ^^^^^^ 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: the following trait is implemented but not in scope; perhaps add a `use` for it:

View File

@ -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 {
x: isize,
}

View File

@ -1,11 +1,19 @@
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 {
| -------- method `clone` not found for this
...
LL | let _d = c.clone();
| ^^^^^ 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
= note: the following trait defines an item `clone`, perhaps you need to implement it:

View File

@ -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
extern crate issue_69725;

View File

@ -1,5 +1,5 @@
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();
| ^^^^^ method not found in `issue_69725::Struct<A>`
@ -8,6 +8,14 @@ LL | let _ = Struct::<A>::new().clone();
|
LL | pub struct Struct<A>(A);
| ------------------------ 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:
`A: std::clone::Clone`

View File

@ -1,9 +1,10 @@
// Regression test for issue #61033.
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() {
test1!(x,);
let _recovery_witness: () = 0; //~ ERROR mismatched types
}

View File

@ -4,5 +4,14 @@ error: this must repeat at least once
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`.

View File

@ -5,7 +5,9 @@ macro_rules! test2 {
$(* $id1: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
)*
}
@ -16,4 +18,8 @@ fn main() {
* a * b
+ a + b + c
}
test2! {
* a * b
+ a + b + c + d
}
}

View File

@ -3,9 +3,22 @@ error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times
|
LL | $(
| __________^
LL | |
LL | |
LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
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

View File

@ -0,0 +1,8 @@
fn main() {}
macro_rules! ambiguity {
($($i:ident)* $j:ident) => {};
}
ambiguity!(error); //~ ERROR local ambiguity
ambiguity!(error); //~ ERROR local ambiguity

View File

@ -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

View File

@ -4,6 +4,8 @@ macro_rules! m {
//~| ERROR macro expansion ignores token `typeof`
//~| 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() {

View File

@ -42,5 +42,29 @@ LL | m!();
|
= 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`.

View File

@ -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() {
test!()

View File

@ -1,8 +1,18 @@
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

View File

@ -1,6 +1,6 @@
// compile-flags: -Z trace-macros
#![recursion_limit="4"]
#![recursion_limit = "4"]
macro_rules! my_faulty_macro {
() => {
@ -24,9 +24,7 @@ macro_rules! my_recursive_macro {
}
macro_rules! my_macro {
() => {
};
() => {};
}
fn main() {
@ -39,7 +37,7 @@ fn main() {
}
#[my_macro]
fn use_bang_macro_as_attr(){}
fn use_bang_macro_as_attr() {}
#[derive(Debug)]
fn use_derive_macro_as_attr(){}
#[derive(Debug)] //~ ERROR `derive` may only be applied to structs
fn use_derive_macro_as_attr() {}

View File

@ -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: trace_macro
--> $DIR/trace_faulty_macros.rs:33:5
--> $DIR/trace_faulty_macros.rs:31:5
|
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: trace_macro
--> $DIR/trace_faulty_macros.rs:34:5
--> $DIR/trace_faulty_macros.rs:32:5
|
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)
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

View File

@ -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
#![feature(rustc_private)]

View File

@ -1,8 +1,16 @@
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();
| ^^^^^ 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

View File

@ -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
// copied

View File

@ -1,11 +1,19 @@
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 {
| ---------- method `clone` not found for this
...
LL | let _y = x.clone();
| ^^^^^ 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
= note: the following trait defines an item `clone`, perhaps you need to implement it:

View File

@ -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.
// error-pattern: this file contains an unclosed delimiter
// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`

View File

@ -1,5 +1,5 @@
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!
| - - - unclosed delimiter
@ -11,7 +11,7 @@ LL | fn main() {}
| ^
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!
| - - - unclosed delimiter
@ -23,7 +23,7 @@ LL | fn main() {}
| ^
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!
| - - - unclosed delimiter
@ -35,13 +35,18 @@ LL | fn main() {}
| ^
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!
| - expected one of `(`, `[`, or `{`
LL |
LL | fn main() {}
| ^^ 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

View File

@ -6,3 +6,5 @@ macro_rules! foo {
}
foo!();
fn main() {}

View File

@ -1,9 +1,12 @@
macro_rules! mac {
( $($v:tt)* ) => (
$v //~ ERROR still repeating at this depth
)
( $($v:tt)* ) => {
$v
//~^ ERROR still repeating at this depth
//~| ERROR still repeating at this depth
};
}
fn main() {
mac!(0);
mac!(1);
}

View File

@ -4,5 +4,11 @@ error: variable 'v' is still repeating at this depth
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

View 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
}

View 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`.

View File

@ -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};
#[derive(PartialEq, Eq)]

View File

@ -1,5 +1,5 @@
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) {
| ^^^^^^^^^^^^^ 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
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)) {
| ^^^^^^^^^^^^^^^^^ 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
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 | | bar: Option<Direction>,

View File

@ -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(exhaustive_patterns)]

View File

@ -1,8 +1,13 @@
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 {
| ^^^^^^^^^^^^^ 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

View File

@ -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)]
enum T { A, B }

View File

@ -1,5 +1,5 @@
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 }
| ---------------
@ -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
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 {
| ^^^^ 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
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) {
| ^^^^^^^^ 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
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) {
| ^^^^^^^^^ 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
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) {
| ^^^^^^^^^^^^ 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
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 }
| ---------------
@ -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
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/non-exhaustive-match.rs:33:11
--> $DIR/non-exhaustive-match.rs:38:11
|
LL | match *vec {
| ^^^^ 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
error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
--> $DIR/non-exhaustive-match.rs:46:11
--> $DIR/non-exhaustive-match.rs:51:11
|
LL | match *vec {
| ^^^^ pattern `[_, _, _, _, ..]` not covered

View File

@ -3,11 +3,9 @@
#[macro_use]
extern crate derive_bad;
#[derive(
A
)]
//~^^ ERROR proc-macro derive produced unparseable tokens
#[derive(A)]
//~^ ERROR proc-macro derive produced unparseable tokens
//~| ERROR expected `:`, found `}`
struct A;
struct A; //~ ERROR the name `A` is defined multiple times
fn main() {}

View File

@ -1,16 +1,28 @@
error: expected `:`, found `}`
--> $DIR/derive-bad.rs:7:5
--> $DIR/derive-bad.rs:6:10
|
LL | A
| ^ expected `:`
LL | #[derive(A)]
| ^ expected `:`
|
= 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
--> $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