mirror of https://github.com/rust-lang/rust.git
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:
commit
7d356ebde3
172
Cargo.lock
172
Cargo.lock
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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}`"))
|
|
@ -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.
|
|
@ -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;
|
|
@ -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};
|
|
@ -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;
|
|
@ -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};
|
|
@ -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};
|
|
@ -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;
|
|
@ -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;
|
|
@ -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> {
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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};
|
||||
|
|
@ -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};
|
|
@ -0,0 +1 @@
|
|||
pub mod infer;
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
|
@ -34,6 +34,7 @@
|
|||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
pub mod error_reporting;
|
||||
mod errors;
|
||||
pub mod infer;
|
||||
pub mod traits;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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::{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 _;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
];
|
||||
|
||||
|
|
|
@ -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"
|
|
@ -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/
|
|
@ -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;
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -1,2 +1,2 @@
|
|||
echo Called dlltool via script.cmd> %TMPDIR%\output.txt
|
||||
echo Called dlltool via script.cmd> actual.txt
|
||||
dlltool.exe %*
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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() {}
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
Loading…
Reference in New Issue