commit
cd952c8c69
28583 changed files with 28991 additions and 13522 deletions
|
|
@ -6,3 +6,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60
|
|||
971c549ca334b7b7406e61e958efcca9c4152822
|
||||
# refactor infcx building
|
||||
283abbf0e7d20176f76006825b5c52e9a4234e4c
|
||||
# format libstd/sys
|
||||
c34fbfaad38cf5829ef5cfe780dc9d58480adeaa
|
||||
|
|
|
|||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -342,7 +342,7 @@ jobs:
|
|||
os: macos-12-xl
|
||||
- name: x86_64-apple-1
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test --exclude src/test/ui --exclude src/test/rustdoc --exclude src/test/run-make-fulldeps"
|
||||
SCRIPT: "./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps"
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.8
|
||||
|
|
@ -353,7 +353,7 @@ jobs:
|
|||
os: macos-12-xl
|
||||
- name: x86_64-apple-2
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test src/test/ui src/test/rustdoc src/test/run-make-fulldeps"
|
||||
SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps"
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.8
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -26,7 +26,7 @@ Session.vim
|
|||
.valgrindrc
|
||||
.cargo
|
||||
# Included because it is part of the test case
|
||||
!/src/test/run-make/thumb-none-qemu/example/.cargo
|
||||
!/tests/run-make/thumb-none-qemu/example/.cargo
|
||||
|
||||
## Configuration
|
||||
/config.toml
|
||||
|
|
@ -74,6 +74,6 @@ package-lock.json
|
|||
package.json
|
||||
|
||||
## Rustdoc GUI tests
|
||||
src/test/rustdoc-gui/src/**.lock
|
||||
tests/rustdoc-gui/src/**.lock
|
||||
|
||||
# Before adding new lines, see the comment at the top.
|
||||
|
|
|
|||
53
Cargo.lock
53
Cargo.lock
|
|
@ -203,6 +203,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.5.3"
|
||||
|
|
@ -328,6 +334,7 @@ name = "cargo"
|
|||
version = "0.69.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
"bytesize",
|
||||
"cargo-platform 0.1.2",
|
||||
"cargo-test-macro",
|
||||
|
|
@ -345,6 +352,7 @@ dependencies = [
|
|||
"git2-curl",
|
||||
"glob",
|
||||
"hex 0.4.2",
|
||||
"hmac",
|
||||
"home",
|
||||
"http-auth",
|
||||
"humantime 2.0.1",
|
||||
|
|
@ -375,6 +383,7 @@ dependencies = [
|
|||
"serde-value",
|
||||
"serde_ignored",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
"shell-escape",
|
||||
"snapbox",
|
||||
"strip-ansi-escapes",
|
||||
|
|
@ -1778,9 +1787,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
|
||||
checksum = "be36bc9e0546df253c0cc41fd0af34f5e92845ad8509462ec76672fac6997f5b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
|
@ -1793,9 +1802,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "git2-curl"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed817a00721e2f8037ba722e60358d4956dae9cca10315fc982f967907d3b0cd"
|
||||
checksum = "7577f4e6341ba7c90d883511130a45b956c274ba5f4d205d9f9da990f654cd33"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"git2",
|
||||
|
|
@ -2335,9 +2344,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.14.0+1.5.0"
|
||||
version = "0.14.1+1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"
|
||||
checksum = "4a07fb2692bc3593bda59de45a502bb3071659f2c515e28c71e728306b038e17"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
|
@ -5025,18 +5034,18 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.14"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
|
@ -5053,9 +5062,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -5073,9 +5082,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.91"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
|
|
@ -5094,6 +5103,17 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
|
|
@ -5380,9 +5400,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -5556,7 +5576,6 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
"semver",
|
||||
"termcolor",
|
||||
"walkdir",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ exclude = [
|
|||
"compiler/rustc_codegen_cranelift",
|
||||
"compiler/rustc_codegen_gcc",
|
||||
"src/bootstrap",
|
||||
"src/test/rustdoc-gui",
|
||||
"tests/rustdoc-gui",
|
||||
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
|
||||
"obj",
|
||||
# The `x` binary is a thin wrapper that calls `x.py`, which initializes
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
Version 1.66.1 (2023-01-10)
|
||||
===========================
|
||||
|
||||
- Added validation of SSH host keys for git URLs in Cargo ([CVE-2022-46176](https://www.cve.org/CVERecord?id=CVE-2022-46176))
|
||||
|
||||
Version 1.66.0 (2022-12-15)
|
||||
==========================
|
||||
|
||||
|
|
|
|||
|
|
@ -1263,8 +1263,8 @@ pub enum Variants<V: Idx> {
|
|||
|
||||
/// Enum-likes with more than one inhabited variant: each variant comes with
|
||||
/// a *discriminant* (usually the same as the variant index but the user can
|
||||
/// assign explicit discriminant values). That discriminant is encoded
|
||||
/// as a *tag* on the machine. The layout of each variant is
|
||||
/// assign explicit discriminant values). That discriminant is encoded
|
||||
/// as a *tag* on the machine. The layout of each variant is
|
||||
/// a struct, and they all have space reserved for the tag.
|
||||
/// For enums, the tag is the sole field of the layout.
|
||||
Multiple {
|
||||
|
|
|
|||
|
|
@ -1307,6 +1307,7 @@ impl Expr {
|
|||
pub struct Closure {
|
||||
pub binder: ClosureBinder,
|
||||
pub capture_clause: CaptureBy,
|
||||
pub constness: Const,
|
||||
pub asyncness: Async,
|
||||
pub movability: Movability,
|
||||
pub fn_decl: P<FnDecl>,
|
||||
|
|
|
|||
|
|
@ -1362,6 +1362,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause: _,
|
||||
constness,
|
||||
asyncness,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
|
|
@ -1370,6 +1371,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
fn_arg_span: _,
|
||||
}) => {
|
||||
vis.visit_closure_binder(binder);
|
||||
visit_constness(constness, vis);
|
||||
vis.visit_asyncness(asyncness);
|
||||
vis.visit_fn_decl(fn_decl);
|
||||
vis.visit_expr(body);
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ impl ExprPrecedence {
|
|||
| ExprPrecedence::Yeet => PREC_JUMP,
|
||||
|
||||
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
|
||||
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
||||
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
||||
// ensures that `pprust` will add parentheses in the right places to get the desired
|
||||
// parse.
|
||||
ExprPrecedence::Range => PREC_RANGE,
|
||||
|
|
|
|||
|
|
@ -836,6 +836,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||
binder,
|
||||
capture_clause: _,
|
||||
asyncness: _,
|
||||
constness: _,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
body,
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
|
|
@ -233,6 +234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
binder,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
*constness,
|
||||
*movability,
|
||||
fn_decl,
|
||||
body,
|
||||
|
|
@ -651,6 +653,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn_decl_span: self.lower_span(span),
|
||||
fn_arg_span: None,
|
||||
movability: Some(hir::Movability::Static),
|
||||
constness: hir::Constness::NotConst,
|
||||
});
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
|
|
@ -689,8 +692,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// call (like the identity function), as otherwise type and lifetime
|
||||
// inference have a hard time figuring things out.
|
||||
// Without this, we would get:
|
||||
// E0720 in src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
|
||||
// E0700 in src/test/ui/self/self_lifetime-async.rs
|
||||
// E0720 in tests/ui/impl-trait/in-trait/default-body-with-rpit.rs
|
||||
// E0700 in tests/ui/self/self_lifetime-async.rs
|
||||
|
||||
// `future::identity_future`:
|
||||
let identity_future =
|
||||
|
|
@ -890,6 +893,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
binder: &ClosureBinder,
|
||||
capture_clause: CaptureBy,
|
||||
closure_id: NodeId,
|
||||
constness: Const,
|
||||
movability: Movability,
|
||||
decl: &FnDecl,
|
||||
body: &Expr,
|
||||
|
|
@ -927,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: generator_option,
|
||||
constness: self.lower_constness(constness),
|
||||
});
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
|
|
@ -1041,6 +1046,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: None,
|
||||
constness: hir::Constness::NotConst,
|
||||
});
|
||||
hir::ExprKind::Closure(c)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pub(super) fn index_hir<'hir>(
|
|||
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
|
||||
let mut nodes = IndexVec::new();
|
||||
// This node's parent should never be accessed: the owner's parent is computed by the
|
||||
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
|
||||
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
|
||||
// used.
|
||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
|
||||
let mut collector = NodeCollector {
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
//
|
||||
// The first two are produced by recursively invoking
|
||||
// `lower_use_tree` (and indeed there may be things
|
||||
// like `use foo::{a::{b, c}}` and so forth). They
|
||||
// like `use foo::{a::{b, c}}` and so forth). They
|
||||
// wind up being directly added to
|
||||
// `self.items`. However, the structure of this
|
||||
// function also requires us to return one item, and
|
||||
|
|
@ -1239,7 +1239,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_constness(&mut self, c: Const) -> hir::Constness {
|
||||
pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
|
||||
match c {
|
||||
Const::Yes(_) => hir::Constness::Const,
|
||||
Const::No => hir::Constness::NotConst,
|
||||
|
|
|
|||
|
|
@ -663,7 +663,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
||||
}
|
||||
|
||||
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
||||
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
||||
/// queries which depend on the full HIR tree and those which only depend on the item signature.
|
||||
fn hash_owner(
|
||||
&mut self,
|
||||
|
|
@ -1194,7 +1194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
itctx: &ImplTraitContext,
|
||||
) -> hir::Ty<'hir> {
|
||||
// Check whether we should interpret this as a bare trait object.
|
||||
// This check mirrors the one in late resolution. We only introduce this special case in
|
||||
// This check mirrors the one in late resolution. We only introduce this special case in
|
||||
// the rare occurrence we need to lower `Fresh` anonymous lifetimes.
|
||||
// The other cases when a qpath should be opportunistically made a trait object are handled
|
||||
// by `ty_path`.
|
||||
|
|
@ -1919,7 +1919,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
this.with_remapping(new_remapping, |this| {
|
||||
// We have to be careful to get elision right here. The
|
||||
// idea is that we create a lifetime parameter for each
|
||||
// lifetime in the return type. So, given a return type
|
||||
// lifetime in the return type. So, given a return type
|
||||
// like `async fn foo(..) -> &[&u32]`, we lower to `impl
|
||||
// Future<Output = &'1 [ &'2 u32 ]>`.
|
||||
//
|
||||
|
|
@ -2013,7 +2013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// Create the `Foo<...>` reference itself. Note that the `type
|
||||
// Foo = impl Trait` is, internally, created as a child of the
|
||||
// async fn, so the *type parameters* are inherited. It's
|
||||
// async fn, so the *type parameters* are inherited. It's
|
||||
// only the lifetime parameters that we must supply.
|
||||
let opaque_ty_ref = hir::TyKind::OpaqueDef(
|
||||
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
|
||||
|
|
|
|||
|
|
@ -385,6 +385,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
ast::ExprKind::TryBlock(_) => {
|
||||
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
|
||||
}
|
||||
ast::ExprKind::Closure(box ast::Closure { constness: ast::Const::Yes(_), .. }) => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
const_closures,
|
||||
e.span,
|
||||
"const closures are experimental"
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_expr(self, e)
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ impl<'a> State<'a> {
|
|||
ast::ExprKind::Closure(box ast::Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
|
|
@ -407,6 +408,7 @@ impl<'a> State<'a> {
|
|||
fn_arg_span: _,
|
||||
}) => {
|
||||
self.print_closure_binder(binder);
|
||||
self.print_constness(*constness);
|
||||
self.print_movability(*movability);
|
||||
self.print_asyncness(*asyncness);
|
||||
self.print_capture_clause(*capture_clause);
|
||||
|
|
@ -471,10 +473,10 @@ impl<'a> State<'a> {
|
|||
self.word("]");
|
||||
}
|
||||
ast::ExprKind::Range(start, end, limits) => {
|
||||
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
||||
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
||||
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
||||
// Here we use a fake precedence value so that any child with lower precedence than
|
||||
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
||||
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
||||
let fake_prec = AssocOp::LOr.precedence() as i8;
|
||||
if let Some(e) = start {
|
||||
self.print_expr_maybe_paren(e, fake_prec);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub use super::{
|
|||
/// can, for example, happen when requesting a body of a `const` function
|
||||
/// because they are evaluated during typechecking. The panic can be avoided
|
||||
/// by overriding the `mir_borrowck` query. You can find a complete example
|
||||
/// that shows how to do this at `src/test/run-make/obtain-borrowck/`.
|
||||
/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
|
||||
///
|
||||
/// * Polonius is highly unstable, so expect regular changes in its signature or other details.
|
||||
pub fn get_body_with_borrowck_facts(
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_note(
|
||||
MultiSpan::from_spans(reinit_spans),
|
||||
&if reinits <= 3 {
|
||||
format!("these {} reinitializations might get skipped", reinits)
|
||||
format!("these {reinits} reinitializations might get skipped")
|
||||
} else {
|
||||
format!(
|
||||
"these 3 reinitializations and {} other{} might get skipped",
|
||||
|
|
@ -225,9 +225,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"value {} here after {}move",
|
||||
"value {} here after {partial_str}move",
|
||||
desired_action.as_verb_in_past_tense(),
|
||||
partial_str
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -257,7 +256,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&format!(
|
||||
"consider creating a fresh reborrow of {} here",
|
||||
self.describe_place(moved_place)
|
||||
.map(|n| format!("`{}`", n))
|
||||
.map(|n| format!("`{n}`"))
|
||||
.unwrap_or_else(|| "the mutable reference".to_string()),
|
||||
),
|
||||
"&mut *",
|
||||
|
|
@ -271,7 +270,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
);
|
||||
let note_msg = match opt_name {
|
||||
Some(name) => format!("`{}`", name),
|
||||
Some(name) => format!("`{name}`"),
|
||||
None => "value".to_owned(),
|
||||
};
|
||||
if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, ¬e_msg) {
|
||||
|
|
@ -297,9 +296,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
} = use_spans
|
||||
{
|
||||
err.note(&format!(
|
||||
"{} occurs due to deref coercion to `{}`",
|
||||
"{} occurs due to deref coercion to `{deref_target_ty}`",
|
||||
desired_action.as_noun(),
|
||||
deref_target_ty
|
||||
));
|
||||
|
||||
// Check first whether the source is accessible (issue #87060)
|
||||
|
|
@ -1739,7 +1737,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
/// We check that there's a single level of block nesting to ensure always correct
|
||||
/// suggestions. If we don't, then we only provide a free-form message to avoid
|
||||
/// misleading users in cases like `src/test/ui/nll/borrowed-temporary-error.rs`.
|
||||
/// misleading users in cases like `tests/ui/nll/borrowed-temporary-error.rs`.
|
||||
/// We could expand the analysis to suggest hoising all of the relevant parts of
|
||||
/// the users' code to make the code compile, but that could be too much.
|
||||
struct NestedStatementVisitor {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, message),
|
||||
format!("{borrow_desc}borrow later {message}"),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -90,7 +90,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
let capture_kind_label = message;
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, capture_kind_label),
|
||||
format!("{borrow_desc}borrow later {capture_kind_label}"),
|
||||
);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
};
|
||||
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
|
||||
if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
|
||||
err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
|
||||
err.span_label(var_or_use_span, format!("{borrow_desc}{message}"));
|
||||
} else {
|
||||
// path_span must be `Some` as otherwise the if condition is true
|
||||
let path_span = path_span.unwrap();
|
||||
|
|
@ -121,7 +121,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
let capture_kind_label = message;
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, capture_kind_label),
|
||||
format!("{borrow_desc}borrow later {capture_kind_label}"),
|
||||
);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
|
|
@ -160,12 +160,8 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
match local_names[dropped_local] {
|
||||
Some(local_name) if !local_decl.from_compiler_desugaring() => {
|
||||
let message = format!(
|
||||
"{B}borrow might be used here, when `{LOC}` is dropped \
|
||||
and runs the {DTOR} for {TYPE}",
|
||||
B = borrow_desc,
|
||||
LOC = local_name,
|
||||
TYPE = type_desc,
|
||||
DTOR = dtor_desc
|
||||
"{borrow_desc}borrow might be used here, when `{local_name}` is dropped \
|
||||
and runs the {dtor_desc} for {type_desc}",
|
||||
);
|
||||
err.span_label(body.source_info(drop_loc).span, message);
|
||||
|
||||
|
|
@ -180,18 +176,14 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
err.span_label(
|
||||
local_decl.source_info.span,
|
||||
format!(
|
||||
"a temporary with access to the {B}borrow \
|
||||
"a temporary with access to the {borrow_desc}borrow \
|
||||
is created here ...",
|
||||
B = borrow_desc
|
||||
),
|
||||
);
|
||||
let message = format!(
|
||||
"... and the {B}borrow might be used here, \
|
||||
"... and the {borrow_desc}borrow might be used here, \
|
||||
when that temporary is dropped \
|
||||
and runs the {DTOR} for {TYPE}",
|
||||
B = borrow_desc,
|
||||
TYPE = type_desc,
|
||||
DTOR = dtor_desc
|
||||
and runs the {dtor_desc} for {type_desc}",
|
||||
);
|
||||
err.span_label(body.source_info(drop_loc).span, message);
|
||||
|
||||
|
|
@ -249,20 +241,16 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"{}requires that `{}` is borrowed for `{}`",
|
||||
"{}requires that `{desc}` is borrowed for `{region_name}`",
|
||||
category.description(),
|
||||
desc,
|
||||
region_name,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"{}requires that {}borrow lasts for `{}`",
|
||||
"{}requires that {borrow_desc}borrow lasts for `{region_name}`",
|
||||
category.description(),
|
||||
borrow_desc,
|
||||
region_name,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
|
@ -296,15 +284,14 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
if region_name.was_named() { region_name.name } else { kw::UnderscoreLifetime };
|
||||
|
||||
let msg = format!(
|
||||
"you can add a bound to the {}to make it last less than `'static` and match `{}`",
|
||||
"you can add a bound to the {}to make it last less than `'static` and match `{region_name}`",
|
||||
category.description(),
|
||||
region_name,
|
||||
);
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
&msg,
|
||||
format!(" + {}", suggestable_name),
|
||||
format!(" + {suggestable_name}"),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,8 +403,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
move_prefix: &str,
|
||||
) {
|
||||
let message = format!(
|
||||
"{}move occurs because {} has type `{}`, which does not implement the `Copy` trait",
|
||||
move_prefix, place_desc, ty,
|
||||
"{move_prefix}move occurs because {place_desc} has type `{ty}`, which does not implement the `Copy` trait",
|
||||
);
|
||||
if let Some(span) = span {
|
||||
err.span_label(span, message);
|
||||
|
|
@ -739,11 +738,11 @@ impl<'tcx> BorrowedContentSource<'tcx> {
|
|||
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||
.ty_adt_def()
|
||||
.and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{name}`")),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
|
||||
.unwrap_or_else(|| format!("dereference of `{ty}`")),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{ty}`"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -769,11 +768,11 @@ impl<'tcx> BorrowedContentSource<'tcx> {
|
|||
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||
.ty_adt_def()
|
||||
.and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{name}`")),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
|
||||
.unwrap_or_else(|| format!("dereference of `{ty}`")),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{ty}`"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1033,7 +1032,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
|
||||
let place_name = self
|
||||
.describe_place(moved_place.as_ref())
|
||||
.map(|n| format!("`{}`", n))
|
||||
.map(|n| format!("`{n}`"))
|
||||
.unwrap_or_else(|| "value".to_owned());
|
||||
match kind {
|
||||
CallKind::FnCall { fn_trait_id, .. }
|
||||
|
|
@ -1042,8 +1041,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{} {}moved due to this call{}",
|
||||
place_name, partially_str, loop_message
|
||||
"{place_name} {partially_str}moved due to this call{loop_message}",
|
||||
),
|
||||
);
|
||||
err.span_note(
|
||||
|
|
@ -1056,8 +1054,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{} {}moved due to usage in operator{}",
|
||||
place_name, partially_str, loop_message
|
||||
"{place_name} {partially_str}moved due to usage in operator{loop_message}",
|
||||
),
|
||||
);
|
||||
if self.fn_self_span_reported.insert(fn_span) {
|
||||
|
|
@ -1089,9 +1086,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_suggestion_verbose(
|
||||
move_span.shrink_to_lo(),
|
||||
&format!(
|
||||
"consider iterating over a slice of the `{}`'s content to \
|
||||
"consider iterating over a slice of the `{ty}`'s content to \
|
||||
avoid moving into the `for` loop",
|
||||
ty,
|
||||
),
|
||||
"&",
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
@ -1101,8 +1097,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{} {}moved due to this implicit call to `.into_iter()`{}",
|
||||
place_name, partially_str, loop_message
|
||||
"{place_name} {partially_str}moved due to this implicit call to `.into_iter()`{loop_message}",
|
||||
),
|
||||
);
|
||||
// If the moved place was a `&mut` ref, then we can
|
||||
|
|
@ -1118,7 +1113,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&format!(
|
||||
"consider creating a fresh reborrow of {} here",
|
||||
self.describe_place(moved_place.as_ref())
|
||||
.map(|n| format!("`{}`", n))
|
||||
.map(|n| format!("`{n}`"))
|
||||
.unwrap_or_else(|| "the mutable reference".to_string()),
|
||||
),
|
||||
"&mut *",
|
||||
|
|
@ -1130,8 +1125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{} {}moved due to this method call{}",
|
||||
place_name, partially_str, loop_message
|
||||
"{place_name} {partially_str}moved due to this method call{loop_message}",
|
||||
),
|
||||
);
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
|
|
@ -1206,7 +1200,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if move_span != span || !loop_message.is_empty() {
|
||||
err.span_label(
|
||||
move_span,
|
||||
format!("value {}moved{} here{}", partially_str, move_msg, loop_message),
|
||||
format!("value {partially_str}moved{move_msg} here{loop_message}"),
|
||||
);
|
||||
}
|
||||
// If the move error occurs due to a loop, don't show
|
||||
|
|
@ -1214,7 +1208,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if loop_message.is_empty() {
|
||||
move_spans.var_span_label(
|
||||
err,
|
||||
format!("variable {}moved due to use{}", partially_str, move_spans.describe()),
|
||||
format!("variable {partially_str}moved due to use{}", move_spans.describe()),
|
||||
"moved",
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
ProjectionElem::Deref,
|
||||
],
|
||||
} => {
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
err.span_label(span, format!("cannot {act}"));
|
||||
|
||||
if let Some(span) = get_mut_span_in_struct_field(
|
||||
self.infcx.tcx,
|
||||
|
|
@ -290,7 +290,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
.unwrap_or(false) =>
|
||||
{
|
||||
let decl = &self.body.local_decls[local];
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
err.span_label(span, format!("cannot {act}"));
|
||||
if let Some(mir::Statement {
|
||||
source_info,
|
||||
kind:
|
||||
|
|
@ -639,7 +639,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => {
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
err.span_label(span, format!("cannot {act}"));
|
||||
|
||||
match opt_source {
|
||||
Some(BorrowedContentSource::OverloadedDeref(ty)) => {
|
||||
|
|
@ -1212,7 +1212,7 @@ fn suggest_ampmut<'tcx>(
|
|||
{
|
||||
let lt_name = &src[1..ws_pos];
|
||||
let ty = &src[ws_pos..];
|
||||
return (true, highlight_span, format!("&{} mut{}", lt_name, ty));
|
||||
return (true, highlight_span, format!("&{lt_name} mut{ty}"));
|
||||
}
|
||||
|
||||
let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
|
||||
|
|
|
|||
|
|
@ -209,14 +209,14 @@ impl OutlivesSuggestionBuilder {
|
|||
let mut diag = if suggested.len() == 1 {
|
||||
mbcx.infcx.tcx.sess.diagnostic().struct_help(&match suggested.last().unwrap() {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| format!("{}", r)).collect();
|
||||
format!("add bound `{}: {}`", a, bs.join(" + "))
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect();
|
||||
format!("add bound `{a}: {}`", bs.join(" + "))
|
||||
}
|
||||
|
||||
SuggestedConstraint::Equal(a, b) => {
|
||||
format!("`{}` and `{}` must be the same: replace one with the other", a, b)
|
||||
format!("`{a}` and `{b}` must be the same: replace one with the other")
|
||||
}
|
||||
SuggestedConstraint::Static(a) => format!("replace `{}` with `'static`", a),
|
||||
SuggestedConstraint::Static(a) => format!("replace `{a}` with `'static`"),
|
||||
})
|
||||
} else {
|
||||
// Create a new diagnostic.
|
||||
|
|
@ -231,18 +231,16 @@ impl OutlivesSuggestionBuilder {
|
|||
for constraint in suggested {
|
||||
match constraint {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> =
|
||||
bs.iter().map(|r| format!("{}", r)).collect();
|
||||
diag.help(&format!("add bound `{}: {}`", a, bs.join(" + ")));
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect();
|
||||
diag.help(&format!("add bound `{a}: {}`", bs.join(" + ")));
|
||||
}
|
||||
SuggestedConstraint::Equal(a, b) => {
|
||||
diag.help(&format!(
|
||||
"`{}` and `{}` must be the same: replace one with the other",
|
||||
a, b
|
||||
"`{a}` and `{b}` must be the same: replace one with the other",
|
||||
));
|
||||
}
|
||||
SuggestedConstraint::Static(a) => {
|
||||
diag.help(&format!("replace `{}` with `'static`", a));
|
||||
diag.help(&format!("replace `{a}` with `'static`"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
);
|
||||
(desc, note)
|
||||
}
|
||||
_ => panic!("Unexpected type {:?}", ty),
|
||||
_ => panic!("Unexpected type {ty:?}"),
|
||||
};
|
||||
diag.note(&format!("requirement occurs because of {desc}",));
|
||||
diag.note(¬e);
|
||||
|
|
@ -725,10 +725,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let lifetime = if f.has_name() { fr_name.name } else { kw::UnderscoreLifetime };
|
||||
|
||||
let arg = match param.param.pat.simple_ident() {
|
||||
Some(simple_ident) => format!("argument `{}`", simple_ident),
|
||||
Some(simple_ident) => format!("argument `{simple_ident}`"),
|
||||
None => "the argument".to_string(),
|
||||
};
|
||||
let captures = format!("captures data from {}", arg);
|
||||
let captures = format!("captures data from {arg}");
|
||||
|
||||
return nice_region_error::suggest_new_region_bound(
|
||||
self.infcx.tcx,
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
/// This is _not_ idempotent. Call `give_region_a_name` when possible.
|
||||
pub(crate) fn synthesize_region_name(&self) -> Symbol {
|
||||
let c = self.next_region_name.replace_with(|counter| *counter + 1);
|
||||
Symbol::intern(&format!("'{:?}", c))
|
||||
Symbol::intern(&format!("'{c:?}"))
|
||||
}
|
||||
|
||||
/// Maps from an internal MIR region vid to something that we can
|
||||
|
|
@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
// programs, so we need to use delay_span_bug here. See #82126.
|
||||
self.infcx.tcx.sess.delay_span_bug(
|
||||
hir_arg.span(),
|
||||
&format!("unmatched subst and hir arg: found {:?} vs {:?}", kind, hir_arg),
|
||||
&format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -783,8 +783,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
} else {
|
||||
span_bug!(
|
||||
hir_ty.span,
|
||||
"bounds from lowered return type of async fn did not match expected format: {:?}",
|
||||
opaque_ty
|
||||
"bounds from lowered return type of async fn did not match expected format: {opaque_ty:?}",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
upvars: &[Upvar<'tcx>],
|
||||
fr: RegionVid,
|
||||
) -> Option<(Option<Symbol>, Span)> {
|
||||
debug!("get_var_name_and_span_for_region(fr={:?})", fr);
|
||||
debug!("get_var_name_and_span_for_region(fr={fr:?})");
|
||||
assert!(self.universal_regions().is_universal_region(fr));
|
||||
|
||||
debug!("get_var_name_and_span_for_region: attempting upvar");
|
||||
|
|
@ -44,10 +44,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
) -> Option<usize> {
|
||||
let upvar_index =
|
||||
self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
|
||||
debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
|
||||
debug!("get_upvar_index_for_region: upvar_ty={upvar_ty:?}");
|
||||
tcx.any_free_region_meets(&upvar_ty, |r| {
|
||||
let r = r.to_region_vid();
|
||||
debug!("get_upvar_index_for_region: r={:?} fr={:?}", r, fr);
|
||||
debug!("get_upvar_index_for_region: r={r:?} fr={fr:?}");
|
||||
r == fr
|
||||
})
|
||||
})?;
|
||||
|
|
@ -55,8 +55,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index);
|
||||
|
||||
debug!(
|
||||
"get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
|
||||
fr, upvar_index, upvar_ty,
|
||||
"get_upvar_index_for_region: found {fr:?} in upvar {upvar_index} which has type {upvar_ty:?}",
|
||||
);
|
||||
|
||||
Some(upvar_index)
|
||||
|
|
@ -71,13 +70,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
upvar_index: usize,
|
||||
) -> (Symbol, Span) {
|
||||
let upvar_hir_id = upvars[upvar_index].place.get_root_variable();
|
||||
debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id);
|
||||
debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}");
|
||||
|
||||
let upvar_name = tcx.hir().name(upvar_hir_id);
|
||||
let upvar_span = tcx.hir().span(upvar_hir_id);
|
||||
debug!(
|
||||
"get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
|
||||
upvar_name, upvar_span
|
||||
"get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}",
|
||||
);
|
||||
|
||||
(upvar_name, upvar_span)
|
||||
|
|
@ -97,15 +95,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let argument_index =
|
||||
self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
|
||||
|arg_ty| {
|
||||
debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty);
|
||||
debug!("get_argument_index_for_region: arg_ty = {arg_ty:?}");
|
||||
tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
|
||||
},
|
||||
)?;
|
||||
|
||||
debug!(
|
||||
"get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
|
||||
fr,
|
||||
argument_index,
|
||||
"get_argument_index_for_region: found {fr:?} in argument {argument_index} which has type {:?}",
|
||||
self.universal_regions().unnormalized_input_tys[argument_index],
|
||||
);
|
||||
|
||||
|
|
@ -122,13 +118,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
) -> (Option<Symbol>, Span) {
|
||||
let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
|
||||
let argument_local = Local::new(implicit_inputs + argument_index + 1);
|
||||
debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
|
||||
debug!("get_argument_name_and_span_for_region: argument_local={argument_local:?}");
|
||||
|
||||
let argument_name = local_names[argument_local];
|
||||
let argument_span = body.local_decls[argument_local].source_info.span;
|
||||
debug!(
|
||||
"get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
|
||||
argument_name, argument_span
|
||||
"get_argument_name_and_span_for_region: argument_name={argument_name:?} argument_span={argument_span:?}",
|
||||
);
|
||||
|
||||
(argument_name, argument_span)
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ fn write_row(
|
|||
) -> Result<(), Box<dyn Error>> {
|
||||
for (index, c) in columns.iter().enumerate() {
|
||||
let tail = if index == columns.len() - 1 { "\n" } else { "\t" };
|
||||
write!(out, "{:?}{}", c.to_string(location_table), tail)?;
|
||||
write!(out, "{:?}{tail}", c.to_string(location_table))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// `self.foo` -- we want to double
|
||||
// check that the location `*self`
|
||||
// is mutable (i.e., this is not a
|
||||
// `Fn` closure). But if that
|
||||
// `Fn` closure). But if that
|
||||
// check succeeds, we want to
|
||||
// *blame* the mutability on
|
||||
// `place` (that is,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ where
|
|||
R1: Copy + Hash + Eq,
|
||||
{
|
||||
/// Remap the "member region" key using `map_fn`, producing a new
|
||||
/// member constraint set. This is used in the NLL code to map from
|
||||
/// member constraint set. This is used in the NLL code to map from
|
||||
/// the original `RegionVid` to an scc index. In some cases, we
|
||||
/// may have multiple `R1` values mapping to the same `R2` key -- that
|
||||
/// is ok, the two sets will be merged.
|
||||
|
|
@ -158,7 +158,7 @@ where
|
|||
}
|
||||
|
||||
/// Iterate down the constraint indices associated with a given
|
||||
/// peek-region. You can then use `choice_regions` and other
|
||||
/// peek-region. You can then use `choice_regions` and other
|
||||
/// methods to access data.
|
||||
pub(crate) fn indices(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ pub(super) fn dump_annotation<'tcx>(
|
|||
|
||||
// When the enclosing function is tagged with `#[rustc_regions]`,
|
||||
// we dump out various bits of state as warnings. This is useful
|
||||
// for verifying that the compiler is behaving as expected. These
|
||||
// for verifying that the compiler is behaving as expected. These
|
||||
// warnings focus on the closure region requirements -- for
|
||||
// viewing the intraprocedural state, the -Zdump-mir output is
|
||||
// better.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||
ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Not) => {
|
||||
// For both derefs of raw pointers and `&T`
|
||||
// references, the original path is `Copy` and
|
||||
// therefore not significant. In particular,
|
||||
// therefore not significant. In particular,
|
||||
// there is nothing the user can do to the
|
||||
// original path that would invalidate the
|
||||
// newly created reference -- and if there
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// enforce the constraint).
|
||||
///
|
||||
/// The current value of `scc` at the time the method is invoked
|
||||
/// is considered a *lower bound*. If possible, we will modify
|
||||
/// is considered a *lower bound*. If possible, we will modify
|
||||
/// the constraint to set it equal to one of the option regions.
|
||||
/// If we make any changes, returns true, else false.
|
||||
#[instrument(skip(self, member_constraint_index), level = "debug")]
|
||||
|
|
@ -959,7 +959,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
//
|
||||
// This is needed because -- particularly in the case
|
||||
// where `ur` is a local bound -- we are sometimes in a
|
||||
// position to prove things that our caller cannot. See
|
||||
// position to prove things that our caller cannot. See
|
||||
// #53570 for an example.
|
||||
if self.eval_verify_bound(infcx, param_env, generic_ty, ur, &type_test.verify_bound) {
|
||||
continue;
|
||||
|
|
@ -2035,7 +2035,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// '5: '6 ('6 is the target)
|
||||
//
|
||||
// Some of those regions are unified with `'6` (in the same
|
||||
// SCC). We want to screen those out. After that point, the
|
||||
// SCC). We want to screen those out. After that point, the
|
||||
// "closest" constraint we have to the end is going to be the
|
||||
// most likely to be the point where the value escapes -- but
|
||||
// we still want to screen for an "interesting" point to
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
return self.tcx.ty_error();
|
||||
}
|
||||
|
||||
// Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs`
|
||||
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
|
||||
// on stable and we'd break that.
|
||||
let OpaqueTyOrigin::TyAlias = origin else {
|
||||
return definition_ty;
|
||||
|
|
@ -318,7 +318,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
|
||||
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
|
||||
// tests to pass
|
||||
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||
let _ = infcx.take_opaque_types();
|
||||
|
||||
if errors.is_empty() {
|
||||
definition_ty
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use std::fmt;
|
||||
|
||||
use rustc_infer::infer::canonical::Canonical;
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::infer::{canonical::Canonical, InferOk};
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::{self, ToPredicate, TypeFoldable};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
|
||||
use rustc_trait_selection::traits::query::Fallible;
|
||||
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||
|
||||
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
|
||||
|
||||
|
|
@ -177,4 +177,74 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
value
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn ascribe_user_type(
|
||||
&mut self,
|
||||
mir_ty: Ty<'tcx>,
|
||||
user_ty: ty::UserType<'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
// FIXME: Ideally MIR types are normalized, but this is not always true.
|
||||
let mir_ty = self.normalize(mir_ty, Locations::All(span));
|
||||
|
||||
self.fully_perform_op(
|
||||
Locations::All(span),
|
||||
ConstraintCategory::Boring,
|
||||
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(mir_ty, user_ty)),
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
span_mirbug!(
|
||||
self,
|
||||
span,
|
||||
"ascribe_user_type `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// *Incorrectly* skips the WF checks we normally do in `ascribe_user_type`.
|
||||
///
|
||||
/// FIXME(#104478, #104477): This is a hack for backward-compatibility.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn ascribe_user_type_skip_wf(
|
||||
&mut self,
|
||||
mir_ty: Ty<'tcx>,
|
||||
user_ty: ty::UserType<'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
let ty::UserType::Ty(user_ty) = user_ty else { bug!() };
|
||||
|
||||
// A fast path for a common case with closure input/output types.
|
||||
if let ty::Infer(_) = user_ty.kind() {
|
||||
self.eq_types(user_ty, mir_ty, Locations::All(span), ConstraintCategory::Boring)
|
||||
.unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let mir_ty = self.normalize(mir_ty, Locations::All(span));
|
||||
let cause = ObligationCause::dummy_with_span(span);
|
||||
let param_env = self.param_env;
|
||||
let op = |infcx: &'_ _| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
let user_ty = ocx.normalize(&cause, param_env, user_ty);
|
||||
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
Ok(InferOk { value: (), obligations: vec![] })
|
||||
};
|
||||
|
||||
self.fully_perform_op(
|
||||
Locations::All(span),
|
||||
ConstraintCategory::Boring,
|
||||
type_op::custom::CustomTypeOp::new(op, || "ascribe_user_type_skip_wf".to_string()),
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
span_mirbug!(
|
||||
self,
|
||||
span,
|
||||
"ascribe_user_type_skip_wf `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||
closure_substs: ty::SubstsRef<'tcx>,
|
||||
) {
|
||||
// Extract the values of the free regions in `closure_substs`
|
||||
// into a vector. These are the regions that we will be
|
||||
// into a vector. These are the regions that we will be
|
||||
// relating to one another.
|
||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||
self.tcx,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ impl UniversalRegionRelations<'_> {
|
|||
let upper_bounds = self.non_local_upper_bounds(fr);
|
||||
|
||||
// In case we find more than one, reduce to one for
|
||||
// convenience. This is to prevent us from generating more
|
||||
// convenience. This is to prevent us from generating more
|
||||
// complex constraints, but it will cause spurious errors.
|
||||
let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds);
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ impl UniversalRegionRelations<'_> {
|
|||
let lower_bounds = self.non_local_bounds(&self.outlives, fr);
|
||||
|
||||
// In case we find more than one, reduce to one for
|
||||
// convenience. This is to prevent us from generating more
|
||||
// convenience. This is to prevent us from generating more
|
||||
// complex constraints, but it will cause spurious errors.
|
||||
let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
use rustc_index::vec::Idx;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::universal_regions::UniversalRegions;
|
||||
|
|
@ -18,6 +18,52 @@ use crate::universal_regions::UniversalRegions;
|
|||
use super::{Locations, TypeChecker};
|
||||
|
||||
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
/// Check explicit closure signature annotation,
|
||||
/// e.g., `|x: FxHashMap<_, &'static u32>| ...`.
|
||||
#[instrument(skip(self, body), level = "debug")]
|
||||
pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) {
|
||||
let mir_def_id = body.source.def_id().expect_local();
|
||||
if !self.tcx().is_closure(mir_def_id.to_def_id()) {
|
||||
return;
|
||||
}
|
||||
let Some(user_provided_poly_sig) =
|
||||
self.tcx().typeck(mir_def_id).user_provided_sigs.get(&mir_def_id)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Instantiate the canonicalized variables from user-provided signature
|
||||
// (e.g., the `_` in the code above) with fresh variables.
|
||||
// Then replace the bound items in the fn sig with fresh variables,
|
||||
// so that they represent the view from "inside" the closure.
|
||||
let user_provided_sig = self
|
||||
.instantiate_canonical_with_fresh_inference_vars(body.span, &user_provided_poly_sig);
|
||||
let user_provided_sig = self.infcx.replace_bound_vars_with_fresh_vars(
|
||||
body.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
user_provided_sig,
|
||||
);
|
||||
|
||||
for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip(
|
||||
// In MIR, closure args begin with an implicit `self`. Skip it!
|
||||
body.args_iter().skip(1).map(|local| &body.local_decls[local]),
|
||||
) {
|
||||
self.ascribe_user_type_skip_wf(
|
||||
arg_decl.ty,
|
||||
ty::UserType::Ty(user_ty),
|
||||
arg_decl.source_info.span,
|
||||
);
|
||||
}
|
||||
|
||||
// If the user explicitly annotated the output type, enforce it.
|
||||
let output_decl = &body.local_decls[RETURN_PLACE];
|
||||
self.ascribe_user_type_skip_wf(
|
||||
output_decl.ty,
|
||||
ty::UserType::Ty(user_provided_sig.output()),
|
||||
output_decl.source_info.span,
|
||||
);
|
||||
}
|
||||
|
||||
#[instrument(skip(self, body, universal_regions), level = "debug")]
|
||||
pub(super) fn equate_inputs_and_outputs(
|
||||
&mut self,
|
||||
|
|
@ -31,39 +77,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
debug!(?normalized_output_ty);
|
||||
debug!(?normalized_input_tys);
|
||||
|
||||
let mir_def_id = body.source.def_id().expect_local();
|
||||
|
||||
// If the user explicitly annotated the input types, extract
|
||||
// those.
|
||||
//
|
||||
// e.g., `|x: FxHashMap<_, &'static u32>| ...`
|
||||
let user_provided_sig = if !self.tcx().is_closure(mir_def_id.to_def_id()) {
|
||||
None
|
||||
} else {
|
||||
let typeck_results = self.tcx().typeck(mir_def_id);
|
||||
|
||||
typeck_results.user_provided_sigs.get(&mir_def_id).map(|user_provided_poly_sig| {
|
||||
// Instantiate the canonicalized variables from
|
||||
// user-provided signature (e.g., the `_` in the code
|
||||
// above) with fresh variables.
|
||||
let poly_sig = self.instantiate_canonical_with_fresh_inference_vars(
|
||||
body.span,
|
||||
&user_provided_poly_sig,
|
||||
);
|
||||
|
||||
// Replace the bound items in the fn sig with fresh
|
||||
// variables, so that they represent the view from
|
||||
// "inside" the closure.
|
||||
self.infcx.replace_bound_vars_with_fresh_vars(
|
||||
body.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
poly_sig,
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
debug!(?normalized_input_tys, ?body.local_decls);
|
||||
|
||||
// Equate expected input tys with those in the MIR.
|
||||
for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() {
|
||||
if argument_index + 1 >= body.local_decls.len() {
|
||||
|
|
@ -86,28 +99,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if let Some(user_provided_sig) = user_provided_sig {
|
||||
for (argument_index, &user_provided_input_ty) in
|
||||
user_provided_sig.inputs().iter().enumerate()
|
||||
{
|
||||
// In MIR, closures begin an implicit `self`, so
|
||||
// argument N is stored in local N+2.
|
||||
let local = Local::new(argument_index + 2);
|
||||
let mir_input_ty = body.local_decls[local].ty;
|
||||
let mir_input_span = body.local_decls[local].source_info.span;
|
||||
|
||||
// If the user explicitly annotated the input types, enforce those.
|
||||
let user_provided_input_ty =
|
||||
self.normalize(user_provided_input_ty, Locations::All(mir_input_span));
|
||||
|
||||
self.equate_normalized_input_or_output(
|
||||
user_provided_input_ty,
|
||||
mir_input_ty,
|
||||
mir_input_span,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
|
||||
body.yield_ty(),
|
||||
|
|
@ -153,29 +144,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
terr
|
||||
);
|
||||
};
|
||||
|
||||
// If the user explicitly annotated the output types, enforce those.
|
||||
// Note that this only happens for closures.
|
||||
if let Some(user_provided_sig) = user_provided_sig {
|
||||
let user_provided_output_ty = user_provided_sig.output();
|
||||
let user_provided_output_ty =
|
||||
self.normalize(user_provided_output_ty, Locations::All(output_span));
|
||||
if let Err(err) = self.eq_types(
|
||||
user_provided_output_ty,
|
||||
mir_output_ty,
|
||||
Locations::All(output_span),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
Location::START,
|
||||
"equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
|
||||
mir_output_ty,
|
||||
user_provided_output_ty,
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
debug_assert!(self.drop_live_at.contains(term_point));
|
||||
|
||||
// Otherwise, scan backwards through the statements in the
|
||||
// block. One of them may be either a definition or use
|
||||
// block. One of them may be either a definition or use
|
||||
// live point.
|
||||
let term_location = self.cx.elements.to_location(term_point);
|
||||
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ use rustc_middle::ty::{
|
|||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_trait_selection::traits::query::type_op;
|
||||
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
|
||||
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||
|
|
@ -197,6 +196,8 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
}
|
||||
|
||||
checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
|
||||
checker.check_signature_annotation(&body);
|
||||
|
||||
liveness::generate(
|
||||
&mut checker,
|
||||
body,
|
||||
|
|
@ -208,7 +209,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
);
|
||||
|
||||
translate_outlives_facts(&mut checker);
|
||||
let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||
let opaque_type_values = infcx.take_opaque_types();
|
||||
|
||||
let opaque_type_values = opaque_type_values
|
||||
.into_iter()
|
||||
|
|
@ -391,23 +392,14 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
check_err(self, promoted_body, ty, promoted_ty);
|
||||
}
|
||||
} else {
|
||||
if let Err(terr) = self.cx.fully_perform_op(
|
||||
locations,
|
||||
ConstraintCategory::Boring,
|
||||
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
|
||||
constant.literal.ty(),
|
||||
self.cx.ascribe_user_type(
|
||||
constant.literal.ty(),
|
||||
UserType::TypeOf(
|
||||
uv.def.did,
|
||||
UserSubsts { substs: uv.substs, user_self_ty: None },
|
||||
)),
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
constant,
|
||||
"bad constant type {:?} ({:?})",
|
||||
constant,
|
||||
terr
|
||||
);
|
||||
}
|
||||
),
|
||||
locations.span(&self.cx.body),
|
||||
);
|
||||
}
|
||||
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
||||
let unnormalized_ty = tcx.type_of(static_def_id);
|
||||
|
|
@ -1041,58 +1033,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
debug!(?self.user_type_annotations);
|
||||
for user_annotation in self.user_type_annotations {
|
||||
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
|
||||
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
|
||||
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
|
||||
debug!(?annotation);
|
||||
match annotation {
|
||||
UserType::Ty(mut ty) => {
|
||||
ty = self.normalize(ty, Locations::All(span));
|
||||
|
||||
if let Err(terr) = self.eq_types(
|
||||
ty,
|
||||
inferred_ty,
|
||||
Locations::All(span),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
user_annotation,
|
||||
"bad user type ({:?} = {:?}): {:?}",
|
||||
ty,
|
||||
inferred_ty,
|
||||
terr
|
||||
);
|
||||
}
|
||||
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())),
|
||||
Locations::All(span),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
);
|
||||
}
|
||||
UserType::TypeOf(def_id, user_substs) => {
|
||||
if let Err(terr) = self.fully_perform_op(
|
||||
Locations::All(span),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
|
||||
inferred_ty,
|
||||
def_id,
|
||||
user_substs,
|
||||
)),
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
user_annotation,
|
||||
"bad user type AscribeUserType({:?}, {:?} {:?}, type_of={:?}): {:?}",
|
||||
inferred_ty,
|
||||
def_id,
|
||||
user_substs,
|
||||
self.tcx().type_of(def_id),
|
||||
terr,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.ascribe_user_type(inferred_ty, annotation, span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1723,7 +1665,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Erase the regions from `ty` to get a global type. The
|
||||
// Erase the regions from `ty` to get a global type. The
|
||||
// `Sized` bound in no way depends on precise regions, so this
|
||||
// shouldn't affect `is_sized`.
|
||||
let erased_ty = tcx.erase_regions(ty);
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||
|
||||
// The "inputs" of the closure in the
|
||||
// signature appear as a tuple. The MIR side
|
||||
// signature appear as a tuple. The MIR side
|
||||
// flattens this tuple.
|
||||
let (&output, tuplized_inputs) =
|
||||
inputs_and_output.skip_binder().split_last().unwrap();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub fn expand_deriving_clone(
|
|||
// some additional `AssertParamIsClone` assertions.
|
||||
//
|
||||
// We can use the simple form if either of the following are true.
|
||||
// - The type derives Copy and there are no generic parameters. (If we
|
||||
// - The type derives Copy and there are no generic parameters. (If we
|
||||
// used the simple form with generics, we'd have to bound the generics
|
||||
// with Clone + Copy, and then there'd be no Clone impl at all if the
|
||||
// user fills in something that is Clone but not Copy. After
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// The compiler code necessary to support the env! extension. Eventually this
|
||||
// The compiler code necessary to support the env! extension. Eventually this
|
||||
// should all get sucked into either the compiler syntax extension plugin
|
||||
// interface.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ fn report_missing_placeholders(
|
|||
if detect_foreign_fmt {
|
||||
use super::format_foreign as foreign;
|
||||
|
||||
// The set of foreign substitutions we've explained. This prevents spamming the user
|
||||
// The set of foreign substitutions we've explained. This prevents spamming the user
|
||||
// with `%d should be written as {}` over and over again.
|
||||
let mut explained = FxHashSet::default();
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ pub(crate) mod printf {
|
|||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Num {
|
||||
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
|
||||
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
||||
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
||||
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
|
||||
// with more precision, than 32 thousand positions which is so wide it couldn't possibly fit
|
||||
// on a screen.
|
||||
|
|
|
|||
|
|
@ -10,118 +10,118 @@ pushd rust
|
|||
|
||||
command -v rg >/dev/null 2>&1 || cargo install ripgrep
|
||||
|
||||
rm -r src/test/ui/{extern/,unsized-locals/,lto/,linkage*} || true
|
||||
for test in $(rg --files-with-matches "lto|// needs-asm-support|// needs-unwind" src/test/{ui,incremental}); do
|
||||
rm -r tests/ui/{extern/,unsized-locals/,lto/,linkage*} || true
|
||||
for test in $(rg --files-with-matches "lto|// needs-asm-support|// needs-unwind" tests/{ui,incremental}); do
|
||||
rm $test
|
||||
done
|
||||
|
||||
for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do
|
||||
for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" tests/ui); do
|
||||
rm $test
|
||||
done
|
||||
|
||||
git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||
git checkout -- src/test/ui/proc-macro/pretty-print-hack/
|
||||
git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||
git checkout -- tests/ui/proc-macro/pretty-print-hack/
|
||||
|
||||
# missing features
|
||||
# ================
|
||||
|
||||
# requires stack unwinding
|
||||
rm src/test/incremental/change_crate_dep_kind.rs
|
||||
rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101)
|
||||
rm tests/incremental/change_crate_dep_kind.rs
|
||||
rm tests/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101)
|
||||
|
||||
# requires compiling with -Cpanic=unwind
|
||||
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
|
||||
rm -r src/test/run-make/test-benches
|
||||
rm -r tests/ui/macros/rfc-2011-nicer-assert-messages/
|
||||
rm -r tests/run-make/test-benches
|
||||
|
||||
# vendor intrinsics
|
||||
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
||||
rm src/test/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics
|
||||
rm src/test/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
|
||||
rm src/test/ui/simd/intrinsic/generic-bitmask-pass.rs # simd_bitmask unimplemented
|
||||
rm src/test/ui/simd/intrinsic/generic-as.rs # simd_as unimplemented
|
||||
rm src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs # simd_saturating_add unimplemented
|
||||
rm src/test/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented
|
||||
rm src/test/ui/simd/intrinsic/generic-gather-pass.rs # simd_gather unimplemented
|
||||
rm src/test/ui/simd/intrinsic/generic-select-pass.rs # simd_select_bitmask unimplemented
|
||||
rm src/test/ui/simd/issue-85915-simd-ptrs.rs # simd_gather unimplemented
|
||||
rm src/test/ui/simd/issue-89193.rs # simd_gather unimplemented
|
||||
rm src/test/ui/simd/simd-bitmask.rs # simd_bitmask unimplemented
|
||||
rm tests/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
||||
rm tests/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics
|
||||
rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
|
||||
rm tests/ui/simd/intrinsic/generic-bitmask-pass.rs # simd_bitmask unimplemented
|
||||
rm tests/ui/simd/intrinsic/generic-as.rs # simd_as unimplemented
|
||||
rm tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs # simd_saturating_add unimplemented
|
||||
rm tests/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented
|
||||
rm tests/ui/simd/intrinsic/generic-gather-pass.rs # simd_gather unimplemented
|
||||
rm tests/ui/simd/intrinsic/generic-select-pass.rs # simd_select_bitmask unimplemented
|
||||
rm tests/ui/simd/issue-85915-simd-ptrs.rs # simd_gather unimplemented
|
||||
rm tests/ui/simd/issue-89193.rs # simd_gather unimplemented
|
||||
rm tests/ui/simd/simd-bitmask.rs # simd_bitmask unimplemented
|
||||
|
||||
# exotic linkages
|
||||
rm src/test/ui/issues/issue-33992.rs # unsupported linkages
|
||||
rm src/test/incremental/hashes/function_interfaces.rs # same
|
||||
rm src/test/incremental/hashes/statics.rs # same
|
||||
rm tests/ui/issues/issue-33992.rs # unsupported linkages
|
||||
rm tests/incremental/hashes/function_interfaces.rs # same
|
||||
rm tests/incremental/hashes/statics.rs # same
|
||||
|
||||
# variadic arguments
|
||||
rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
|
||||
rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support
|
||||
rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
|
||||
rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support
|
||||
|
||||
# unsized locals
|
||||
rm -r src/test/run-pass-valgrind/unsized-locals
|
||||
rm -r tests/run-pass-valgrind/unsized-locals
|
||||
|
||||
# misc unimplemented things
|
||||
rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
|
||||
rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented
|
||||
rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
|
||||
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
||||
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
|
||||
rm src/test/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
|
||||
rm -r src/test/run-make/repr128-dwarf # debuginfo test
|
||||
rm src/test/codegen-units/item-collection/asm-sym.rs # requires support for sym in asm!()
|
||||
rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
|
||||
rm tests/ui/target-feature/missing-plusminus.rs # error not implemented
|
||||
rm tests/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
|
||||
rm -r tests/run-make/emit-named-files # requires full --emit support
|
||||
rm tests/ui/abi/stack-probes.rs # stack probes not yet implemented
|
||||
rm tests/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
|
||||
rm -r tests/run-make/repr128-dwarf # debuginfo test
|
||||
rm tests/codegen-units/item-collection/asm-sym.rs # requires support for sym in asm!()
|
||||
|
||||
# optimization tests
|
||||
# ==================
|
||||
rm src/test/ui/codegen/issue-28950.rs # depends on stack size optimizations
|
||||
rm src/test/ui/codegen/init-large-type.rs # same
|
||||
rm src/test/ui/issues/issue-40883.rs # same
|
||||
rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
|
||||
rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations
|
||||
rm tests/ui/codegen/init-large-type.rs # same
|
||||
rm tests/ui/issues/issue-40883.rs # same
|
||||
rm -r tests/run-make/fmt-write-bloat/ # tests an optimization
|
||||
|
||||
# backend specific tests
|
||||
# ======================
|
||||
rm src/test/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
|
||||
rm src/test/ui/abi/stack-protector.rs # requires stack protector support
|
||||
rm tests/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
|
||||
rm tests/ui/abi/stack-protector.rs # requires stack protector support
|
||||
|
||||
# giving different but possibly correct results
|
||||
# =============================================
|
||||
rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
||||
rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
|
||||
rm src/test/ui/consts/issue-33537.rs # same
|
||||
rm src/test/ui/layout/valid_range_oob.rs # different ICE message
|
||||
rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
||||
rm tests/ui/mir/mir_raw_fat_ptr.rs # same
|
||||
rm tests/ui/consts/issue-33537.rs # same
|
||||
rm tests/ui/layout/valid_range_oob.rs # different ICE message
|
||||
|
||||
# doesn't work due to the way the rustc test suite is invoked.
|
||||
# should work when using ./x.py test the way it is intended
|
||||
# ============================================================
|
||||
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in dist/bin/
|
||||
rm -r src/test/run-make/unstable-flag-required # same
|
||||
rm -r src/test/run-make/rustdoc-* # same
|
||||
rm -r src/test/run-make/issue-88756-default-output # same
|
||||
rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
||||
rm -r src/test/ui/consts/missing_span_in_backtrace.rs # expects sysroot source to be elsewhere
|
||||
rm -r tests/run-make/emit-shared-files # requires the rustdoc executable in dist/bin/
|
||||
rm -r tests/run-make/unstable-flag-required # same
|
||||
rm -r tests/run-make/rustdoc-* # same
|
||||
rm -r tests/run-make/issue-88756-default-output # same
|
||||
rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
||||
rm -r tests/ui/consts/missing_span_in_backtrace.rs # expects sysroot source to be elsewhere
|
||||
|
||||
# genuine bugs
|
||||
# ============
|
||||
rm src/test/incremental/spike-neg1.rs # errors out for some reason
|
||||
rm src/test/incremental/spike-neg2.rs # same
|
||||
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
|
||||
rm src/test/ui/mir/ssa-analysis-regression-50041.rs # produces ICE
|
||||
rm src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE
|
||||
rm tests/incremental/spike-neg1.rs # errors out for some reason
|
||||
rm tests/incremental/spike-neg2.rs # same
|
||||
rm tests/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
|
||||
rm tests/ui/mir/ssa-analysis-regression-50041.rs # produces ICE
|
||||
rm tests/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE
|
||||
|
||||
rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
|
||||
rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
|
||||
|
||||
rm src/test/ui/runtime/out-of-stack.rs # SIGSEGV instead of SIGABRT for some reason (#1301)
|
||||
rm tests/ui/runtime/out-of-stack.rs # SIGSEGV instead of SIGABRT for some reason (#1301)
|
||||
|
||||
# bugs in the test suite
|
||||
# ======================
|
||||
rm src/test/ui/backtrace.rs # TODO warning
|
||||
rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
|
||||
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
|
||||
rm tests/ui/backtrace.rs # TODO warning
|
||||
rm tests/ui/simple_global_asm.rs # TODO add needs-asm-support
|
||||
rm tests/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
|
||||
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
|
||||
rm -r src/test/run-make/native-link-modifier-bundle
|
||||
rm src/test/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
|
||||
rm src/test/ui/dyn-star/dispatch-on-pin-mut.rs # TODO failed assertion in vtable::get_ptr_and_method_ref
|
||||
rm -r tests/run-make/native-link-modifier-bundle
|
||||
rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
|
||||
rm tests/ui/dyn-star/dispatch-on-pin-mut.rs # TODO failed assertion in vtable::get_ptr_and_method_ref
|
||||
|
||||
rm src/test/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
||||
rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
||||
|
||||
echo "[TEST] rustc test suite"
|
||||
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
|
||||
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 tests/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
|
||||
popd
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ fn data_id_for_static(
|
|||
|
||||
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
||||
// Declare an internal global `extern_with_linkage_foo` which
|
||||
// is initialized with the address of `foo`. If `foo` is
|
||||
// is initialized with the address of `foo`. If `foo` is
|
||||
// discarded during linking (for example, if `foo` has weak
|
||||
// linkage and there are no definitions), then
|
||||
// `extern_with_linkage_foo` will instead be initialized to
|
||||
|
|
|
|||
|
|
@ -253,25 +253,25 @@ rustc = "$HOME/.rustup/toolchains/$rust_toolchain-$TARGET_TRIPLE/bin/rustc"
|
|||
EOF
|
||||
|
||||
rustc -V | cut -d' ' -f3 | tr -d '('
|
||||
git checkout $(rustc -V | cut -d' ' -f3 | tr -d '(') src/test
|
||||
git checkout $(rustc -V | cut -d' ' -f3 | tr -d '(') tests
|
||||
|
||||
for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do
|
||||
for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" tests/ui); do
|
||||
rm $test
|
||||
done
|
||||
|
||||
git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||
git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||
|
||||
rm -r src/test/ui/{abi*,extern/,panic-runtime/,panics/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,borrowck/,test*,*lto*.rs} || true
|
||||
for test in $(rg --files-with-matches "catch_unwind|should_panic|thread|lto" src/test/ui); do
|
||||
rm -r tests/ui/{abi*,extern/,panic-runtime/,panics/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,borrowck/,test*,*lto*.rs} || true
|
||||
for test in $(rg --files-with-matches "catch_unwind|should_panic|thread|lto" tests/ui); do
|
||||
rm $test
|
||||
done
|
||||
git checkout src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
|
||||
git checkout src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
|
||||
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
|
||||
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
|
||||
|
||||
RUSTC_ARGS="-Zpanic-abort-tests -Csymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot -Cpanic=abort"
|
||||
|
||||
echo "[TEST] rustc test suite"
|
||||
COMPILETEST_FORCE_STAGE0=1 ./x.py test --run always --stage 0 src/test/ui/ --rustc-args "$RUSTC_ARGS"
|
||||
COMPILETEST_FORCE_STAGE0=1 ./x.py test --run always --stage 0 tests/ui/ --rustc-args "$RUSTC_ARGS"
|
||||
}
|
||||
|
||||
function clean_ui_tests() {
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||
bx.store(val, cast_dst, self.layout.align.abi);
|
||||
} else {
|
||||
// The actual return type is a struct, but the ABI
|
||||
// adaptation code has cast it into some scalar type. The
|
||||
// adaptation code has cast it into some scalar type. The
|
||||
// code that follows is the only reliable way I have
|
||||
// found to do a transform like i64 -> {i32,i32}.
|
||||
// Basically we dump the data onto the stack then memcpy it.
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ pub(crate) fn inline_asm_call<'ll>(
|
|||
};
|
||||
|
||||
// Store mark in a metadata node so we can map LLVM errors
|
||||
// back to source locations. See #17552.
|
||||
// back to source locations. See #17552.
|
||||
let key = "srcloc";
|
||||
let kind = llvm::LLVMGetMDKindIDInContext(
|
||||
bx.llcx,
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
// The binutils linker used on -windows-gnu targets cannot read the import
|
||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
||||
// that loaded but crashed with an AV upon calling one of the imported
|
||||
// functions. Therefore, use binutils to create the import library instead,
|
||||
// functions. Therefore, use binutils to create the import library instead,
|
||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
||||
let def_file_path =
|
||||
tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");
|
||||
|
|
@ -219,7 +219,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
|
||||
// All import names are Rust identifiers and therefore cannot contain \0 characters.
|
||||
// FIXME: when support for #[link_name] is implemented, ensure that the import names
|
||||
// still don't contain any \0 characters. Also need to check that the names don't
|
||||
// still don't contain any \0 characters. Also need to check that the names don't
|
||||
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
|
||||
// in definition files.
|
||||
let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
|
||||
|
|
@ -433,7 +433,7 @@ fn find_binutils_dlltool(sess: &Session) -> OsString {
|
|||
}
|
||||
|
||||
// The user didn't specify the location of the dlltool binary, and we weren't able
|
||||
// to find the appropriate one on the PATH. Just return the name of the tool
|
||||
// to find the appropriate one on the PATH. Just return the name of the tool
|
||||
// and let the invocation fail with a hopefully useful error message.
|
||||
tool_name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -909,7 +909,7 @@ unsafe fn embed_bitcode(
|
|||
|
||||
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
|
||||
// This is required to satisfy `dllimport` references to static data in .rlibs
|
||||
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||
// code references on its own.
|
||||
// See #26591, #27438
|
||||
fn create_msvc_imps(
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
|||
let llptrty = fn_abi.ptr_to_llvm_type(cx);
|
||||
|
||||
// This is subtle and surprising, but sometimes we have to bitcast
|
||||
// the resulting fn pointer. The reason has to do with external
|
||||
// functions. If you have two crates that both bind the same C
|
||||
// the resulting fn pointer. The reason has to do with external
|
||||
// functions. If you have two crates that both bind the same C
|
||||
// library, they may not use precisely the same types: for
|
||||
// example, they will probably each declare their own structs,
|
||||
// which are distinct types from LLVM's point of view (nominal
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ pub fn codegen_static_initializer<'ll, 'tcx>(
|
|||
fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {
|
||||
// The target may require greater alignment for globals than the type does.
|
||||
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
|
||||
// which can force it to be smaller. Rust doesn't support this yet.
|
||||
// which can force it to be smaller. Rust doesn't support this yet.
|
||||
if let Some(min) = cx.sess().target.min_global_align {
|
||||
match Align::from_bits(min) {
|
||||
Ok(min) => align = align.max(min),
|
||||
|
|
@ -171,7 +171,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
|
|||
llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage));
|
||||
|
||||
// Declare an internal global `extern_with_linkage_foo` which
|
||||
// is initialized with the address of `foo`. If `foo` is
|
||||
// is initialized with the address of `foo`. If `foo` is
|
||||
// discarded during linking (for example, if `foo` has weak
|
||||
// linkage and there are no definitions), then
|
||||
// `extern_with_linkage_foo` will instead be initialized to
|
||||
|
|
|
|||
|
|
@ -654,7 +654,7 @@ fn codegen_gnu_try<'ll>(
|
|||
// Type indicator for the exception being thrown.
|
||||
//
|
||||
// The first value in this tuple is a pointer to the exception object
|
||||
// being thrown. The second value is a "selector" indicating which of
|
||||
// being thrown. The second value is a "selector" indicating which of
|
||||
// the landing pad clauses the exception's type had been matched to.
|
||||
// rust_try ignores the selector.
|
||||
bx.switch_to_block(catch);
|
||||
|
|
@ -718,7 +718,7 @@ fn codegen_emcc_try<'ll>(
|
|||
// Type indicator for the exception being thrown.
|
||||
//
|
||||
// The first value in this tuple is a pointer to the exception object
|
||||
// being thrown. The second value is a "selector" indicating which of
|
||||
// being thrown. The second value is a "selector" indicating which of
|
||||
// the landing pad clauses the exception's type had been matched to.
|
||||
bx.switch_to_block(catch);
|
||||
let tydesc = bx.eh_catch_typeinfo();
|
||||
|
|
|
|||
|
|
@ -352,10 +352,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
|||
let scalar = [a, b][index];
|
||||
|
||||
// Make sure to return the same type `immediate_llvm_type` would when
|
||||
// dealing with an immediate pair. This means that `(bool, bool)` is
|
||||
// dealing with an immediate pair. This means that `(bool, bool)` is
|
||||
// effectively represented as `{i8, i8}` in memory and two `i1`s as an
|
||||
// immediate, just like `bool` is typically `i8` in memory and only `i1`
|
||||
// when immediate. We need to load/store `bool` as `i8` to avoid
|
||||
// when immediate. We need to load/store `bool` as `i8` to avoid
|
||||
// crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
|
||||
if immediate && scalar.is_bool() {
|
||||
return cx.type_i1();
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ fn link_rlib<'a>(
|
|||
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
|
||||
///
|
||||
/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
|
||||
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
|
||||
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
|
||||
/// linker appears to expect only a single import library for each library used, so we need to
|
||||
/// collate the symbols together by library name before generating the import libraries.
|
||||
fn collate_raw_dylibs<'a, 'b>(
|
||||
|
|
@ -1197,7 +1197,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
|
||||
// On historical Solaris systems, "cc" may have
|
||||
// been Sun Studio, which is not flag-compatible
|
||||
// with "gcc". This history casts a long shadow,
|
||||
// with "gcc". This history casts a long shadow,
|
||||
// and many modern illumos distributions today
|
||||
// ship GCC as "gcc" without also making it
|
||||
// available as "cc".
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
// link times negatively.
|
||||
//
|
||||
// -dead_strip can't be part of the pre_link_args because it's also used
|
||||
// for partial linking when using multiple codegen units (-r). So we
|
||||
// for partial linking when using multiple codegen units (-r). So we
|
||||
// insert it here.
|
||||
if self.sess.target.is_like_osx {
|
||||
self.linker_arg("-dead_strip");
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub struct ModuleConfig {
|
|||
pub emit_thin_lto: bool,
|
||||
pub bc_cmdline: String,
|
||||
|
||||
// Miscellaneous flags. These are mostly copied from command-line
|
||||
// Miscellaneous flags. These are mostly copied from command-line
|
||||
// options.
|
||||
pub verify_llvm_ir: bool,
|
||||
pub no_prepopulate_passes: bool,
|
||||
|
|
@ -538,7 +538,7 @@ fn produce_final_output_artifacts(
|
|||
|
||||
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
|
||||
if compiled_modules.modules.len() == 1 {
|
||||
// 1) Only one codegen unit. In this case it's no difficulty
|
||||
// 1) Only one codegen unit. In this case it's no difficulty
|
||||
// to copy `foo.0.x` to `foo.x`.
|
||||
let module_name = Some(&compiled_modules.modules[0].name[..]);
|
||||
let path = crate_output.temp_path(output_type, module_name);
|
||||
|
|
@ -557,15 +557,15 @@ fn produce_final_output_artifacts(
|
|||
.to_owned();
|
||||
|
||||
if crate_output.outputs.contains_key(&output_type) {
|
||||
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
||||
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.emit_warning(errors::IgnoringEmitPath { extension });
|
||||
} else if crate_output.single_output_file.is_some() {
|
||||
// 3) Multiple codegen units, with `-o some_name`. We have
|
||||
// 3) Multiple codegen units, with `-o some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.emit_warning(errors::IgnoringOutput { extension });
|
||||
} else {
|
||||
// 4) Multiple codegen units, but no explicit name. We
|
||||
// 4) Multiple codegen units, but no explicit name. We
|
||||
// just leave the `foo.0.x` files in place.
|
||||
// (We don't have to do any work in this case.)
|
||||
}
|
||||
|
|
@ -579,7 +579,7 @@ fn produce_final_output_artifacts(
|
|||
match *output_type {
|
||||
OutputType::Bitcode => {
|
||||
user_wants_bitcode = true;
|
||||
// Copy to .bc, but always keep the .0.bc. There is a later
|
||||
// Copy to .bc, but always keep the .0.bc. There is a later
|
||||
// check to figure out if we should delete .0.bc files, or keep
|
||||
// them for making an rlib.
|
||||
copy_if_one_unit(OutputType::Bitcode, true);
|
||||
|
|
@ -611,7 +611,7 @@ fn produce_final_output_artifacts(
|
|||
// `-C save-temps` or `--emit=` flags).
|
||||
|
||||
if !sess.opts.cg.save_temps {
|
||||
// Remove the temporary .#module-name#.o objects. If the user didn't
|
||||
// Remove the temporary .#module-name#.o objects. If the user didn't
|
||||
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
||||
// needed for building an rlib, then we must remove .#module-name#.bc as
|
||||
// well.
|
||||
|
|
@ -1098,7 +1098,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
// There are a few environmental pre-conditions that shape how the system
|
||||
// is set up:
|
||||
//
|
||||
// - Error reporting only can happen on the main thread because that's the
|
||||
// - Error reporting can only happen on the main thread because that's the
|
||||
// only place where we have access to the compiler `Session`.
|
||||
// - LLVM work can be done on any thread.
|
||||
// - Codegen can only happen on the main thread.
|
||||
|
|
@ -1110,16 +1110,16 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
// Error Reporting
|
||||
// ===============
|
||||
// The error reporting restriction is handled separately from the rest: We
|
||||
// set up a `SharedEmitter` the holds an open channel to the main thread.
|
||||
// set up a `SharedEmitter` that holds an open channel to the main thread.
|
||||
// When an error occurs on any thread, the shared emitter will send the
|
||||
// error message to the receiver main thread (`SharedEmitterMain`). The
|
||||
// main thread will periodically query this error message queue and emit
|
||||
// any error messages it has received. It might even abort compilation if
|
||||
// has received a fatal error. In this case we rely on all other threads
|
||||
// it has received a fatal error. In this case we rely on all other threads
|
||||
// being torn down automatically with the main thread.
|
||||
// Since the main thread will often be busy doing codegen work, error
|
||||
// reporting will be somewhat delayed, since the message queue can only be
|
||||
// checked in between to work packages.
|
||||
// checked in between two work packages.
|
||||
//
|
||||
// Work Processing Infrastructure
|
||||
// ==============================
|
||||
|
|
@ -1133,7 +1133,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
// thread about what work to do when, and it will spawn off LLVM worker
|
||||
// threads as open LLVM WorkItems become available.
|
||||
//
|
||||
// The job of the main thread is to codegen CGUs into LLVM work package
|
||||
// The job of the main thread is to codegen CGUs into LLVM work packages
|
||||
// (since the main thread is the only thread that can do this). The main
|
||||
// thread will block until it receives a message from the coordinator, upon
|
||||
// which it will codegen one CGU, send it to the coordinator and block
|
||||
|
|
@ -1142,10 +1142,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
//
|
||||
// The coordinator keeps a queue of LLVM WorkItems, and when a `Token` is
|
||||
// available, it will spawn off a new LLVM worker thread and let it process
|
||||
// that a WorkItem. When a LLVM worker thread is done with its WorkItem,
|
||||
// a WorkItem. When a LLVM worker thread is done with its WorkItem,
|
||||
// it will just shut down, which also frees all resources associated with
|
||||
// the given LLVM module, and sends a message to the coordinator that the
|
||||
// has been completed.
|
||||
// WorkItem has been completed.
|
||||
//
|
||||
// Work Scheduling
|
||||
// ===============
|
||||
|
|
@ -1165,7 +1165,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
//
|
||||
// Doing LLVM Work on the Main Thread
|
||||
// ----------------------------------
|
||||
// Since the main thread owns the compiler processes implicit `Token`, it is
|
||||
// Since the main thread owns the compiler process's implicit `Token`, it is
|
||||
// wasteful to keep it blocked without doing any work. Therefore, what we do
|
||||
// in this case is: We spawn off an additional LLVM worker thread that helps
|
||||
// reduce the queue. The work it is doing corresponds to the implicit
|
||||
|
|
@ -1216,7 +1216,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
// ------------------------------
|
||||
//
|
||||
// The final job the coordinator thread is responsible for is managing LTO
|
||||
// and how that works. When LTO is requested what we'll to is collect all
|
||||
// and how that works. When LTO is requested what we'll do is collect all
|
||||
// optimized LLVM modules into a local vector on the coordinator. Once all
|
||||
// modules have been codegened and optimized we hand this to the `lto`
|
||||
// module for further optimization. The `lto` module will return back a list
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
(
|
||||
&ty::Dynamic(ref data_a, _, src_dyn_kind),
|
||||
&ty::Dynamic(ref data_b, _, target_dyn_kind),
|
||||
) => {
|
||||
assert_eq!(src_dyn_kind, target_dyn_kind);
|
||||
|
||||
) if src_dyn_kind == target_dyn_kind => {
|
||||
let old_info =
|
||||
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
|
||||
if data_a.principal_def_id() == data_b.principal_def_id() {
|
||||
|
|
|
|||
|
|
@ -658,13 +658,13 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
|||
sole_meta_list
|
||||
{
|
||||
// According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
|
||||
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
||||
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
||||
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
|
||||
// to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
|
||||
//
|
||||
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for this:
|
||||
// both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
|
||||
// a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
|
||||
// a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
|
||||
// for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
|
||||
// library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I don't know yet
|
||||
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
|
||||
|
|
|
|||
|
|
@ -261,6 +261,9 @@ impl CleanupKind {
|
|||
}
|
||||
}
|
||||
|
||||
/// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only
|
||||
/// branch to itself or to its parent. Luckily, the code we generates matches this pattern.
|
||||
/// Recover that structure in an analyze pass.
|
||||
pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
|
||||
fn discover_masters<'tcx>(
|
||||
result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ pub struct DebugScope<S, L> {
|
|||
}
|
||||
|
||||
impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
|
||||
/// DILocations inherit source file name from the parent DIScope. Due to macro expansions
|
||||
/// DILocations inherit source file name from the parent DIScope. Due to macro expansions
|
||||
/// it may so happen that the current span belongs to a different file than the DIScope
|
||||
/// corresponding to span's containing source scope. If so, we need to create a DIScope
|
||||
/// corresponding to span's containing source scope. If so, we need to create a DIScope
|
||||
/// "extension" into that file.
|
||||
pub fn adjust_dbg_scope_for_span<Cx: CodegenMethods<'tcx, DIScope = S, DILocation = L>>(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
|||
("bmi2", None),
|
||||
("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
|
||||
("ermsb", Some(sym::ermsb_target_feature)),
|
||||
("f16c", Some(sym::f16c_target_feature)),
|
||||
("f16c", None),
|
||||
("fma", None),
|
||||
("fxsr", None),
|
||||
("gfni", Some(sym::avx512_target_feature)),
|
||||
|
|
@ -396,7 +396,6 @@ pub fn from_target_feature(
|
|||
Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature,
|
||||
Some(sym::movbe_target_feature) => rust_features.movbe_target_feature,
|
||||
Some(sym::rtm_target_feature) => rust_features.rtm_target_feature,
|
||||
Some(sym::f16c_target_feature) => rust_features.f16c_target_feature,
|
||||
Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature,
|
||||
Some(sym::bpf_target_feature) => rust_features.bpf_target_feature,
|
||||
Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
|
|||
};
|
||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
||||
}
|
||||
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
|
||||
_ => {
|
||||
if let Some(fn_kind) = node.fn_kind() {
|
||||
if fn_kind.constness() == hir::Constness::Const {
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
// Only check non-glue functions
|
||||
if let ty::InstanceDef::Item(def) = instance.def {
|
||||
// Execution might have wandered off into other crates, so we cannot do a stability-
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if !ecx.tcx.is_const_fn_raw(def.did) {
|
||||
// allow calling functions inside a trait marked with #[const_trait].
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ impl<'tcx, Prov: Provenance + 'static> LocalState<'tcx, Prov> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Overwrite the local. If the local can be overwritten in place, return a reference
|
||||
/// Overwrite the local. If the local can be overwritten in place, return a reference
|
||||
/// to do so; otherwise return the `MemPlace` to consult instead.
|
||||
///
|
||||
/// Note: This may only be invoked from the `Machine::access_local_mut` hook and not from
|
||||
|
|
@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
);
|
||||
|
||||
// Recurse to get the size of the dynamically sized field (must be
|
||||
// the last field). Can't have foreign types here, how would we
|
||||
// the last field). Can't have foreign types here, how would we
|
||||
// adjust alignment and size for them?
|
||||
let field = layout.field(self, layout.fields.count() - 1);
|
||||
let Some((unsized_size, mut unsized_align)) = self.size_and_align_of(metadata, &field)? else {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_ev
|
|||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
|
||||
enum InternMode {
|
||||
/// A static and its current mutability. Below shared references inside a `static mut`,
|
||||
/// A static and its current mutability. Below shared references inside a `static mut`,
|
||||
/// this is *immutable*, and below mutable references inside an `UnsafeCell`, this
|
||||
/// is *mutable*.
|
||||
Static(hir::Mutability),
|
||||
|
|
@ -296,7 +296,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
|
|||
}
|
||||
}
|
||||
InternMode::Const => {
|
||||
// Ignore `UnsafeCell`, everything is immutable. Validity does some sanity
|
||||
// Ignore `UnsafeCell`, everything is immutable. Validity does some sanity
|
||||
// checking for mutable references that we encounter -- they must all be
|
||||
// ZST.
|
||||
InternMode::Const
|
||||
|
|
@ -330,7 +330,7 @@ pub enum InternKind {
|
|||
|
||||
/// Intern `ret` and everything it references.
|
||||
///
|
||||
/// This *cannot raise an interpreter error*. Doing so is left to validation, which
|
||||
/// This *cannot raise an interpreter error*. Doing so is left to validation, which
|
||||
/// tracks where in the value we are and thus can show much better error messages.
|
||||
#[instrument(level = "debug", skip(ecx))]
|
||||
pub fn intern_const_alloc_recursive<
|
||||
|
|
@ -379,7 +379,7 @@ pub fn intern_const_alloc_recursive<
|
|||
inside_unsafe_cell: false,
|
||||
}
|
||||
.visit_value(&mplace);
|
||||
// We deliberately *ignore* interpreter errors here. When there is a problem, the remaining
|
||||
// We deliberately *ignore* interpreter errors here. When there is a problem, the remaining
|
||||
// references are "leftover"-interned, and later validation will show a proper error
|
||||
// and point at the right part of the value causing the problem.
|
||||
match res {
|
||||
|
|
@ -454,7 +454,7 @@ pub fn intern_const_alloc_recursive<
|
|||
return Err(reported);
|
||||
} else if ecx.tcx.try_get_global_alloc(alloc_id).is_none() {
|
||||
// We have hit an `AllocId` that is neither in local or global memory and isn't
|
||||
// marked as dangling by local memory. That should be impossible.
|
||||
// marked as dangling by local memory. That should be impossible.
|
||||
span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
unwind: StackPopUnwind,
|
||||
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>;
|
||||
|
||||
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
|
||||
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
|
||||
/// pointer as appropriate.
|
||||
fn call_extra_fn(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
|
|
@ -439,7 +439,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
}
|
||||
|
||||
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
|
||||
/// (CTFE and ConstProp) use the same instance. Here, we share that code.
|
||||
/// (CTFE and ConstProp) use the same instance. Here, we share that code.
|
||||
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||
type Provenance = AllocId;
|
||||
type ProvenanceExtra = ();
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
|
||||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
/// Call this to turn untagged "global" pointers (obtained via `tcx`) into
|
||||
/// the machine pointer to the allocation. Must never be used
|
||||
/// the machine pointer to the allocation. Must never be used
|
||||
/// for any other pointers, nor for TLS statics.
|
||||
///
|
||||
/// Using the resulting pointer represents a *direct* access to that memory
|
||||
|
|
@ -536,7 +536,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
&self,
|
||||
id: AllocId,
|
||||
) -> InterpResult<'tcx, &Allocation<M::Provenance, M::AllocExtra>> {
|
||||
// The error type of the inner closure here is somewhat funny. We have two
|
||||
// The error type of the inner closure here is somewhat funny. We have two
|
||||
// ways of "erroring": An actual error, or because we got a reference from
|
||||
// `get_global_alloc` that we can actually use directly without inserting anything anywhere.
|
||||
// So the error type is `InterpResult<'tcx, &Allocation<M::Provenance>>`.
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Ok(OpTy { op, layout: place.layout, align: Some(place.align) })
|
||||
}
|
||||
|
||||
/// Evaluate a place with the goal of reading from it. This lets us sometimes
|
||||
/// Evaluate a place with the goal of reading from it. This lets us sometimes
|
||||
/// avoid allocations.
|
||||
pub fn eval_place_to_op(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
|
|||
_ => bug!("len not supported on unsized type {:?}", self.layout.ty),
|
||||
}
|
||||
} else {
|
||||
// Go through the layout. There are lots of types that support a length,
|
||||
// Go through the layout. There are lots of types that support a length,
|
||||
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
|
||||
match self.layout.fields {
|
||||
abi::FieldsShape::Array { count, .. } => Ok(count),
|
||||
|
|
@ -294,7 +294,7 @@ where
|
|||
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
||||
{
|
||||
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||
///
|
||||
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
||||
/// want to ever use the place for memory access!
|
||||
|
|
@ -703,7 +703,7 @@ where
|
|||
&mut Operand::Immediate(local_val) => {
|
||||
// We need to make an allocation.
|
||||
|
||||
// We need the layout of the local. We can NOT use the layout we got,
|
||||
// We need the layout of the local. We can NOT use the layout we got,
|
||||
// that might e.g., be an inner field of a struct with `Scalar` layout,
|
||||
// that has different alignment than the outer field.
|
||||
let local_layout =
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// they go to.
|
||||
|
||||
// For where they come from: If the ABI is RustCall, we untuple the
|
||||
// last incoming argument. These two iterators do not have the same type,
|
||||
// last incoming argument. These two iterators do not have the same type,
|
||||
// so to keep the code paths uniform we accept an allocation
|
||||
// (for RustCall ABI only).
|
||||
let caller_args: Cow<'_, [OpTy<'tcx, M::Provenance>]> =
|
||||
|
|
@ -481,7 +481,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
.filter(|arg_and_abi| !matches!(arg_and_abi.1.mode, PassMode::Ignore));
|
||||
|
||||
// Now we have to spread them out across the callee's locals,
|
||||
// taking into account the `spread_arg`. If we could write
|
||||
// taking into account the `spread_arg`. If we could write
|
||||
// this is a single iterator (that handles `spread_arg`), then
|
||||
// `pass_argument` would be the loop body. It takes care to
|
||||
// not advance `caller_iter` for ZSTs.
|
||||
|
|
@ -648,8 +648,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
unwind: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
trace!("drop_in_place: {:?},\n {:?}, {:?}", *place, place.layout.ty, instance);
|
||||
// We take the address of the object. This may well be unaligned, which is fine
|
||||
// for us here. However, unaligned accesses will probably make the actual drop
|
||||
// We take the address of the object. This may well be unaligned, which is fine
|
||||
// for us here. However, unaligned accesses will probably make the actual drop
|
||||
// implementation fail -- a problem shared by rustc.
|
||||
let place = self.force_allocation(place)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,11 @@ where
|
|||
let index = index
|
||||
.try_into()
|
||||
.expect("more generic parameters than can fit into a `u32`");
|
||||
let is_used = unused_params.contains(index).map_or(true, |unused| !unused);
|
||||
// Only recurse when generic parameters in fns, closures and generators
|
||||
// are used and require substitution.
|
||||
// Just in case there are closures or generators within this subst,
|
||||
// recurse.
|
||||
if is_used && subst.needs_subst() {
|
||||
if unused_params.is_used(index) && subst.needs_subst() {
|
||||
return subst.visit_with(self);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ fn write_path(out: &mut String, path: &[PathElem]) {
|
|||
TupleElem(idx) => write!(out, ".{}", idx),
|
||||
ArrayElem(idx) => write!(out, "[{}]", idx),
|
||||
// `.<deref>` does not match Rust syntax, but it is more readable for long paths -- and
|
||||
// some of the other items here also are not Rust syntax. Actually we can't
|
||||
// some of the other items here also are not Rust syntax. Actually we can't
|
||||
// even use the usual syntax because we are just showing the projections,
|
||||
// not the root.
|
||||
Deref => write!(out, ".<deref>"),
|
||||
|
|
@ -484,7 +484,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
}
|
||||
|
||||
/// Check if this is a value of primitive type, and if yes check the validity of the value
|
||||
/// at that type. Return `true` if the type is indeed primitive.
|
||||
/// at that type. Return `true` if the type is indeed primitive.
|
||||
fn try_visit_primitive(
|
||||
&mut self,
|
||||
value: &OpTy<'tcx, M::Provenance>,
|
||||
|
|
@ -623,7 +623,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
// Can only happen during CTFE.
|
||||
// We support 2 kinds of ranges here: full range, and excluding zero.
|
||||
if start == 1 && end == max_value {
|
||||
// Only null is the niche. So make sure the ptr is NOT null.
|
||||
// Only null is the niche. So make sure the ptr is NOT null.
|
||||
if self.ecx.scalar_may_be_null(scalar)? {
|
||||
throw_validation_failure!(self.path,
|
||||
{ "a potentially null pointer" }
|
||||
|
|
@ -759,7 +759,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// Recursively walk the value at its type.
|
||||
self.walk_value(op)?;
|
||||
|
||||
// *After* all of this, check the ABI. We need to check the ABI to handle
|
||||
// *After* all of this, check the ABI. We need to check the ABI to handle
|
||||
// types like `NonNull` where the `Scalar` info is more restrictive than what
|
||||
// the fields say (`rustc_layout_scalar_valid_range_start`).
|
||||
// But in most cases, this will just propagate what the fields say,
|
||||
|
|
@ -857,10 +857,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// Optimization: we just check the entire range at once.
|
||||
// NOTE: Keep this in sync with the handling of integer and float
|
||||
// types above, in `visit_primitive`.
|
||||
// In run-time mode, we accept pointers in here. This is actually more
|
||||
// In run-time mode, we accept pointers in here. This is actually more
|
||||
// permissive than a per-element check would be, e.g., we accept
|
||||
// a &[u8] that contains a pointer even though bytewise checking would
|
||||
// reject it. However, that's good: We don't inherently want
|
||||
// reject it. However, that's good: We don't inherently want
|
||||
// to reject those pointers, we just do not have the machinery to
|
||||
// talk about parts of a pointer.
|
||||
// We also accept uninit, for consistency with the slow path.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust.
|
|||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(is_some_and)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||
// impl trait is gone in MIR, so check the return type of a const fn by its signature
|
||||
// instead of the type of the return place.
|
||||
self.span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
let return_ty = tcx.fn_sig(def_id).output();
|
||||
let return_ty = self.ccx.fn_sig().output();
|
||||
self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE);
|
||||
}
|
||||
|
||||
|
|
@ -730,6 +730,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: Some(sym::const_trait_impl),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -782,6 +783,20 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
);
|
||||
return;
|
||||
}
|
||||
Ok(Some(ImplSource::Closure(data))) => {
|
||||
if !tcx.is_const_fn_raw(data.closure_def_id) {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: None,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ok(Some(ImplSource::UserDefined(data))) => {
|
||||
let callee_name = tcx.item_name(callee);
|
||||
if let Some(&did) = tcx
|
||||
|
|
@ -802,6 +817,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -844,6 +860,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -903,6 +920,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_attr as attr;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::{self, PolyFnSig, TyCtxt};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
pub use self::qualifs::Qualif;
|
||||
|
|
@ -64,6 +64,17 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
|||
fn is_async(&self) -> bool {
|
||||
self.tcx.asyncness(self.def_id()).is_async()
|
||||
}
|
||||
|
||||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
||||
let did = self.def_id().to_def_id();
|
||||
if self.tcx.is_closure(did) {
|
||||
let ty = self.tcx.type_of(did);
|
||||
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") };
|
||||
substs.as_closure().sig()
|
||||
} else {
|
||||
self.tcx.fn_sig(did)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rustc_allow_const_fn_unstable(
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ pub struct FnCallNonConst<'tcx> {
|
|||
pub substs: SubstsRef<'tcx>,
|
||||
pub span: Span,
|
||||
pub from_hir_call: bool,
|
||||
pub feature: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
|
|
@ -119,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
_: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let FnCallNonConst { caller, callee, substs, span, from_hir_call } = *self;
|
||||
let FnCallNonConst { caller, callee, substs, span, from_hir_call, feature } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
|
||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||
|
|
@ -318,6 +319,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
|||
ccx.const_kind(),
|
||||
));
|
||||
|
||||
if let Some(feature) = feature && ccx.tcx.sess.is_nightly_build() {
|
||||
err.help(&format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable",
|
||||
feature,
|
||||
));
|
||||
}
|
||||
|
||||
if let ConstContext::Static(_) = ccx.const_kind() {
|
||||
err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
|
|||
}
|
||||
|
||||
// Drop elaboration is not precise enough to accept code like
|
||||
// `src/test/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option<Vec<T>>` is
|
||||
// `tests/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option<Vec<T>>` is
|
||||
// initialized with `None` and never changed, it still emits drop glue.
|
||||
// Hence we additionally check the qualifs here to allow more code to pass.
|
||||
if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,6 @@ pub fn is_subtype<'tcx>(
|
|||
// even if they're constrained in our current function.
|
||||
//
|
||||
// It seems very unlikely that this hides any bugs.
|
||||
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||
let _ = infcx.take_opaque_types();
|
||||
errors.is_empty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
//! ```
|
||||
//!
|
||||
//! `Frozen` impls `Deref`, so we can ergonomically call methods on `Bar`, but it doesn't `impl
|
||||
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
|
||||
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
|
||||
//! `mutate` requires a mutable reference but we don't have one.
|
||||
//!
|
||||
//! # Caveats
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ fn test_find_state_2() {
|
|||
// 0 -> 1 -> 2 -> 1
|
||||
//
|
||||
// and at this point detect a cycle. The state of 2 will thus be
|
||||
// `InCycleWith { 1 }`. We will then visit the 1 -> 3 edge, which
|
||||
// `InCycleWith { 1 }`. We will then visit the 1 -> 3 edge, which
|
||||
// will attempt to visit 0 as well, thus going to the state
|
||||
// `InCycleWith { 0 }`. Finally, node 1 will complete; the lowest
|
||||
// depth of any successor was 3 which had depth 0, and thus it
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ impl<T> Steal<T> {
|
|||
ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.value.get_mut().as_mut().expect("attempt to read from stolen value")
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn steal(&self) -> T {
|
||||
let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
|
|||
// values. So here is what we do:
|
||||
//
|
||||
// 1. Find the vector `[X | a < X && b < X]` of all values
|
||||
// `X` where `a < X` and `b < X`. In terms of the
|
||||
// `X` where `a < X` and `b < X`. In terms of the
|
||||
// graph, this means all values reachable from both `a`
|
||||
// and `b`. Note that this vector is also a set, but we
|
||||
// use the term vector because the order matters
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
The `driver` crate is effectively the "main" function for the rust
|
||||
compiler. It orchestrates the compilation process and "knits together"
|
||||
compiler. It orchestrates the compilation process and "knits together"
|
||||
the code from the other crates within rustc. This crate itself does
|
||||
not contain any of the "main logic" of the compiler (though it does
|
||||
have some code related to pretty printing or other minor compiler
|
||||
|
|
|
|||
|
|
@ -309,8 +309,8 @@ fn run_compiler(
|
|||
|
||||
if let Some(ppm) = &sess.opts.pretty {
|
||||
if ppm.needs_ast_map() {
|
||||
let expanded_crate = queries.expansion()?.peek().0.clone();
|
||||
queries.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
let expanded_crate = queries.expansion()?.borrow().0.clone();
|
||||
queries.global_ctxt()?.enter(|tcx| {
|
||||
pretty::print_after_hir_lowering(
|
||||
tcx,
|
||||
compiler.input(),
|
||||
|
|
@ -321,7 +321,7 @@ fn run_compiler(
|
|||
Ok(())
|
||||
})?;
|
||||
} else {
|
||||
let krate = queries.parse()?.take();
|
||||
let krate = queries.parse()?.steal();
|
||||
pretty::print_after_parsing(
|
||||
sess,
|
||||
compiler.input(),
|
||||
|
|
@ -343,7 +343,8 @@ fn run_compiler(
|
|||
}
|
||||
|
||||
{
|
||||
let (_, lint_store) = &*queries.register_plugins()?.peek();
|
||||
let plugins = queries.register_plugins()?;
|
||||
let (_, lint_store) = &*plugins.borrow();
|
||||
|
||||
// Lint plugins are registered; now we can process command line flags.
|
||||
if sess.opts.describe_lints {
|
||||
|
|
@ -371,7 +372,7 @@ fn run_compiler(
|
|||
return early_exit();
|
||||
}
|
||||
|
||||
queries.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
queries.global_ctxt()?.enter(|tcx| {
|
||||
let result = tcx.analysis(());
|
||||
if sess.opts.unstable_opts.save_analysis {
|
||||
let crate_name = tcx.crate_name(LOCAL_CRATE);
|
||||
|
|
@ -1196,8 +1197,8 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
|
|||
};
|
||||
|
||||
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
|
||||
// Don't do this for `GoodPathBug`, which already emits its own more useful backtrace.
|
||||
if !info.payload().is::<rustc_errors::GoodPathBug>() {
|
||||
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
|
||||
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
|
||||
(*DEFAULT_HOOK)(info);
|
||||
|
||||
// Separate the output with an empty line
|
||||
|
|
@ -1235,7 +1236,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
|||
// a .span_bug or .bug call has already printed what
|
||||
// it wants to print.
|
||||
if !info.payload().is::<rustc_errors::ExplicitBug>()
|
||||
&& !info.payload().is::<rustc_errors::GoodPathBug>()
|
||||
&& !info.payload().is::<rustc_errors::DelayedBugPanic>()
|
||||
{
|
||||
let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
|
||||
handler.emit_diagnostic(&mut d);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Error messages for EXXXX errors. Each message should start and end with a
|
||||
// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
|
||||
// Error messages for EXXXX errors. Each message should start and end with a
|
||||
// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
|
||||
// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
|
||||
//
|
||||
// /!\ IMPORTANT /!\
|
||||
|
|
@ -110,6 +110,7 @@ E0204: include_str!("./error_codes/E0204.md"),
|
|||
E0205: include_str!("./error_codes/E0205.md"),
|
||||
E0206: include_str!("./error_codes/E0206.md"),
|
||||
E0207: include_str!("./error_codes/E0207.md"),
|
||||
E0208: include_str!("./error_codes/E0208.md"),
|
||||
E0210: include_str!("./error_codes/E0210.md"),
|
||||
E0211: include_str!("./error_codes/E0211.md"),
|
||||
E0212: include_str!("./error_codes/E0212.md"),
|
||||
|
|
@ -387,6 +388,7 @@ E0636: include_str!("./error_codes/E0636.md"),
|
|||
E0637: include_str!("./error_codes/E0637.md"),
|
||||
E0638: include_str!("./error_codes/E0638.md"),
|
||||
E0639: include_str!("./error_codes/E0639.md"),
|
||||
E0640: include_str!("./error_codes/E0640.md"),
|
||||
E0641: include_str!("./error_codes/E0641.md"),
|
||||
E0642: include_str!("./error_codes/E0642.md"),
|
||||
E0643: include_str!("./error_codes/E0643.md"),
|
||||
|
|
@ -434,6 +436,8 @@ E0713: include_str!("./error_codes/E0713.md"),
|
|||
E0714: include_str!("./error_codes/E0714.md"),
|
||||
E0715: include_str!("./error_codes/E0715.md"),
|
||||
E0716: include_str!("./error_codes/E0716.md"),
|
||||
E0711: include_str!("./error_codes/E0711.md"),
|
||||
E0717: include_str!("./error_codes/E0717.md"),
|
||||
E0718: include_str!("./error_codes/E0718.md"),
|
||||
E0719: include_str!("./error_codes/E0719.md"),
|
||||
E0720: include_str!("./error_codes/E0720.md"),
|
||||
|
|
@ -540,7 +544,6 @@ E0791: include_str!("./error_codes/E0791.md"),
|
|||
// E0190, // deprecated: can only cast a &-pointer to an &-object
|
||||
// E0194, // merged into E0403
|
||||
// E0196, // cannot determine a type for this closure
|
||||
E0208, // internal error code
|
||||
// E0209, // builtin traits can only be implemented on structs or enums
|
||||
// E0213, // associated types are not accepted in this context
|
||||
// E0215, // angle-bracket notation is not stable with `Fn`
|
||||
|
|
@ -571,7 +574,7 @@ E0791: include_str!("./error_codes/E0791.md"),
|
|||
// E0274, // on_unimplemented #2
|
||||
// E0278, // requirement is not satisfied
|
||||
// E0279,
|
||||
E0280, // requirement is not satisfied
|
||||
// E0280, // changed to ICE
|
||||
// E0285, // overflow evaluation builtin bounds
|
||||
// E0296, // replaced with a generic attribute input check
|
||||
// E0298, // cannot compare constants
|
||||
|
|
@ -615,7 +618,7 @@ E0791: include_str!("./error_codes/E0791.md"),
|
|||
// E0487, // unsafe use of destructor: destructor might be called while...
|
||||
// E0488, // lifetime of variable does not enclose its declaration
|
||||
// E0489, // type/lifetime parameter not in scope here
|
||||
E0490, // a value of type `..` is borrowed for too long
|
||||
// E0490, // removed: unreachable
|
||||
E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
|
||||
// E0526, // shuffle indices are not constant
|
||||
// E0540, // multiple rustc_deprecated attributes
|
||||
|
|
@ -633,14 +636,11 @@ E0791: include_str!("./error_codes/E0791.md"),
|
|||
// E0629, // missing 'feature' (rustc_const_unstable)
|
||||
// E0630, // rustc_const_unstable attribute must be paired with stable/unstable
|
||||
// attribute
|
||||
E0640, // infer outlives requirements, internal error code
|
||||
// E0645, // trait aliases not finished
|
||||
// E0694, // an unknown tool name found in scoped attributes
|
||||
// E0702, // replaced with a generic attribute input check
|
||||
// E0707, // multiple elided lifetimes used in arguments of `async fn`
|
||||
// E0709, // multiple different lifetimes used in arguments of `async fn`
|
||||
E0711, // a feature has been declared with conflicting stability attributes, internal error code
|
||||
E0717, // rustc_promotable without stability attribute, internal error code
|
||||
// E0721, // `await` keyword
|
||||
// E0723, // unstable feature in `const` context
|
||||
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
|
||||
|
|
|
|||
1
compiler/rustc_error_codes/src/error_codes/E0208.md
Normal file
1
compiler/rustc_error_codes/src/error_codes/E0208.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
#### This error code is internal to the compiler and will not be emitted with normal Rust code.
|
||||
|
|
@ -17,7 +17,7 @@ fn mutable() {
|
|||
foo(|| x = 2);
|
||||
}
|
||||
|
||||
// Attempts to take a mutable reference to closed-over data. Error message
|
||||
// Attempts to take a mutable reference to closed-over data. Error message
|
||||
// reads: `cannot borrow data mutably in a captured outer variable...`
|
||||
fn mut_addr() {
|
||||
let mut x = 0u32;
|
||||
|
|
|
|||
1
compiler/rustc_error_codes/src/error_codes/E0640.md
Normal file
1
compiler/rustc_error_codes/src/error_codes/E0640.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
#### This error code is internal to the compiler and will not be emitted with normal Rust code.
|
||||
30
compiler/rustc_error_codes/src/error_codes/E0711.md
Normal file
30
compiler/rustc_error_codes/src/error_codes/E0711.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#### This error code is internal to the compiler and will not be emitted with normal Rust code.
|
||||
|
||||
Feature declared with conflicting stability requirements.
|
||||
|
||||
```compile_fail,E0711
|
||||
// NOTE: this attribute is perma-unstable and should *never* be used outside of
|
||||
// stdlib and the compiler.
|
||||
#![feature(staged_api)]
|
||||
|
||||
#![stable(feature = "...", since = "1.0.0")]
|
||||
|
||||
#[stable(feature = "foo", since = "1.0.0")]
|
||||
fn foo_stable_1_0_0() {}
|
||||
|
||||
// error: feature `foo` is declared stable since 1.29.0
|
||||
#[stable(feature = "foo", since = "1.29.0")]
|
||||
fn foo_stable_1_29_0() {}
|
||||
|
||||
// error: feature `foo` is declared unstable
|
||||
#[unstable(feature = "foo", issue = "none")]
|
||||
fn foo_unstable() {}
|
||||
```
|
||||
|
||||
In the above example, the `foo` feature is first defined to be stable since
|
||||
1.0.0, but is then re-declared stable since 1.29.0. This discrepancy in
|
||||
versions causes an error. Furthermore, `foo` is then re-declared as unstable,
|
||||
again the conflict causes an error.
|
||||
|
||||
This error can be fixed by splitting the feature, this allows any
|
||||
stability requirements and removes any possibility of conflict.
|
||||
|
|
@ -22,7 +22,7 @@ gets called when they go out of scope. This destructor gets exclusive
|
|||
access to the fields of the struct when it runs.
|
||||
|
||||
This means that when `s` reaches the end of `demo`, its destructor
|
||||
gets exclusive access to its `&mut`-borrowed string data. allowing
|
||||
gets exclusive access to its `&mut`-borrowed string data. allowing
|
||||
another borrow of that string data (`p`), to exist across the drop of
|
||||
`s` would be a violation of the principle that `&mut`-borrows have
|
||||
exclusive, unaliased access to their referenced data.
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ fn main() {}
|
|||
```
|
||||
|
||||
The items of marker traits cannot be overridden, so there's no need to have them
|
||||
when they cannot be changed per-type anyway. If you wanted them for ergonomic
|
||||
when they cannot be changed per-type anyway. If you wanted them for ergonomic
|
||||
reasons, consider making an extension trait instead.
|
||||
|
|
|
|||
1
compiler/rustc_error_codes/src/error_codes/E0717.md
Normal file
1
compiler/rustc_error_codes/src/error_codes/E0717.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
#### This error code is internal to the compiler and will not be emitted with normal Rust code.
|
||||
|
|
@ -120,3 +120,7 @@ hir_analysis_self_in_impl_self =
|
|||
|
||||
hir_analysis_linkage_type =
|
||||
invalid type for variable with `#[linkage]` attribute
|
||||
|
||||
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
||||
.label = deref recursion limit reached
|
||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ infer_subtype_2 = ...so that {$requirement ->
|
|||
infer_reborrow = ...so that reference does not outlive borrowed content
|
||||
infer_reborrow_upvar = ...so that closure can access `{$name}`
|
||||
infer_relate_object_bound = ...so that it can be closed over into an object
|
||||
infer_data_borrowed = ...so that the type `{$name}` is not borrowed for too long
|
||||
infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
|
||||
infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
|
||||
[true] ...
|
||||
|
|
|
|||
|
|
@ -15,6 +15,43 @@ lint_enum_intrinsics_mem_variant =
|
|||
|
||||
lint_expectation = this lint expectation is unfulfilled
|
||||
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
|
||||
.rationale = {$rationale}
|
||||
|
||||
lint_for_loops_over_fallibles =
|
||||
for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement
|
||||
.suggestion = consider using `if let` to clear intent
|
||||
.remove_next = to iterate over `{$recv_snip}` remove the call to `next`
|
||||
.use_while_let = to check pattern in a loop use `while let`
|
||||
.use_question_mark = consider unwrapping the `Result` with `?` to iterate over its contents
|
||||
|
||||
lint_non_binding_let_on_sync_lock =
|
||||
non-binding let on a synchronization lock
|
||||
|
||||
lint_non_binding_let_on_drop_type =
|
||||
non-binding let on a type that implements `Drop`
|
||||
|
||||
lint_non_binding_let_suggestion =
|
||||
consider binding to an unused variable to avoid immediately dropping the value
|
||||
|
||||
lint_non_binding_let_multi_suggestion =
|
||||
consider immediately dropping the value
|
||||
|
||||
lint_deprecated_lint_name =
|
||||
lint name `{$name}` is deprecated and may not have an effect in the future.
|
||||
.suggestion = change it to
|
||||
|
||||
lint_renamed_or_removed_lint = {$msg}
|
||||
.suggestion = use the new name
|
||||
|
||||
lint_unknown_lint =
|
||||
unknown lint: `{$name}`
|
||||
.suggestion = did you mean
|
||||
|
||||
lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level
|
||||
|
||||
lint_unknown_gated_lint =
|
||||
unknown lint: `{$name}`
|
||||
.note = the `{$name}` lint is unstable
|
||||
|
||||
lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
|
||||
.label = this {$label} contains {$count ->
|
||||
|
|
@ -55,6 +92,8 @@ lint_diag_out_of_impl =
|
|||
|
||||
lint_untranslatable_diag = diagnostics should be created using translatable messages
|
||||
|
||||
lint_bad_opt_access = {$msg}
|
||||
|
||||
lint_cstring_ptr = getting the inner pointer of a temporary `CString`
|
||||
.as_ptr_label = this pointer will be invalid
|
||||
.unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
||||
|
|
@ -331,6 +370,8 @@ lint_builtin_anonymous_params = anonymous parameters are deprecated and will be
|
|||
.suggestion = try naming the parameter or explicitly ignoring it
|
||||
|
||||
lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
|
||||
.msg_suggestion = {$msg}
|
||||
.default_suggestion = remove this attribute
|
||||
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
|
||||
lint_builtin_deprecated_attr_default_suggestion = remove this attribute
|
||||
|
||||
|
|
@ -391,10 +432,16 @@ lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may n
|
|||
.note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
|
||||
.help = consider using `min_{$name}` instead, which is more stable and complete
|
||||
|
||||
lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
|
||||
lint_builtin_unpermitted_type_init_zeroed = the type `{$ty}` does not permit zero-initialization
|
||||
lint_builtin_unpermitted_type_init_unint = the type `{$ty}` does not permit being left uninitialized
|
||||
|
||||
lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed
|
||||
lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
||||
lint_builtin_clashing_extern_same_name = `{$this}` redeclared with a different signature
|
||||
.previous_decl_label = `{$orig}` previously declared here
|
||||
.mismatch_label = this signature doesn't match the previous declaration
|
||||
lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
|
||||
lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature
|
||||
.previous_decl_label = `{$orig}` previously declared here
|
||||
.mismatch_label = this signature doesn't match the previous declaration
|
||||
|
||||
|
|
@ -403,6 +450,16 @@ lint_builtin_deref_nullptr = dereferencing a null pointer
|
|||
|
||||
lint_builtin_asm_labels = avoid using named labels in inline assembly
|
||||
|
||||
lint_builtin_special_module_name_used_lib = found module declaration for lib.rs
|
||||
.note = lib.rs is the root of this crate's library target
|
||||
.help = to refer to it from other targets, use the library's name as the path
|
||||
|
||||
lint_builtin_special_module_name_used_main = found module declaration for main.rs
|
||||
.note = a binary crate cannot be used as library
|
||||
|
||||
lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
|
||||
.label = target type is set here
|
||||
|
||||
lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid
|
||||
.label = overruled by previous forbid
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
|
|||
.label = lower bound larger than upper bound
|
||||
.teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
|
||||
|
||||
mir_build_literal_in_range_out_of_bounds =
|
||||
literal out of range for `{$ty}`
|
||||
.label = this value doesn't fit in `{$ty}` whose maximum value is `{$max}`
|
||||
|
||||
mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper
|
||||
|
||||
mir_build_leading_irrefutable_let_patterns = leading irrefutable {$count ->
|
||||
|
|
@ -299,3 +303,64 @@ mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once a
|
|||
.mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
|
||||
.immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
|
||||
.moved = also moved into `{$name_moved}` here
|
||||
|
||||
mir_build_union_pattern = cannot use unions in constant patterns
|
||||
|
||||
mir_build_type_not_structural =
|
||||
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
|
||||
mir_build_unsized_pattern = cannot use unsized non-slice type `{$non_sm_ty}` in constant patterns
|
||||
|
||||
mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns
|
||||
|
||||
mir_build_float_pattern = floating-point types cannot be used in patterns
|
||||
|
||||
mir_build_pointer_pattern = function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
||||
|
||||
mir_build_indirect_structural_match =
|
||||
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
|
||||
mir_build_nontrivial_structural_match =
|
||||
to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
|
||||
mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpoints
|
||||
.range = ... with this range
|
||||
.note = you likely meant to write mutually exclusive ranges
|
||||
|
||||
mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
|
||||
.help = ensure that all variants are matched explicitly by adding the suggested match arms
|
||||
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
|
||||
|
||||
mir_build_uncovered = {$count ->
|
||||
[1] pattern `{$witness_1}`
|
||||
[2] patterns `{$witness_1}` and `{$witness_2}`
|
||||
[3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}`
|
||||
*[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and {$remainder} more
|
||||
} not covered
|
||||
|
||||
mir_build_pattern_not_covered = refutable pattern in {$origin}
|
||||
.pattern_ty = the matched value is of type `{$pattern_ty}`
|
||||
|
||||
mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||
|
||||
mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||
|
||||
mir_build_res_defined_here = {$res} defined here
|
||||
|
||||
mir_build_adt_defined_here = `{$ty}` defined here
|
||||
|
||||
mir_build_variant_defined_here = not covered
|
||||
|
||||
mir_build_interpreted_as_const = introduce a variable instead
|
||||
|
||||
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as {$article} {$res} pattern, not a new variable
|
||||
|
||||
mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count ->
|
||||
[one] variant that isn't
|
||||
*[other] variants that aren't
|
||||
} matched
|
||||
|
||||
mir_build_suggest_let_else = you might want to use `let else` to handle the {$count ->
|
||||
[one] variant that isn't
|
||||
*[other] variants that aren't
|
||||
} matched
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ parse_struct_literal_body_without_path =
|
|||
struct literal body without path
|
||||
.suggestion = you might have forgotten to add the struct literal inside the block
|
||||
|
||||
parse_struct_literal_needing_parens =
|
||||
invalid struct literal
|
||||
.suggestion = you might need to surround the struct literal in parentheses
|
||||
|
||||
parse_maybe_report_ambiguous_plus =
|
||||
ambiguous `+` in a type
|
||||
.suggestion = use parentheses to disambiguate
|
||||
|
|
@ -368,3 +372,9 @@ parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of
|
|||
|
||||
parse_expected_fn_path_found_fn_keyword = expected identifier, found keyword `fn`
|
||||
.suggestion = use `Fn` to refer to the trait
|
||||
|
||||
parse_where_clause_before_tuple_struct_body = where clauses are not allowed before tuple struct bodies
|
||||
.label = unexpected where clause
|
||||
.name_label = while parsing this tuple struct
|
||||
.body_label = the struct body
|
||||
.suggestion = move the body before the where clause
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@ trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entri
|
|||
|
||||
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
|
||||
|
||||
trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
||||
.label = deref recursion limit reached
|
||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||
|
||||
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
|
||||
.label = empty on-clause here
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue