Auto merge of #127831 - tgross35:rollup-c0j9n7b, r=tgross35

Rollup of 7 pull requests

Successful merges:

 - #124033 (Sync ar_archive_writer to LLVM 18.1.3)
 - #126699 (Delegation: support coercion for target expression)
 - #126762 (Deny keyword lifetimes pre-expansion)
 - #126967 (Promote the `wasm32-wasip2` target to Tier 2)
 - #127390 (Migrate `raw-dylib-inline-cross-dylib` and `raw-dylib-custom-dlltool` `run-make` tests to rmake)
 - #127501 (Invert infer `error_reporting` mod struture)
 - #127816 (Update method name to reflect changes to its internals)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-16 21:46:24 +00:00
commit 7d356ebde3
87 changed files with 1433 additions and 342 deletions

View File

@ -236,11 +236,11 @@ checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
[[package]]
name = "ar_archive_writer"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
checksum = "f8412a2d690663356cba5a2532f3ed55d1e8090743bc6695b88403b27df67733"
dependencies = [
"object 0.32.2",
"object 0.35.0",
]
[[package]]
@ -1682,6 +1682,7 @@ dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
"serde",
]
[[package]]
@ -1891,6 +1892,12 @@ dependencies = [
"syn 2.0.67",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "ident_case"
version = "1.0.1"
@ -2120,6 +2127,12 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
[[package]]
name = "lexopt"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
[[package]]
name = "libc"
version = "0.2.155"
@ -2634,7 +2647,7 @@ dependencies = [
"indexmap",
"memchr",
"ruzstd 0.5.0",
"wasmparser",
"wasmparser 0.118.2",
]
[[package]]
@ -2648,6 +2661,15 @@ dependencies = [
"ruzstd 0.6.0",
]
[[package]]
name = "object"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.36.0"
@ -3436,7 +3458,7 @@ dependencies = [
"object 0.34.0",
"regex",
"similar",
"wasmparser",
"wasmparser 0.118.2",
]
[[package]]
@ -3823,7 +3845,7 @@ dependencies = [
"thin-vec",
"thorin-dwp",
"tracing",
"wasm-encoder",
"wasm-encoder 0.200.0",
"windows",
]
@ -5267,6 +5289,15 @@ dependencies = [
"color-eyre",
]
[[package]]
name = "spdx"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc"
dependencies = [
"smallvec",
]
[[package]]
name = "spdx-expression"
version = "0.5.2"
@ -6315,6 +6346,28 @@ version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "wasm-component-ld"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "314d932d5e84c9678751b85498b1482b2f32f185744e449d3ce0b1d400376dad"
dependencies = [
"anyhow",
"clap",
"lexopt",
"tempfile",
"wasmparser 0.210.0",
"wat",
"wit-component",
]
[[package]]
name = "wasm-component-ld-wrapper"
version = "0.1.0"
dependencies = [
"wasm-component-ld",
]
[[package]]
name = "wasm-encoder"
version = "0.200.0"
@ -6324,6 +6377,40 @@ dependencies = [
"leb128",
]
[[package]]
name = "wasm-encoder"
version = "0.210.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e3764d9d6edabd8c9e16195e177be0d20f6ab942ad18af52860f12f82bc59a"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-encoder"
version = "0.211.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e7d931a1120ef357f32b74547646b6fa68ea25e377772b72874b131a9ed70d4"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.210.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "012729d1294907fcb0866f08460ab95426a6d0b176a599619b84cac7653452b4"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_derive",
"serde_json",
"spdx",
"wasm-encoder 0.210.0",
"wasmparser 0.210.0",
]
[[package]]
name = "wasmparser"
version = "0.118.2"
@ -6334,6 +6421,42 @@ dependencies = [
"semver",
]
[[package]]
name = "wasmparser"
version = "0.210.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7bbcd21e7581619d9f6ca00f8c4f08f1cacfe58bf63f83af57cd0476f1026f5"
dependencies = [
"ahash",
"bitflags 2.5.0",
"hashbrown",
"indexmap",
"semver",
"serde",
]
[[package]]
name = "wast"
version = "211.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b25506dd82d00da6b14a87436b3d52b1d264083fa79cdb72a0d1b04a8595ccaa"
dependencies = [
"bumpalo",
"leb128",
"memchr",
"unicode-width",
"wasm-encoder 0.211.1",
]
[[package]]
name = "wat"
version = "1.211.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb716ca6c86eecac2d82541ffc39860118fc0af9309c4f2670637bea2e1bdd7d"
dependencies = [
"wast",
]
[[package]]
name = "winapi"
version = "0.3.9"
@ -6561,6 +6684,43 @@ dependencies = [
"memchr",
]
[[package]]
name = "wit-component"
version = "0.210.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a450bdb5d032acf1fa0865451fa0c6f50e62f2d31eaa8dba967c2e2d068694a4"
dependencies = [
"anyhow",
"bitflags 2.5.0",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder 0.210.0",
"wasm-metadata",
"wasmparser 0.210.0",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.210.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a965cbd439af19a4b44a54a97ab8957d86f02d01320efc9e31c1d3605c6710"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser 0.210.0",
]
[[package]]
name = "writeable"
version = "0.5.5"

View File

@ -45,6 +45,7 @@ members = [
"src/tools/opt-dist",
"src/tools/coverage-dump",
"src/tools/rustc-perf-wrapper",
"src/tools/wasm-component-ld",
]
exclude = [
@ -104,6 +105,9 @@ rustc-demangle.debug = 0
[profile.release.package.lld-wrapper]
debug = 0
strip = true
[profile.release.package.wasm-component-ld-wrapper]
debug = 0
strip = true
[patch.crates-io]
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on

View File

@ -38,7 +38,7 @@
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
use super::{ImplTraitContext, LoweringContext, ParamMode};
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
use ast::visit::Visitor;
use hir::def::{DefKind, PartialRes, Res};
@ -259,8 +259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self_param_id: pat_node_id,
};
self_resolver.visit_block(block);
let block = this.lower_block(block, false);
this.mk_expr(hir::ExprKind::Block(block, None), block.span)
this.lower_target_expr(&block)
} else {
let pat_hir_id = this.lower_node_id(pat_node_id);
this.generate_arg(pat_hir_id, span)
@ -273,13 +272,69 @@ impl<'hir> LoweringContext<'_, 'hir> {
})
}
// Generates fully qualified call for the resulting body.
// FIXME(fn_delegation): Alternatives for target expression lowering:
// https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600.
fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> {
if block.stmts.len() == 1
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
{
return self.lower_expr_mut(expr);
}
let block = self.lower_block(block, false);
self.mk_expr(hir::ExprKind::Block(block, None), block.span)
}
// Generates expression for the resulting body. If possible, `MethodCall` is used
// to allow autoref/autoderef for target expression. For example in:
//
// trait Trait : Sized {
// fn by_value(self) -> i32 { 1 }
// fn by_mut_ref(&mut self) -> i32 { 2 }
// fn by_ref(&self) -> i32 { 3 }
// }
//
// struct NewType(SomeType);
// impl Trait for NewType {
// reuse Trait::* { self.0 }
// }
//
// `self.0` will automatically coerce.
fn finalize_body_lowering(
&mut self,
delegation: &Delegation,
args: Vec<hir::Expr<'hir>>,
span: Span,
) -> hir::Expr<'hir> {
let args = self.arena.alloc_from_iter(args);
let has_generic_args =
delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some());
let call = if self
.get_resolution_id(delegation.id, span)
.and_then(|def_id| Ok(self.has_self(def_id, span)))
.unwrap_or_default()
&& delegation.qself.is_none()
&& !has_generic_args
{
let ast_segment = delegation.path.segments.last().unwrap();
let segment = self.lower_path_segment(
delegation.path.span,
ast_segment,
ParamMode::Optional,
ParenthesizedGenericArgs::Err,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
let segment = self.arena.alloc(segment);
self.arena.alloc(hir::Expr {
hir_id: self.next_id(),
kind: hir::ExprKind::MethodCall(segment, &args[0], &args[1..], span),
span,
})
} else {
let path = self.lower_qpath(
delegation.id,
&delegation.qself,
@ -289,10 +344,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
None,
);
let args = self.arena.alloc_from_iter(args);
let path_expr = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span));
let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(path_expr, args), span));
let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span));
self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span))
};
let block = self.arena.alloc(hir::Block {
stmts: &[],
expr: Some(call),

View File

@ -159,9 +159,6 @@ ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
.type = inherent impl for this type
.only_trait = only trait implementations may be annotated with {$annotation}
ast_passes_invalid_label =
invalid label name `{$name}`
ast_passes_invalid_unnamed_field =
unnamed fields are not allowed outside of structs or unions
.label = unnamed field declared here
@ -176,9 +173,6 @@ ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot
ast_passes_item_underscore = `{$kind}` items in this context need a name
.label = `_` is not a valid name for this `{$kind}` item
ast_passes_keyword_lifetime =
lifetimes cannot use keyword names
ast_passes_match_arm_with_no_body =
`match` arm with no body
.suggestion = add a body after the pattern

View File

@ -269,19 +269,6 @@ impl<'a> AstValidator<'a> {
self.session.dcx()
}
fn check_lifetime(&self, ident: Ident) {
let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
}
}
fn check_label(&self, ident: Ident) {
if ident.without_first_quote().is_reserved() {
self.dcx().emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
}
}
fn visibility_not_permitted(&self, vis: &Visibility, note: errors::VisibilityNotPermittedNote) {
if let VisibilityKind::Inherited = vis.kind {
return;
@ -908,16 +895,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.walk_ty(ty)
}
fn visit_label(&mut self, label: &'a Label) {
self.check_label(label.ident);
visit::walk_label(self, label);
}
fn visit_lifetime(&mut self, lifetime: &'a Lifetime, _: visit::LifetimeCtxt) {
self.check_lifetime(lifetime.ident);
visit::walk_lifetime(self, lifetime);
}
fn visit_field_def(&mut self, field: &'a FieldDef) {
self.deny_unnamed_field(field);
visit::walk_field_def(self, field)
@ -1356,13 +1333,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
fn visit_generic_param(&mut self, param: &'a GenericParam) {
if let GenericParamKind::Lifetime { .. } = param.kind {
self.check_lifetime(param.ident);
}
visit::walk_generic_param(self, param);
}
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
match bound {
GenericBound::Trait(trait_ref, modifiers) => {

View File

@ -9,21 +9,6 @@ use rustc_span::{symbol::Ident, Span, Symbol};
use crate::fluent_generated as fluent;
#[derive(Diagnostic)]
#[diag(ast_passes_keyword_lifetime)]
pub struct KeywordLifetime {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_passes_invalid_label)]
pub struct InvalidLabel {
#[primary_span]
pub span: Span,
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(ast_passes_visibility_not_permitted, code = E0449)]
pub struct VisibilityNotPermitted {

View File

@ -1,7 +1,7 @@
use rustc_errors::Diag;
use rustc_hir::def_id::LocalDefId;
use rustc_infer::error_reporting::infer::nice_region_error::NiceRegionError;
use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_infer::infer::region_constraints::Constraint;
use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::RegionVariableOrigin;

View File

@ -10,11 +10,11 @@ use rustc_hir::GenericBound::Trait;
use rustc_hir::QPath::Resolved;
use rustc_hir::WherePredicate::BoundPredicate;
use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
use rustc_infer::infer::error_reporting::nice_region_error::{
use rustc_infer::error_reporting::infer::nice_region_error::{
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor,
};
use rustc_infer::infer::error_reporting::region::unexpected_hidden_region_diagnostic;
use rustc_infer::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
use rustc_middle::bug;
use rustc_middle::hir::place::PlaceBase;

View File

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
use rustc_codegen_ssa::back::archive::{
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
};
use rustc_session::Session;
@ -9,7 +9,7 @@ pub(crate) struct ArArchiveBuilderBuilder;
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
}
fn create_dll_import_lib(

View File

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
use rustc_codegen_ssa::back::archive::{
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
};
use rustc_session::Session;
@ -11,7 +11,7 @@ pub(crate) struct ArArchiveBuilderBuilder;
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
}
fn create_dll_import_lib(

View File

@ -15,8 +15,8 @@ use crate::errors::{
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use rustc_codegen_ssa::back::archive::{
get_native_object_symbols, try_extract_macho_fat_archive, ArArchiveBuilder,
ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, UnknownArchiveKind,
try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
};
use tracing::trace;
@ -115,7 +115,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
if true {
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
} else {
Box::new(ArArchiveBuilder::new(sess, get_llvm_object_symbols))
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
}
}
@ -291,18 +291,33 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
// As such we need to use LLVM for them.
#[deny(unsafe_op_in_unsafe_fn)]
fn get_llvm_object_symbols(
buf: &[u8],
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
) -> io::Result<bool> {
static LLVM_OBJECT_READER: ObjectReader = ObjectReader {
get_symbols: get_llvm_object_symbols,
is_64_bit_object_file: llvm_is_64_bit_object_file,
is_ec_object_file: llvm_is_ec_object_file,
get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
};
fn should_use_llvm_reader(buf: &[u8]) -> bool {
let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
// COFF bigobj file, msvc LTO file or import library. See
// https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
if is_bitcode || is_unsupported_windows_obj_file {
is_bitcode || is_unsupported_windows_obj_file
}
#[deny(unsafe_op_in_unsafe_fn)]
fn get_llvm_object_symbols(
buf: &[u8],
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
) -> io::Result<bool> {
if !should_use_llvm_reader(buf) {
return (DEFAULT_OBJECT_READER.get_symbols)(buf, f);
}
let mut state = Box::new(f);
let err = unsafe {
@ -321,10 +336,7 @@ fn get_llvm_object_symbols(
return Err(unsafe { *Box::from_raw(err as *mut io::Error) });
}
unsafe extern "C" fn callback(
state: *mut c_void,
symbol_name: *const c_char,
) -> *mut c_void {
unsafe extern "C" fn callback(state: *mut c_void, symbol_name: *const c_char) -> *mut c_void {
let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
Ok(()) => std::ptr::null_mut(),
@ -339,9 +351,22 @@ fn get_llvm_object_symbols(
format!("LLVM error: {}", error.to_string_lossy()),
))) as *mut c_void
}
} else {
get_native_object_symbols(buf, f)
}
fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
if !should_use_llvm_reader(buf) {
return (DEFAULT_OBJECT_READER.is_64_bit_object_file)(buf);
}
unsafe { llvm::LLVMRustIs64BitSymbolicFile(buf.as_ptr(), buf.len()) }
}
fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
if !should_use_llvm_reader(buf) {
return (DEFAULT_OBJECT_READER.is_ec_object_file)(buf);
}
unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
}
impl<'a> LlvmArchiveBuilder<'a> {

View File

@ -2440,4 +2440,8 @@ extern "C" {
callback: GetSymbolsCallback,
error_callback: GetSymbolsErrorCallback,
) -> *mut c_void;
pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
}

View File

@ -5,7 +5,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
ar_archive_writer = "0.2.0"
ar_archive_writer = "0.3.0"
arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
cc = "1.0.90"

View File

@ -6,8 +6,8 @@ use rustc_span::symbol::Symbol;
use super::metadata::search_for_section;
pub use ar_archive_writer::get_native_object_symbols;
use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
pub use ar_archive_writer::{ObjectReader, DEFAULT_OBJECT_READER};
use object::read::archive::ArchiveFile;
use object::read::macho::FatArch;
use tempfile::Builder as TempFileBuilder;
@ -89,8 +89,7 @@ pub trait ArchiveBuilder {
#[must_use = "must call build() to finish building the archive"]
pub struct ArArchiveBuilder<'a> {
sess: &'a Session,
get_object_symbols:
fn(buf: &[u8], f: &mut dyn FnMut(&[u8]) -> io::Result<()>) -> io::Result<bool>,
object_reader: &'static ObjectReader,
src_archives: Vec<(PathBuf, Mmap)>,
// Don't use an `HashMap` here, as the order is important. `lib.rmeta` needs
@ -105,14 +104,8 @@ enum ArchiveEntry {
}
impl<'a> ArArchiveBuilder<'a> {
pub fn new(
sess: &'a Session,
get_object_symbols: fn(
buf: &[u8],
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
) -> io::Result<bool>,
) -> ArArchiveBuilder<'a> {
ArArchiveBuilder { sess, get_object_symbols, src_archives: vec![], entries: vec![] }
pub fn new(sess: &'a Session, object_reader: &'static ObjectReader) -> ArArchiveBuilder<'a> {
ArArchiveBuilder { sess, object_reader, src_archives: vec![], entries: vec![] }
}
}
@ -267,7 +260,7 @@ impl<'a> ArArchiveBuilder<'a> {
entries.push(NewArchiveMember {
buf: data,
get_symbols: self.get_object_symbols,
object_reader: self.object_reader,
member_name: String::from_utf8(entry_name).unwrap(),
mtime: 0,
uid: 0,
@ -294,7 +287,13 @@ impl<'a> ArArchiveBuilder<'a> {
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
.map_err(|err| io_error_context("couldn't create the temp file", err))?;
write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
write_archive_to_stream(
&mut archive_tmpfile,
&entries,
archive_kind,
false,
/* is_ec = */ self.sess.target.arch == "arm64ec",
)?;
let any_entries = !entries.is_empty();
drop(entries);

View File

@ -82,7 +82,7 @@ use rustc_errors::{pluralize, struct_span_code_err, Diag};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
use rustc_infer::error_reporting::infer::ObligationCauseExt as _;
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, TyCtxtInferExt as _};
use rustc_infer::traits::ObligationCause;

View File

@ -19,7 +19,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
};
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
@ -1519,7 +1519,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
let e = self.tainted_by_errors().unwrap_or_else(|| {
self.err_ctxt()
.emit_inference_failure_err(self.body_id, sp, ty.into(), E0282, true)
.emit_inference_failure_err(
self.body_id,
sp,
ty.into(),
TypeAnnotationNeeded::E0282,
true,
)
.emit()
});
let err = Ty::new_error(self.tcx, e);

View File

@ -29,7 +29,7 @@ use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
use rustc_hir_analysis::check::potentially_plural_count;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_index::IndexVec;
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
use rustc_infer::error_reporting::infer::{FailureCode, ObligationCauseExt};
use rustc_infer::infer::TypeTrace;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::ty::adjustment::AllowTwoPhase;

View File

@ -15,9 +15,9 @@ use hir::def_id::CRATE_DEF_ID;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
use rustc_infer::error_reporting::infer::sub_relations::SubRelations;
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::infer;
use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::Session;
use rustc_span::symbol::Ident;

View File

@ -182,8 +182,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_expr: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
let pick =
self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
let scope = if let Some(only_method) = segment.res.opt_def_id() {
ProbeScope::Single(only_method)
} else {
ProbeScope::TraitsInScope
};
let pick = self.lookup_probe(segment.ident, self_ty, call_expr, scope)?;
self.lint_edition_dependent_dot_call(
self_ty, segment, span, call_expr, self_expr, &pick, args,

View File

@ -12,7 +12,7 @@ use rustc_hir::HirId;
use rustc_hir_analysis::autoderef::{self, Autoderef};
use rustc_infer::infer::canonical::OriginalQueryValues;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_infer::traits::ObligationCauseCode;
@ -20,6 +20,7 @@ use rustc_middle::middle::stability;
use rustc_middle::query::Providers;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::AssocItem;
use rustc_middle::ty::AssocItemContainer;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::Upcast;
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
@ -216,6 +217,9 @@ pub enum Mode {
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum ProbeScope {
// Single candidate coming from pre-resolved delegation method.
Single(DefId),
// Assemble candidates coming only from traits in scope.
TraitsInScope,
@ -441,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.body_id,
span,
ty.into(),
E0282,
TypeAnnotationNeeded::E0282,
!raw_ptr_call,
);
if raw_ptr_call {
@ -480,12 +484,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
is_suggestion,
);
probe_cx.assemble_inherent_candidates();
match scope {
ProbeScope::TraitsInScope => {
probe_cx.assemble_extension_candidates_for_traits_in_scope()
probe_cx.assemble_inherent_candidates();
probe_cx.assemble_extension_candidates_for_traits_in_scope();
}
ProbeScope::AllTraits => {
probe_cx.assemble_inherent_candidates();
probe_cx.assemble_extension_candidates_for_all_traits();
}
ProbeScope::Single(def_id) => {
let item = self.tcx.associated_item(def_id);
// FIXME(fn_delegation): Delegation to inherent methods is not yet supported.
assert_eq!(item.container, AssocItemContainer::TraitContainer);
let trait_def_id = self.tcx.parent(def_id);
let trait_span = self.tcx.def_span(trait_def_id);
let trait_args = self.fresh_args_for_item(trait_span, trait_def_id);
let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args);
probe_cx.push_candidate(
Candidate {
item,
kind: CandidateKind::TraitCandidate(ty::Binder::dummy(trait_ref)),
import_ids: smallvec![],
},
false,
);
}
ProbeScope::AllTraits => probe_cx.assemble_extension_candidates_for_all_traits(),
};
op(probe_cx)
})

View File

@ -8,7 +8,7 @@ use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::HirId;
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
use rustc_middle::span_bug;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@ -783,7 +783,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
self.fcx.tcx.hir().body_owner_def_id(self.body.id()),
self.span.to_span(self.fcx.tcx),
p.into(),
E0282,
TypeAnnotationNeeded::E0282,
false,
)
.emit()

View File

@ -45,17 +45,11 @@
//! ported to this system, and which relies on string concatenation at the
//! time of error detection.
use super::{InferCtxt, TypeTrace, ValuePairs};
use std::borrow::Cow;
use std::ops::{ControlFlow, Deref};
use std::path::PathBuf;
use std::{cmp, fmt, iter};
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
use crate::infer;
use crate::infer::ExpectedFound;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
PredicateObligation,
};
use crate::infer::relate::{self, RelateResult, TypeRelation};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{
pluralize, Applicability, Diag, DiagCtxtHandle, DiagStyledString, IntoDiagArg, StringPart,
@ -68,6 +62,7 @@ use rustc_hir::{self as hir};
use rustc_macros::extension;
use rustc_middle::bug;
use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
use rustc_middle::ty::{
@ -76,18 +71,21 @@ use rustc_middle::ty::{
};
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi;
use std::borrow::Cow;
use std::ops::{ControlFlow, Deref};
use std::path::PathBuf;
use std::{cmp, fmt, iter};
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
use crate::infer;
use crate::infer::relate::{self, RelateResult, TypeRelation};
use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
PredicateObligation,
};
mod note_and_explain;
mod suggest;
pub(crate) mod need_type_info;
pub mod sub_relations;
pub use need_type_info::TypeAnnotationNeeded;
pub mod region;
pub mod sub_relations;
pub mod nice_region_error;
@ -1242,7 +1240,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
Some(values) => {
let values = self.resolve_vars_if_possible(values);
let (is_simple_error, exp_found) = match values {
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
ValuePairs::Terms(ExpectedFound { expected, found }) => {
match (expected.unpack(), found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
let is_simple_err = expected.is_simple_text(self.tcx)
@ -1254,7 +1252,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
(
is_simple_err,
Mismatch::Variable(infer::ExpectedFound { expected, found }),
Mismatch::Variable(ExpectedFound { expected, found }),
)
}
(ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
@ -1263,13 +1261,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
_ => (false, Mismatch::Fixed("type")),
}
}
ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
ValuePairs::PolySigs(ExpectedFound { expected, found }) => {
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
.report(diag);
(false, Mismatch::Fixed("signature"))
}
ValuePairs::TraitRefs(_) => (false, Mismatch::Fixed("trait")),
ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
ValuePairs::Aliases(ExpectedFound { expected, .. }) => {
(false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
}
ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
@ -1303,9 +1301,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
if let Some((sp, msg)) = secondary_span {
if swap_secondary_and_primary {
let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
expected,
..
let terr = if let Some(infer::ValuePairs::Terms(ExpectedFound {
expected, ..
})) = values
{
Cow::from(format!("expected this to be `{expected}`"))

View File

@ -1,21 +1,20 @@
//! Error Reporting for Anonymous Region Lifetime Errors
//! where both the regions are anonymous.
use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
use crate::error_reporting::infer::nice_region_error::util::AnonymousParamInfo;
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::AddLifetimeParamsSuggestion;
use crate::errors::LifetimeMismatch;
use crate::errors::LifetimeMismatchLabels;
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::RegionResolutionError;
use crate::infer::SubregionOrigin;
use crate::infer::TyCtxt;
use rustc_errors::Subdiagnostic;
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::Ty;
use rustc_middle::ty::Region;
use rustc_middle::ty::{Region, TyCtxt};
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when both the concerned regions are anonymous.

View File

@ -1,12 +1,12 @@
//! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
//! to hold.
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
use crate::errors::{
DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::ObligationCauseCode;
use rustc_data_structures::fx::FxIndexSet;

View File

@ -1,6 +1,6 @@
use crate::infer::error_reporting::TypeErrCtxt;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::lexical_region_resolve::RegionResolutionError::*;
use crate::error_reporting::infer::TypeErrCtxt;
use crate::infer::RegionResolutionError;
use crate::infer::RegionResolutionError::*;
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, TyCtxt};

View File

@ -1,11 +1,9 @@
//! Error Reporting for Anonymous Region Lifetime Errors
//! where one region is named and the other is anonymous.
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::{
errors::ExplicitLifetimeRequired,
infer::error_reporting::nice_region_error::find_anon_type::find_anon_type,
};
use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::ExplicitLifetimeRequired;
use rustc_errors::Diag;
use rustc_middle::ty;
use rustc_span::symbol::kw;

View File

@ -1,9 +1,9 @@
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::{
ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
TraitPlaceholderMismatch, TyOrSig,
};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::RegionResolutionError;
use crate::infer::ValuePairs;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode};

View File

@ -1,9 +1,6 @@
use crate::{
errors::PlaceholderRelationLfNotSatisfied,
infer::{
error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin,
},
};
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::PlaceholderRelationLfNotSatisfied;
use crate::infer::{RegionResolutionError, SubregionOrigin};
use rustc_data_structures::intern::Interned;
use rustc_errors::Diag;
use rustc_middle::ty::{self, RePlaceholder, Region};

View File

@ -1,11 +1,11 @@
//! Error Reporting for static impl Traits.
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::{
ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted,
ReqIntroducedLocations,
};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_data_structures::fx::FxIndexSet;

View File

@ -1,8 +1,8 @@
//! Error Reporting for `impl` items that do not match the obligations from their `trait`.
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::RegionResolutionError;
use crate::infer::{Subtype, ValuePairs};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;

View File

@ -1,13 +1,13 @@
//! Helper functions corresponding to lifetime errors due to
//! anonymous regions.
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::TyCtxt;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, Binder, Region, Ty, TypeFoldable};
use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable};
use rustc_span::Span;
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
/// Information about the anonymous region we are searching for.
#[derive(Debug)]
pub struct AnonymousParamInfo<'tcx> {

View File

@ -0,0 +1,421 @@
use crate::error_reporting::infer::{note_and_explain_region, TypeErrCtxt};
use crate::errors::{
note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
};
use crate::fluent_generated as fluent;
use crate::infer::{self, SubregionOrigin};
use rustc_errors::{Diag, Subdiagnostic};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
use rustc_span::symbol::kw;
use super::ObligationCauseAsDiagArg;
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
match *origin {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
span: trace.cause.span,
requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
}
.add_to_diag(err),
infer::Reborrow(span) => {
RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
}
infer::RelateObjectBound(span) => {
RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
.add_to_diag(err);
}
infer::ReferenceOutlivesReferent(ty, span) => {
RegionOriginNote::WithName {
span,
msg: fluent::infer_reference_outlives_referent,
name: &self.ty_to_string(ty),
continues: false,
}
.add_to_diag(err);
}
infer::RelateParamBound(span, ty, opt_span) => {
RegionOriginNote::WithName {
span,
msg: fluent::infer_relate_param_bound,
name: &self.ty_to_string(ty),
continues: opt_span.is_some(),
}
.add_to_diag(err);
if let Some(span) = opt_span {
RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
.add_to_diag(err);
}
}
infer::RelateRegionParamBound(span) => {
RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
.add_to_diag(err);
}
infer::CompareImplItemObligation { span, .. } => {
RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
.add_to_diag(err);
}
infer::CheckAssociatedTypeBounds { ref parent, .. } => {
self.note_region_origin(err, parent);
}
infer::AscribeUserTypeProvePredicate(span) => {
RegionOriginNote::Plain {
span,
msg: fluent::infer_ascribe_user_type_prove_predicate,
}
.add_to_diag(err);
}
}
}
pub(super) fn report_concrete_failure(
&self,
generic_param_scope: LocalDefId,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
sup: Region<'tcx>,
) -> Diag<'a> {
let mut err = match origin {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, terr);
match (*sub, *sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
note_and_explain_region(
self.tcx,
&mut err,
generic_param_scope,
"",
sup,
" doesn't meet the lifetime requirements",
None,
);
}
(_, ty::RePlaceholder(_)) => {
note_and_explain_region(
self.tcx,
&mut err,
generic_param_scope,
"the required lifetime does not necessarily outlive ",
sub,
"",
None,
);
}
_ => {
note_and_explain_region(
self.tcx,
&mut err,
generic_param_scope,
"",
sup,
"...",
None,
);
note_and_explain_region(
self.tcx,
&mut err,
generic_param_scope,
"...does not necessarily outlive ",
sub,
"",
None,
);
}
}
err
}
infer::Reborrow(span) => {
let reference_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
note_and_explain::PrefixKind::RefValidFor,
note_and_explain::SuffixKind::Continues,
);
let content_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sup,
None,
note_and_explain::PrefixKind::ContentValidFor,
note_and_explain::SuffixKind::Empty,
);
self.dcx().create_err(OutlivesContent {
span,
notes: reference_valid.into_iter().chain(content_valid).collect(),
})
}
infer::RelateObjectBound(span) => {
let object_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
note_and_explain::PrefixKind::TypeObjValidFor,
note_and_explain::SuffixKind::Empty,
);
let pointer_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sup,
None,
note_and_explain::PrefixKind::SourcePointerValidFor,
note_and_explain::SuffixKind::Empty,
);
self.dcx().create_err(OutlivesBound {
span,
notes: object_valid.into_iter().chain(pointer_valid).collect(),
})
}
infer::RelateParamBound(span, ty, opt_span) => {
let prefix = match *sub {
ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
_ => note_and_explain::PrefixKind::TypeOutlive,
};
let suffix = if opt_span.is_some() {
note_and_explain::SuffixKind::ReqByBinding
} else {
note_and_explain::SuffixKind::Empty
};
let note = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
opt_span,
prefix,
suffix,
);
self.dcx().create_err(FulfillReqLifetime {
span,
ty: self.resolve_vars_if_possible(ty),
note,
})
}
infer::RelateRegionParamBound(span) => {
let param_instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sup,
None,
note_and_explain::PrefixKind::LfParamInstantiatedWith,
note_and_explain::SuffixKind::Empty,
);
let param_must_outlive = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
note_and_explain::PrefixKind::LfParamMustOutlive,
note_and_explain::SuffixKind::Empty,
);
self.dcx().create_err(LfBoundNotSatisfied {
span,
notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
})
}
infer::ReferenceOutlivesReferent(ty, span) => {
let pointer_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
note_and_explain::PrefixKind::PointerValidFor,
note_and_explain::SuffixKind::Empty,
);
let data_valid = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sup,
None,
note_and_explain::PrefixKind::DataValidFor,
note_and_explain::SuffixKind::Empty,
);
self.dcx().create_err(RefLongerThanData {
span,
ty: self.resolve_vars_if_possible(ty),
notes: pointer_valid.into_iter().chain(data_valid).collect(),
})
}
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
let mut err = self.infcx.report_extra_impl_obligation(
span,
impl_item_def_id,
trait_item_def_id,
&format!("`{sup}: {sub}`"),
);
// We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id)
&& generics.where_clause_span.contains(span)
{
self.suggest_copy_trait_method_bounds(
trait_item_def_id,
impl_item_def_id,
&mut err,
);
}
err
}
infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
// Don't mention the item name if it's an RPITIT, since that'll just confuse
// folks.
if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
let trait_item_span = self.tcx.def_span(trait_item_def_id);
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
err.span_label(
trait_item_span,
format!("definition of `{item_name}` from trait"),
);
}
self.suggest_copy_trait_method_bounds(
trait_item_def_id,
impl_item_def_id,
&mut err,
);
err
}
infer::AscribeUserTypeProvePredicate(span) => {
let instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sup,
None,
note_and_explain::PrefixKind::LfInstantiatedWith,
note_and_explain::SuffixKind::Empty,
);
let must_outlive = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
note_and_explain::PrefixKind::LfMustOutlive,
note_and_explain::SuffixKind::Empty,
);
self.dcx().create_err(LfBoundNotSatisfied {
span,
notes: instantiated.into_iter().chain(must_outlive).collect(),
})
}
};
if sub.is_error() || sup.is_error() {
err.downgrade_to_delayed_bug();
}
err
}
pub fn suggest_copy_trait_method_bounds(
&self,
trait_item_def_id: DefId,
impl_item_def_id: LocalDefId,
err: &mut Diag<'_>,
) {
// FIXME(compiler-errors): Right now this is only being used for region
// predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
// but right now it's not really very smart when it comes to implicit `Sized`
// predicates and bounds on the trait itself.
let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
else {
return;
};
let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
return;
};
let trait_args = trait_ref
.instantiate_identity()
// Replace the explicit self type with `Self` for better suggestion rendering
.with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
.args;
let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
.rebase_onto(self.tcx, impl_def_id, trait_args);
let Ok(trait_predicates) =
self.tcx
.explicit_predicates_of(trait_item_def_id)
.instantiate_own(self.tcx, trait_item_args)
.map(|(pred, _)| {
if pred.is_suggestable(self.tcx, false) {
Ok(pred.to_string())
} else {
Err(())
}
})
.collect::<Result<Vec<_>, ()>>()
else {
return;
};
let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else {
return;
};
let suggestion = if trait_predicates.is_empty() {
WhereClauseSuggestions::Remove { span: generics.where_clause_span }
} else {
let space = if generics.where_clause_span.is_empty() { " " } else { "" };
WhereClauseSuggestions::CopyPredicates {
span: generics.where_clause_span,
space,
trait_predicates: trait_predicates.join(", "),
}
};
err.subdiagnostic(suggestion);
}
pub(super) fn report_placeholder_failure(
&self,
generic_param_scope: LocalDefId,
placeholder_origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
sup: Region<'tcx>,
) -> Diag<'a> {
// I can't think how to do better than this right now. -nikomatsakis
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
match placeholder_origin {
infer::Subtype(box ref trace)
if matches!(
&trace.cause.code().peel_derives(),
ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::WhereClauseInExpr(..)
) =>
{
// Hack to get around the borrow checker because trace.cause has an `Rc`.
if let ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
&trace.cause.code().peel_derives()
&& !span.is_dummy()
{
let span = *span;
self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
.with_span_note(span, "the lifetime requirement is introduced here")
} else {
unreachable!(
"control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
)
}
}
infer::Subtype(box trace) => {
let terr = TypeError::RegionsPlaceholderMismatch;
return self.report_and_explain_type_error(trace, terr);
}
_ => {
return self.report_concrete_failure(
generic_param_scope,
placeholder_origin,
sub,
sup,
);
}
}
}
}

View File

@ -18,12 +18,12 @@ use rustc_type_ir::Upcast as _;
use super::nice_region_error::find_anon_type;
use super::{nice_region_error, ObligationCauseAsDiagArg};
use crate::error_reporting::infer::{ObligationCauseExt as _, TypeErrCtxt};
use crate::errors::{
self, note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound,
OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
};
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{ObligationCauseExt as _, TypeErrCtxt};
use crate::infer::region_constraints::GenericKind;
use crate::infer::{self, InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin};

View File

@ -1,4 +1,4 @@
use crate::infer::error_reporting::hir::Path;
use crate::error_reporting::infer::hir::Path;
use core::ops::ControlFlow;
use hir::def::CtorKind;
use hir::intravisit::{walk_expr, walk_stmt, Visitor};

View File

@ -0,0 +1 @@
pub mod infer;

View File

@ -15,11 +15,10 @@ use rustc_span::symbol::kw;
use rustc_span::Symbol;
use rustc_span::{symbol::Ident, BytePos, Span};
use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted;
use crate::error_reporting::infer::ObligationCauseAsDiagArg;
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{
need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
ObligationCauseAsDiagArg,
};
use crate::infer::need_type_info::UnderspecifiedArgKind;
use std::path::PathBuf;

View File

@ -1,5 +1,5 @@
use crate::error_reporting::infer::nice_region_error::find_anon_type;
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::nice_region_error::find_anon_type;
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::bug;

View File

@ -11,9 +11,9 @@ pub use BoundRegionConversionTime::*;
pub use RegionVariableOrigin::*;
pub use SubregionOrigin::*;
use crate::error_reporting::infer::TypeErrCtxt;
use crate::infer::relate::RelateResult;
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
use error_reporting::TypeErrCtxt;
use free_regions::RegionRelations;
use lexical_region_resolve::LexicalRegionResolutions;
use opaque_types::OpaqueTypeStorage;
@ -54,7 +54,6 @@ use type_variable::TypeVariableOrigin;
pub mod at;
pub mod canonical;
mod context;
pub mod error_reporting;
pub mod free_regions;
mod freshen;
mod lexical_region_resolve;
@ -66,6 +65,8 @@ pub mod relate;
pub mod resolve;
pub(crate) mod snapshot;
pub mod type_variable;
// FIXME(error_reporting): Where should we put this?
pub mod need_type_info;
#[must_use]
#[derive(Debug)]

View File

@ -1,8 +1,8 @@
use crate::error_reporting::infer::TypeErrCtxt;
use crate::errors::{
AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
SourceKindMultiSuggestion, SourceKindSubdiag,
};
use crate::infer::error_reporting::TypeErrCtxt;
use crate::infer::InferCtxt;
use rustc_errors::{codes::*, Diag, IntoDiagArg};
use rustc_hir as hir;

View File

@ -34,6 +34,7 @@
#[macro_use]
extern crate tracing;
pub mod error_reporting;
mod errors;
pub mod infer;
pub mod traits;

View File

@ -4,12 +4,16 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Derived from:
// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h
// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp
// * https://github.com/llvm/llvm-project/blob/ef6d1ec07c693352c4a60dd58db08d2d8558f6ea/llvm/include/llvm/Object/ArchiveWriter.h
// * https://github.com/llvm/llvm-project/blob/ef6d1ec07c693352c4a60dd58db08d2d8558f6ea/llvm/lib/Object/ArchiveWriter.cpp
#include "LLVMWrapper.h"
#include "SuppressLLVMWarnings.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include <llvm/Support/raw_ostream.h>
@ -34,6 +38,27 @@ static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *);
typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *);
// This function is copied from ArchiveWriter.cpp.
static Expected<std::unique_ptr<SymbolicFile>>
getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context) {
const file_magic Type = identify_magic(Buf.getBuffer());
// Don't attempt to read non-symbolic file types.
if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
return nullptr;
if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf, file_magic::bitcode, &Context);
if (!ObjOrErr)
return ObjOrErr.takeError();
return std::move(*ObjOrErr);
} else {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf);
if (!ObjOrErr)
return ObjOrErr.takeError();
return std::move(*ObjOrErr);
}
}
// Note: This is implemented in C++ instead of using the C api from Rust as
// IRObjectFile doesn't implement getSymbolName, only printSymbolName, which is
// inaccessible from the C api.
@ -49,16 +74,8 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
// In the scenario when LLVMContext is populated SymbolicFile will contain a
// reference to it, thus SymbolicFile should be destroyed first.
LLVMContext Context;
std::unique_ptr<object::SymbolicFile> Obj;
const file_magic Type = identify_magic(Buf->getBuffer());
if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) {
return 0;
}
if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf->getMemBufferRef(), file_magic::bitcode, &Context);
Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
getSymbolicFile(Buf->getMemBufferRef(), Context);
if (!ObjOrErr) {
Error E = ObjOrErr.takeError();
SmallString<0> ErrorBuf;
@ -66,19 +83,7 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
Error << E << '\0';
return ErrorCallback(Error.str().data());
}
Obj = std::move(*ObjOrErr);
} else {
auto ObjOrErr =
object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef());
if (!ObjOrErr) {
Error E = ObjOrErr.takeError();
SmallString<0> ErrorBuf;
auto Error = raw_svector_ostream(ErrorBuf);
Error << E << '\0';
return ErrorCallback(Error.str().data());
}
Obj = std::move(*ObjOrErr);
}
std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
for (const object::BasicSymbolRef &S : Obj->symbols()) {
if (!isArchiveSymbol(S))
@ -97,3 +102,72 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
}
return 0;
}
// Encoding true and false as invalid pointer values
#define TRUE_PTR (void *)1
#define FALSE_PTR (void *)0
extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) {
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
SmallString<0> SymNameBuf;
auto SymName = raw_svector_ostream(SymNameBuf);
// Code starting from this line is copied from s64BitSymbolicFile in
// ArchiveWriter.cpp.
// In the scenario when LLVMContext is populated SymbolicFile will contain a
// reference to it, thus SymbolicFile should be destroyed first.
LLVMContext Context;
Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
getSymbolicFile(Buf->getMemBufferRef(), Context);
if (!ObjOrErr) {
return false;
}
std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
return Obj != nullptr ? Obj->is64Bit() : false;
}
extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
SmallString<0> SymNameBuf;
auto SymName = raw_svector_ostream(SymNameBuf);
// In the scenario when LLVMContext is populated SymbolicFile will contain a
// reference to it, thus SymbolicFile should be destroyed first.
LLVMContext Context;
Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
getSymbolicFile(Buf->getMemBufferRef(), Context);
if (!ObjOrErr) {
return false;
}
std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
if (Obj == nullptr) {
return false;
}
// Code starting from this line is copied from isECObject in
// ArchiveWriter.cpp with an extra #if to work with LLVM 17.
if (Obj->isCOFF())
return cast<llvm::object::COFFObjectFile>(&*Obj)->getMachine() !=
COFF::IMAGE_FILE_MACHINE_ARM64;
#if LLVM_VERSION_GE(18, 0)
if (Obj->isCOFFImportFile())
return cast<llvm::object::COFFImportFile>(&*Obj)->getMachine() !=
COFF::IMAGE_FILE_MACHINE_ARM64;
#endif
if (Obj->isIR()) {
Expected<std::string> TripleStr =
getBitcodeTargetTriple(Obj->getMemoryBufferRef());
if (!TripleStr)
return false;
Triple T(*TripleStr);
return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
}
return false;
}

View File

@ -388,6 +388,9 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword
parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
parse_invalid_label =
invalid label name `{$name}`
parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
.label = invalid suffix `{$suffix}`
.tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases
@ -414,6 +417,9 @@ parse_invalid_unicode_escape = invalid unicode character escape
parse_invalid_variable_declaration =
invalid variable declaration
parse_keyword_lifetime =
lifetimes cannot use keyword names
parse_kw_bad_case = keyword `{$kw}` is written in the wrong case
.suggestion = write it in the correct case

View File

@ -2009,6 +2009,21 @@ pub struct CannotBeRawIdent {
pub ident: Symbol,
}
#[derive(Diagnostic)]
#[diag(parse_keyword_lifetime)]
pub struct KeywordLifetime {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_invalid_label)]
pub struct InvalidLabel {
#[primary_span]
pub span: Span,
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(parse_cr_doc_comment)]
pub struct CrDocComment {

View File

@ -2932,10 +2932,17 @@ impl<'a> Parser<'a> {
}
pub(crate) fn eat_label(&mut self) -> Option<Label> {
self.token.lifetime().map(|ident| {
if let Some(ident) = self.token.lifetime() {
// Disallow `'fn`, but with a better error message than `expect_lifetime`.
if ident.without_first_quote().is_reserved() {
self.dcx().emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
}
self.bump();
Label { ident }
})
Some(Label { ident })
} else {
None
}
}
/// Parses a `match ... { ... }` expression (`match` token already eaten).

View File

@ -177,8 +177,11 @@ impl<'a> Parser<'a> {
.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?))
}
NonterminalKind::Lifetime => {
return if self.check_lifetime() {
Ok(ParseNtResult::Lifetime(self.expect_lifetime().ident))
// We want to keep `'keyword` parsing, just like `keyword` is still
// an ident for nonterminal purposes.
return if let Some(ident) = self.token.lifetime() {
self.bump();
Ok(ParseNtResult::Lifetime(ident))
} else {
Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime {
span: self.token.span,

View File

@ -542,12 +542,12 @@ impl<'a> Parser<'a> {
None => PatKind::Path(qself, path),
}
}
} else if let token::Lifetime(lt) = self.token.kind
} else if let Some(lt) = self.token.lifetime()
// In pattern position, we're totally fine with using "next token isn't colon"
// as a heuristic. We could probably just always try to recover if it's a lifetime,
// because we never have `'a: label {}` in a pattern position anyways, but it does
// keep us from suggesting something like `let 'a: Ty = ..` => `let 'a': Ty = ..`
&& could_be_unclosed_char_literal(Ident::with_dummy_span(lt))
&& could_be_unclosed_char_literal(lt)
&& !self.look_ahead(1, |token| matches!(token.kind, token::Colon))
{
// Recover a `'a` as a `'a'` literal
@ -683,12 +683,12 @@ impl<'a> Parser<'a> {
/// Parse `&pat` / `&mut pat`.
fn parse_pat_deref(&mut self, expected: Option<Expected>) -> PResult<'a, PatKind> {
self.expect_and()?;
if let token::Lifetime(name) = self.token.kind {
if let Some(lifetime) = self.token.lifetime() {
self.bump(); // `'a`
self.dcx().emit_err(UnexpectedLifetimeInPattern {
span: self.prev_token.span,
symbol: name,
symbol: lifetime.name,
suggestion: self.prev_token.span.until(self.token.span),
});
}

View File

@ -1230,6 +1230,12 @@ impl<'a> Parser<'a> {
/// Parses a single lifetime `'a` or panics.
pub(super) fn expect_lifetime(&mut self) -> Lifetime {
if let Some(ident) = self.token.lifetime() {
if ident.without_first_quote().is_reserved()
&& ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
{
self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
}
self.bump();
Lifetime { ident, id: ast::DUMMY_NODE_ID }
} else {

View File

@ -316,7 +316,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
}
fn insert_field_def_ids(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
fn insert_field_idents(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
if fields.iter().any(|field| field.is_placeholder) {
// The fields are not expanded yet.
return;
@ -652,7 +652,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let def_id = feed.key();
// Record field names for error reporting.
self.insert_field_def_ids(def_id, fields);
self.insert_field_idents(def_id, fields);
self.insert_field_visibilities_local(def_id.to_def_id(), fields);
for field in fields {
@ -1520,7 +1520,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
// Record field names for error reporting.
self.insert_field_def_ids(def_id, variant.data.fields());
self.insert_field_idents(def_id, variant.data.fields());
self.insert_field_visibilities_local(def_id.to_def_id(), variant.data.fields());
visit::walk_variant(self, variant);

View File

@ -8,7 +8,8 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor as _;
use rustc_hir::LangItem;
use rustc_infer::infer::error_reporting::{TypeAnnotationNeeded, TypeErrCtxt};
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt};
use rustc_infer::traits::util::elaborate;
use rustc_infer::traits::{

View File

@ -4,7 +4,6 @@ use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt;
use crate::errors::{
AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
};
use crate::infer::error_reporting::TyCategory;
use crate::infer::InferCtxtExt as _;
use crate::infer::{self, InferCtxt};
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
@ -25,7 +24,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::error_reporting::infer::TyCategory;
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_macros::extension;
use rustc_middle::traits::select::OverflowError;

View File

@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::traits::{
Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError,
};

View File

@ -3,7 +3,6 @@ use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt;
use crate::errors::{
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
};
use crate::infer::error_reporting::TypeErrCtxt;
use crate::infer::InferCtxtExt;
use rustc_ast::AttrArgs;
use rustc_ast::AttrArgsEq;
@ -14,6 +13,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_macros::{extension, LintDiagnostic};
use rustc_middle::bug;
use rustc_middle::ty::print::PrintTraitRefExt as _;

View File

@ -5,7 +5,7 @@ use rustc_errors::{
};
use rustc_hir::def::Namespace;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::traits::{Obligation, PredicateObligation};
use rustc_macros::extension;
use rustc_middle::ty::print::{FmtPrinter, Print};

View File

@ -23,7 +23,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::is_range_literal;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::error_reporting::infer::TypeErrCtxt;
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
use rustc_macros::extension;
use rustc_middle::hir::map;

View File

@ -1820,6 +1820,21 @@ impl Step for Assemble {
&self_contained_lld_dir.join(exe(name, target_compiler.host)),
);
}
// In addition to `rust-lld` also install `wasm-component-ld` when
// LLD is enabled. This is a relatively small binary that primarily
// delegates to the `rust-lld` binary for linking and then runs
// logic to create the final binary. This is used by the
// `wasm32-wasip2` target of Rust.
let wasm_component_ld_exe =
builder.ensure(crate::core::build_steps::tool::WasmComponentLd {
compiler: build_compiler,
target: target_compiler.host,
});
builder.copy_link(
&wasm_component_ld_exe,
&libdir_bin.join(wasm_component_ld_exe.file_name().unwrap()),
);
}
if builder.config.llvm_enabled(target_compiler.host) {

View File

@ -337,6 +337,7 @@ bootstrap_tool!(
RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test";
CoverageDump, "src/tools/coverage-dump", "coverage-dump";
RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
);
#[derive(Debug, Clone, Hash, PartialEq, Eq)]

View File

@ -112,6 +112,7 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown
ENV TARGETS=$TARGETS,wasm32-wasi
ENV TARGETS=$TARGETS,wasm32-wasip1
ENV TARGETS=$TARGETS,wasm32-wasip1-threads
ENV TARGETS=$TARGETS,wasm32-wasip2
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
ENV TARGETS=$TARGETS,x86_64-pc-solaris
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32

View File

@ -3,7 +3,7 @@ error[E0308]: mismatched types
|
LL | const S: A = B;
| ^ expected `A`, found `B`
-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
error: aborting due to 1 previous error

View File

@ -96,9 +96,7 @@ run-make/print-target-list/Makefile
run-make/prune-link-args/Makefile
run-make/raw-dylib-alt-calling-convention/Makefile
run-make/raw-dylib-c/Makefile
run-make/raw-dylib-custom-dlltool/Makefile
run-make/raw-dylib-import-name-type/Makefile
run-make/raw-dylib-inline-cross-dylib/Makefile
run-make/raw-dylib-link-ordinal/Makefile
run-make/raw-dylib-stdcall-ordinal/Makefile
run-make/redundant-libs/Makefile

View File

@ -95,7 +95,12 @@ const EXCEPTIONS: ExceptionList = &[
("self_cell", "Apache-2.0"), // rustc (fluent translations)
("snap", "BSD-3-Clause"), // rustc
("wasm-encoder", "Apache-2.0 WITH LLVM-exception"), // rustc
("wasm-metadata", "Apache-2.0 WITH LLVM-exception"), // rustc
("wasmparser", "Apache-2.0 WITH LLVM-exception"), // rustc
("wast", "Apache-2.0 WITH LLVM-exception"), // rustc
("wat", "Apache-2.0 WITH LLVM-exception"), // rustc
("wit-component", "Apache-2.0 WITH LLVM-exception"), // rustc
("wit-parser", "Apache-2.0 WITH LLVM-exception"), // rustc
// tidy-alphabetical-end
];

View File

@ -0,0 +1,13 @@
# See the `README.md` in this directory for what this tool is.
[package]
name = "wasm-component-ld-wrapper"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "wasm-component-ld"
path = "src/main.rs"
[dependencies]
wasm-component-ld = "0.5.4"

View File

@ -0,0 +1,62 @@
# `wasm-component-ld`
This wrapper is a wrapper around the [`wasm-component-ld`] crates.io crate. That
crate. That crate is itself a thin wrapper around two pieces:
* `wasm-ld` - the LLVM-based linker distributed as part of LLD and packaged in
Rust as `rust-lld`.
* [`wit-component`] - a Rust crate for creating a [WebAssembly Component] from a
core wasm module.
This linker is used for Rust's `wasm32-wasip2` target to natively output a
component instead of a core WebAssembly module, unlike other WebAssembly
targets. If you're confused about any of this here's an FAQ-style explanation of
what's going on here:
* **What's a component?** - It's a proposal to the WebAssembly standard
primarily developed at this time by out-of-browser use cases of WebAssembly.
You can find high-level documentation [here][component docs].
* **What's WASIp2?** - Not to be confused with WASIp1, WASIp0,
`wasi_snapshot_preview1`, or `wasi_unstable`, it's a version of WASI. Released
in January 2024 it's the first version of WASI defined in terms of the
component model.
* **Why does this need its own linker?** - like any target that Rust has the
`wasm32-wasip2` target needs a linker. What makes this different from other
WebAssembly targets is that WASIp2 is defined at the component level, not core
WebAssembly level. This means that filesystem functions take a `string`
instead of `i32 i32`, for example. This means that the raw output of LLVM and
`wasm-ld`, a core WebAssembly module, is not suitable.
* **Isn't writing a linker really hard?** - Generally, yes, but this linker
works by first asking `wasm-ld` to do all the hard work. It invokes `wasm-ld`
and then uses the output core WebAssembly module to create a component.
* **How do you create a component from a core module?** - this is the purpose of
the [`wit-component`] crate, notably the `ComponentEncoder` type. This uses
component type information embedded in the core module and a general set of
conventions/guidelines with what the core module imports/exports. A component
is then hooked up to codify all of these conventions in a component itself.
* **Why not require users to run `wit-component` themselves?** - while possible
it adds friction to the usage `wasm32-wasip2` target. More importantly though
the "module only" output of the `wasm32-wasip2` target is not ready right now.
The standard library still imports from `wasi_snapshot_preview1` and it will
take time to migrate all usage to WASIp2.
* **What exactly does this linker do?** - the `wasm-component-ld` has the same
CLI interface and flags as `wasm-ld`, plus some more that are
component-specific. These flags are used to forward most flags to `wasm-ld` to
produce a core wasm module. After the core wasm module is produced the
`wit-component` crate will read custom sections in the final binary which
contain component type information. After merging all this type information
together a component is produced which wraps the core module.
If you've got any other questions about this linker or its operation don't
hesitate to reach out to the maintainers of the `wasm32-wasip2` target.
[`wasm-component-ld`]: https://crates.io/crates/wasm-component-ld
[`wit-component`]: https://crates.io/crates/wit-component
[WebAssembly Component]: https://github.com/webassembly/component-model
[component docs]: https://component-model.bytecodealliance.org/

View File

@ -0,0 +1,9 @@
// See the `README.md` in this directory for what this tool is.
// The source for this crate lives at
// https://github.com/bytecodealliance/wasm-component-ld and the binary is
// independently used in other projects such as `wasi-sdk` so the `main`
// function is just reexported here to delegate. A Cargo dependency is used to
// facilitate version management in the Rust repository and work well with
// vendored/offline builds.
use wasm_component_ld::main;

View File

@ -1,11 +0,0 @@
# Test using -Cdlltool to change where raw-dylib looks for the dlltool binary.
# only-windows
# only-gnu
# needs-dlltool
include ../tools.mk
all:
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs -Cdlltool=$(CURDIR)/script.cmd
$(DIFF) output.txt "$(TMPDIR)"/output.txt

View File

@ -0,0 +1,24 @@
// Instead of using the default dlltool, the rust compiler can also accept a custom
// command file with the -C dlltool flag. This test uses it to compile some rust code
// with the raw_dylib Windows-exclusive feature, and checks that the output contains
// the string passed from the custom dlltool, confirming that the default dlltool was
// successfully overridden.
// See https://github.com/rust-lang/rust/pull/109677
//@ only-windows
//@ only-gnu
//@ needs-dlltool
// Reason: this test specifically checks the custom dlltool feature, only
// available on Windows-gnu.
use run_make_support::{diff, rustc};
fn main() {
let out = rustc()
.crate_type("lib")
.crate_name("raw_dylib_test")
.input("lib.rs")
.arg("-Cdlltool=script.cmd")
.run();
diff().expected_file("output.txt").actual_file("actual.txt").normalize(r#"\r"#, "").run();
}

View File

@ -1,2 +1,2 @@
echo Called dlltool via script.cmd> %TMPDIR%\output.txt
echo Called dlltool via script.cmd> actual.txt
dlltool.exe %*

View File

@ -1,30 +0,0 @@
# Regression test for calling an inline function that uses a raw-dylib function.
# only-windows
include ../tools.mk
# We'd be using the llvm-objdump instead of the system objdump to ensure compatibility
# with the LLVM bitcode generated by rustc but on Windows piping/IO redirection under MSYS2 is wonky with llvm-objdump.
OBJDUMP = objdump
all:
$(RUSTC) --crate-type dylib --crate-name raw_dylib_test lib.rs -C prefer-dynamic
$(RUSTC) --crate-type dylib --crate-name raw_dylib_test_wrapper lib_wrapper.rs -C prefer-dynamic
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" -C prefer-dynamic
# Make sure we don't find an import to the functions we expect to be inlined.
$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function"
$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function_calls_inline"
# Make sure we do find an import to the functions we expect to be imported.
$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -e "library_function"
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
ifdef IS_MSVC
$(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll -noimplib
$(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll -noimplib
else
$(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
$(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
endif
$(call RUN,driver) | tr -d '\r' > "$(TMPDIR)"/output.txt
$(RUSTC_TEST_OP) "$(TMPDIR)"/output.txt output.txt

View File

@ -0,0 +1,61 @@
// When we generate the import library for a dylib or bin crate, we should generate it
// for the symbols both for the current crate and all upstream crates. This allows for
// using the link kind `raw-dylib` inside inline functions successfully. This test checks
// that the import symbols in the object files match this convention, and that execution
// of the binary results in all function names exported successfully.
// See https://github.com/rust-lang/rust/pull/102988
//@ only-windows
use run_make_support::{cc, diff, is_msvc, llvm_objdump, run, rustc};
fn main() {
rustc()
.crate_type("dylib")
.crate_name("raw_dylib_test")
.input("lib.rs")
.arg("-Cprefer-dynamic")
.run();
rustc()
.crate_type("dylib")
.crate_name("raw_dylib_test_wrapper")
.input("lib_wrapper.rs")
.arg("-Cprefer-dynamic")
.run();
rustc().crate_type("bin").input("driver.rs").arg("-Cprefer-dynamic").run();
llvm_objdump()
.arg("--private-headers")
.input("driver.exe")
.run()
// Make sure we don't find an import to the functions we expect to be inlined.
.assert_stdout_not_contains("inline_library_function")
// Make sure we do find an import to the functions we expect to be imported.
.assert_stdout_contains("library_function");
if is_msvc() {
cc().arg("-c").out_exe("extern_1").input("extern_1.c").run();
cc().arg("-c").out_exe("extern_2").input("extern_2.c").run();
cc().input("extern_1.obj")
.arg("-link")
.arg("-dll")
.arg("-out:extern_1.dll")
.arg("-noimplib")
.run();
cc().input("extern_2.obj")
.arg("-link")
.arg("-dll")
.arg("-out:extern_2.dll")
.arg("-noimplib")
.run();
} else {
cc().arg("-v").arg("-c").out_exe("extern_1").input("extern_1.c").run();
cc().arg("-v").arg("-c").out_exe("extern_2").input("extern_2.c").run();
cc().input("extern_1").out_exe("extern_1.dll").arg("-shared").run();
cc().input("extern_2").out_exe("extern_2.dll").arg("-shared").run();
}
let out = run("driver").stdout_utf8();
diff()
.expected_file("output.txt")
.actual_text("actual_output", out)
.normalize(r#"\r"#, "")
.run();
}

View File

@ -3,7 +3,7 @@ error[E0308]: mismatched types
|
LL | const S: A = B;
| ^ expected `A`, found `B`
-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
error: aborting due to 1 previous error

View File

@ -34,6 +34,9 @@ impl Trait for S {
reuse foo { &self.0 }
//~^ ERROR cannot find function `foo` in this scope
reuse Trait::foo2 { self.0 }
//~^ ERROR cannot find function `foo2` in trait `Trait`
//~| ERROR method `foo2` is not a member of trait `Trait`
}
mod prefix {}

View File

@ -25,6 +25,15 @@ LL | reuse <F as Trait>::baz;
| | help: there is an associated function with a similar name: `bar`
| not a member of trait `Trait`
error[E0407]: method `foo2` is not a member of trait `Trait`
--> $DIR/bad-resolve.rs:37:5
|
LL | reuse Trait::foo2 { self.0 }
| ^^^^^^^^^^^^^----^^^^^^^^^^^
| | |
| | help: there is an associated function with a similar name: `foo`
| not a member of trait `Trait`
error[E0423]: expected function, found associated constant `Trait::C`
--> $DIR/bad-resolve.rs:24:11
|
@ -54,6 +63,15 @@ error[E0425]: cannot find function `foo` in this scope
LL | reuse foo { &self.0 }
| ^^^ not found in this scope
error[E0425]: cannot find function `foo2` in trait `Trait`
--> $DIR/bad-resolve.rs:37:18
|
LL | fn foo(&self, x: i32) -> i32 { x }
| ---------------------------- similarly named associated function `foo` defined here
...
LL | reuse Trait::foo2 { self.0 }
| ^^^^ help: an associated function with a similar name exists: `foo`
error[E0046]: not all trait items implemented, missing: `Type`
--> $DIR/bad-resolve.rs:22:1
|
@ -64,18 +82,18 @@ LL | impl Trait for S {
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
error[E0433]: failed to resolve: use of undeclared crate or module `unresolved_prefix`
--> $DIR/bad-resolve.rs:40:7
--> $DIR/bad-resolve.rs:43:7
|
LL | reuse unresolved_prefix::{a, b, c};
| ^^^^^^^^^^^^^^^^^ use of undeclared crate or module `unresolved_prefix`
error[E0433]: failed to resolve: `crate` in paths can only be used in start position
--> $DIR/bad-resolve.rs:41:29
--> $DIR/bad-resolve.rs:44:29
|
LL | reuse prefix::{self, super, crate};
| ^^^^^ `crate` in paths can only be used in start position
error: aborting due to 10 previous errors
error: aborting due to 12 previous errors
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0433, E0575, E0576.
For more information about an error, try `rustc --explain E0046`.

View File

@ -24,8 +24,8 @@ reuse to_reuse::zero_args { self }
struct S(F);
impl Trait for S {
reuse Trait::bar { &self.0 }
reuse Trait::description { &self.0 }
reuse Trait::bar { self.0 }
reuse Trait::description { self.0 }
reuse <F as Trait>::static_method;
reuse <F as Trait>::static_method2 { S::static_method(self) }
}

View File

@ -34,7 +34,7 @@ mod inherent_impl_assoc_fn_to_other {
use crate::*;
impl S {
reuse Trait::foo1 { &self.0 }
reuse Trait::foo1 { self.0 }
reuse <S as Trait>::foo2;
reuse to_reuse::foo3;
reuse F::foo4 { &self.0 }
@ -46,7 +46,7 @@ mod trait_impl_assoc_fn_to_other {
use crate::*;
impl Trait for S {
reuse Trait::foo1 { &self.0 }
reuse Trait::foo1 { self.0 }
reuse <F as Trait>::foo2;
reuse to_reuse::foo3;
//~^ ERROR method `foo3` is not a member of trait `Trait`

View File

@ -91,10 +91,17 @@ error[E0308]: mismatched types
LL | trait Trait2 : Trait {
| -------------------- found this type parameter
LL | reuse <F as Trait>::foo1 { self }
| ^^^^ expected `&F`, found `&Self`
| ---- ^^^^ expected `&F`, found `&Self`
| |
| arguments to this function are incorrect
|
= note: expected reference `&F`
found reference `&Self`
note: method defined here
--> $DIR/explicit-paths.rs:5:8
|
LL | fn foo1(&self, x: i32) -> i32 { x }
| ^^^^ -----
error[E0277]: the trait bound `S2: Trait` is not satisfied
--> $DIR/explicit-paths.rs:78:16

View File

@ -4,15 +4,6 @@ error[E0308]: mismatched types
LL | fn description(&self) -> &str {}
| ^^ expected `&str`, found `()`
error[E0308]: mismatched types
--> $DIR/ice-issue-122550.rs:13:39
|
LL | reuse <S as Trait>::description { &self.0 }
| ^^^^^^^ expected `&S`, found `&F`
|
= note: expected reference `&S`
found reference `&F`
error[E0277]: the trait bound `S: Trait` is not satisfied
--> $DIR/ice-issue-122550.rs:13:12
|
@ -25,6 +16,22 @@ help: this trait has no implementations, consider adding one
LL | trait Trait {
| ^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/ice-issue-122550.rs:13:39
|
LL | reuse <S as Trait>::description { &self.0 }
| ----------- ^^^^^^^ expected `&S`, found `&F`
| |
| arguments to this function are incorrect
|
= note: expected reference `&S`
found reference `&F`
note: method defined here
--> $DIR/ice-issue-122550.rs:5:8
|
LL | fn description(&self) -> &str {}
| ^^^^^^^^^^^ -----
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0308.

View File

@ -0,0 +1,25 @@
#![feature(fn_delegation)]
#![allow(incomplete_features)]
trait Trait {
fn foo(&self) {}
}
struct F;
impl Trait for F {}
struct S(F);
pub mod to_reuse {
use crate::F;
pub fn foo(_: &F) {}
}
impl Trait for S {
// Make sure that the method call is not generated if the path resolution
// does not have a `self` parameter.
reuse to_reuse::foo { self.0 }
//~^ ERROR mismatched types
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0308]: mismatched types
--> $DIR/method-call-choice.rs:21:27
|
LL | reuse to_reuse::foo { self.0 }
| --- ^^^^^^ expected `&F`, found `F`
| |
| arguments to this function are incorrect
|
note: function defined here
--> $DIR/method-call-choice.rs:15:12
|
LL | pub fn foo(_: &F) {}
| ^^^ -----
help: consider borrowing here
|
LL | reuse to_reuse::foo { &self.0 }
| +
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,34 @@
//@ run-pass
#![feature(fn_delegation)]
#![allow(incomplete_features)]
#![allow(dead_code)]
trait Trait1 {
fn foo(&self) -> i32 { 1 }
}
trait Trait2 {
fn foo(&self) -> i32 { 2 }
}
struct F;
impl Trait1 for F {}
impl Trait2 for F {}
impl F {
fn foo(&self) -> i32 { 3 }
}
struct S(F);
impl Trait1 for S {
// Make sure that the generated `self.0.foo()` does not turn into the inherent method `F::foo`
// that has a higher priority than methods from traits.
reuse Trait1::foo { self.0 }
}
fn main() {
let s = S(F);
assert_eq!(s.foo(), 1);
}

View File

@ -0,0 +1,26 @@
//@ run-pass
#![feature(fn_delegation)]
#![allow(incomplete_features)]
trait Trait : Sized {
fn by_value(self) -> i32 { 1 }
fn by_mut_ref(&mut self) -> i32 { 2 }
fn by_ref(&self) -> i32 { 3 }
}
struct F;
impl Trait for F {}
struct S(F);
impl Trait for S {
reuse Trait::{by_value, by_mut_ref, by_ref} { self.0 }
}
fn main() {
let mut s = S(F);
assert_eq!(s.by_ref(), 3);
assert_eq!(s.by_mut_ref(), 2);
assert_eq!(s.by_value(), 1);
}

View File

@ -0,0 +1,15 @@
// Disallow `'keyword` even in cfg'd code.
#[cfg(any())]
fn hello() -> &'ref () {}
//~^ ERROR lifetimes cannot use keyword names
macro_rules! macro_invocation {
($i:item) => {}
}
macro_invocation! {
fn hello() -> &'ref () {}
//~^ ERROR lifetimes cannot use keyword names
}
fn main() {}

View File

@ -0,0 +1,14 @@
error: lifetimes cannot use keyword names
--> $DIR/cfg-keyword-lifetime.rs:4:16
|
LL | fn hello() -> &'ref () {}
| ^^^^
error: lifetimes cannot use keyword names
--> $DIR/cfg-keyword-lifetime.rs:11:20
|
LL | fn hello() -> &'ref () {}
| ^^^^
error: aborting due to 2 previous errors

View File

@ -24,12 +24,14 @@ fn main() {
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
//~| ERROR expected
//~| HELP add `'` to close the char literal
//~| ERROR invalid label name
f<'_>();
//~^ comparison operators cannot be chained
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
//~| ERROR expected
//~| HELP add `'` to close the char literal
//~| ERROR invalid label name
let _ = f<u8>;
//~^ ERROR comparison operators cannot be chained

View File

@ -53,6 +53,12 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
LL | let _ = f::<u8, i8>();
| ++
error: invalid label name `'_`
--> $DIR/require-parens-for-chained-comparison.rs:22:15
|
LL | let _ = f<'_, i8>();
| ^^
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/require-parens-for-chained-comparison.rs:22:17
|
@ -75,8 +81,14 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
LL | let _ = f::<'_, i8>();
| ++
error: invalid label name `'_`
--> $DIR/require-parens-for-chained-comparison.rs:29:7
|
LL | f<'_>();
| ^^
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/require-parens-for-chained-comparison.rs:28:9
--> $DIR/require-parens-for-chained-comparison.rs:29:9
|
LL | f<'_>();
| ^ expected `while`, `for`, `loop` or `{` after a label
@ -87,7 +99,7 @@ LL | f<'_'>();
| +
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:28:6
--> $DIR/require-parens-for-chained-comparison.rs:29:6
|
LL | f<'_>();
| ^ ^
@ -98,7 +110,7 @@ LL | f::<'_>();
| ++
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:34:14
--> $DIR/require-parens-for-chained-comparison.rs:36:14
|
LL | let _ = f<u8>;
| ^ ^
@ -106,5 +118,5 @@ LL | let _ = f<u8>;
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
= help: or use `(...)` if you meant to specify fn arguments
error: aborting due to 10 previous errors
error: aborting due to 12 previous errors

View File

@ -4,6 +4,12 @@ error: expected identifier, found keyword `Self`
LL | struct Self;
| ^^^^ expected identifier, found keyword
error: lifetimes cannot use keyword names
--> $DIR/self_type_keyword.rs:6:12
|
LL | struct Bar<'Self>;
| ^^^^^
error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:14:13
|
@ -53,12 +59,6 @@ error: expected identifier, found keyword `Self`
LL | trait Self {}
| ^^^^ expected identifier, found keyword
error: lifetimes cannot use keyword names
--> $DIR/self_type_keyword.rs:6:12
|
LL | struct Bar<'Self>;
| ^^^^^
error: cannot find macro `Self` in this scope
--> $DIR/self_type_keyword.rs:21:9
|