Merge branch 'master' into patch-2

This commit is contained in:
Kagami Sascha Rosylight 2022-11-15 21:16:11 +01:00 committed by GitHub
commit 0a528b16fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2627 changed files with 58235 additions and 31211 deletions

View File

@ -4,3 +4,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60
95e00bfed801e264e9c4ac817004153ca0f19eb6 95e00bfed801e264e9c4ac817004153ca0f19eb6
# reformat with new rustfmt # reformat with new rustfmt
971c549ca334b7b7406e61e958efcca9c4152822 971c549ca334b7b7406e61e958efcca9c4152822
# refactor infcx building
283abbf0e7d20176f76006825b5c52e9a4234e4c

View File

@ -217,7 +217,7 @@ Hsiang-Cheng Yang <rick68@users.noreply.github.com>
Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com> Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com>
Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk> Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk>
Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org> Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org>
Ibraheem Ahmed <ibrah1440@gmail.com> Ibraheem Ahmed <ibraheem@ibraheem.ca> <ibrah1440@gmail.com>
Ilyong Cho <ilyoan@gmail.com> Ilyong Cho <ilyoan@gmail.com>
inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com>
Irina Popa <irinagpopa@gmail.com> Irina Popa <irinagpopa@gmail.com>

View File

@ -6,11 +6,6 @@ Files: *
Copyright: The Rust Project Developers (see https://thanks.rust-lang.org) Copyright: The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT or Apache-2.0 License: MIT or Apache-2.0
Files: library/std/src/sync/mpsc/mpsc_queue.rs
library/std/src/sync/mpsc/spsc_queue.rs
Copyright: 2010-2011 Dmitry Vyukov
License: BSD-2-Clause
Files: src/librustdoc/html/static/fonts/FiraSans* Files: src/librustdoc/html/static/fonts/FiraSans*
Copyright: 2014, Mozilla Foundation, 2014, Telefonica S.A. Copyright: 2014, Mozilla Foundation, 2014, Telefonica S.A.
License: OFL-1.1 License: OFL-1.1

View File

@ -339,3 +339,53 @@ their own copyright notices and license terms:
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE. OF SUCH DAMAGE.
* Portions of internationalization code use code or data from Unicode, which
carry the following license:
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
See Terms of Use <https://www.unicode.org/copyright.html>
for definitions of Unicode Inc.s Data Files and Software.
NOTICE TO USER: Carefully read the following legal agreement.
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
TERMS AND CONDITIONS OF THIS AGREEMENT.
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
THE DATA FILES OR SOFTWARE.
COPYRIGHT AND PERMISSION NOTICE
Copyright © 1991-2022 Unicode, Inc. All rights reserved.
Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Unicode data files and any associated documentation
(the "Data Files") or Unicode software and any associated documentation
(the "Software") to deal in the Data Files or Software
without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, and/or sell copies of
the Data Files or Software, and to permit persons to whom the Data Files
or Software are furnished to do so, provided that either
(a) this copyright and permission notice appear with all copies
of the Data Files or Software, or
(b) this copyright and permission notice appear in associated
Documentation.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder
shall not be used in advertising or otherwise to promote the sale,
use or other dealings in these Data Files or Software without prior
written authorization of the copyright holder.

View File

@ -2,34 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "addr2line"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
dependencies = [
"compiler_builtins",
"gimli 0.25.0",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.17.0" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli 0.26.1",
]
[[package]]
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"gimli",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core", "rustc-std-workspace-core",
] ]
@ -38,6 +19,10 @@ name = "adler"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-core",
]
[[package]] [[package]]
name = "ahash" name = "ahash"
@ -185,12 +170,12 @@ version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
dependencies = [ dependencies = [
"addr2line 0.17.0", "addr2line",
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"miniz_oxide 0.5.3", "miniz_oxide",
"object 0.29.0", "object",
"rustc-demangle", "rustc-demangle",
] ]
@ -288,7 +273,7 @@ dependencies = [
[[package]] [[package]]
name = "cargo" name = "cargo"
version = "0.67.0" version = "0.68.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"atty", "atty",
@ -427,7 +412,6 @@ dependencies = [
"glob", "glob",
"itertools", "itertools",
"lazy_static", "lazy_static",
"remove_dir_all",
"serde_json", "serde_json",
"snapbox", "snapbox",
"tar", "tar",
@ -449,7 +433,7 @@ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
"log", "log",
"miow", "miow 0.4.0",
"same-file", "same-file",
"shell-escape", "shell-escape",
"tempfile", "tempfile",
@ -489,9 +473,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.73" version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
dependencies = [ dependencies = [
"jobserver", "jobserver",
] ]
@ -518,9 +502,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-derive" name = "chalk-derive"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0001adf0cf12361e08b65e1898ea138f8f77d8f5177cbf29b6b3b3532252bd6" checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -530,9 +514,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-engine" name = "chalk-engine"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c44ee96f2d67cb5193d1503f185db1abad9933a1c6e6b4169c176f90baecd393" checksum = "7e54ac43048cb31c470d7b3e3acd409090ef4a5abddfe02455187aebc3d6879f"
dependencies = [ dependencies = [
"chalk-derive", "chalk-derive",
"chalk-ir", "chalk-ir",
@ -543,9 +527,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-ir" name = "chalk-ir"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d8a95548f23618fda86426e4304e563ec2bb7ba0216139f0748d63c107b5f1" checksum = "43aa55deff4e7fbdb09fa014543372f2c95a06835ac487b9ce57b5099b950838"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chalk-derive", "chalk-derive",
@ -554,9 +538,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-solve" name = "chalk-solve"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37f492dacfafe2e21319b80827da2779932909bb392f0cc86b2bd5c07c1b4e1" checksum = "61213deefc36ba265ad01c4d997e18bcddf7922862a4594a47ca4575afb3dab4"
dependencies = [ dependencies = [
"chalk-derive", "chalk-derive",
"chalk-ir", "chalk-ir",
@ -815,7 +799,8 @@ dependencies = [
"lazy_static", "lazy_static",
"lazycell", "lazycell",
"libc", "libc",
"miow", "miow 0.3.7",
"miropt-test-tools",
"regex", "regex",
"rustfix", "rustfix",
"serde", "serde",
@ -839,7 +824,7 @@ dependencies = [
"lazy_static", "lazy_static",
"libc", "libc",
"log", "log",
"miow", "miow 0.3.7",
"regex", "regex",
"rustfix", "rustfix",
"serde", "serde",
@ -852,9 +837,9 @@ dependencies = [
[[package]] [[package]]
name = "concolor" name = "concolor"
version = "0.0.8" version = "0.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af" checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
@ -863,9 +848,9 @@ dependencies = [
[[package]] [[package]]
name = "concolor-query" name = "concolor-query"
version = "0.0.5" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317"
[[package]] [[package]]
name = "content_inspector" name = "content_inspector"
@ -1035,9 +1020,9 @@ dependencies = [
[[package]] [[package]]
name = "curl" name = "curl"
version = "0.4.43" version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f" checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
dependencies = [ dependencies = [
"curl-sys", "curl-sys",
"libc", "libc",
@ -1050,9 +1035,9 @@ dependencies = [
[[package]] [[package]]
name = "curl-sys" name = "curl-sys"
version = "0.4.55+curl-7.83.1" version = "0.4.59+curl-7.86.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@ -1153,6 +1138,17 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "displaydoc"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "dlmalloc" name = "dlmalloc"
version = "0.2.3" version = "0.2.3"
@ -1284,15 +1280,15 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.16" version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e" checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 1.0.0",
"crc32fast", "crc32fast",
"libc", "libc",
"libz-sys", "libz-sys",
"miniz_oxide 0.4.0", "miniz_oxide",
] ]
[[package]] [[package]]
@ -1514,11 +1510,11 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.1.14" version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 1.0.0",
"libc", "libc",
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
@ -1534,25 +1530,17 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "gimli"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.26.1" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
dependencies = [ dependencies = [
"compiler_builtins",
"fallible-iterator", "fallible-iterator",
"indexmap", "indexmap",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
"stable_deref_trait", "stable_deref_trait",
] ]
@ -1833,11 +1821,10 @@ dependencies = [
[[package]] [[package]]
name = "intl_pluralrules" name = "intl_pluralrules"
version = "7.0.1" version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b18f988384267d7066cc2be425e6faf352900652c046b6971d2e228d3b1c5ecf" checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
dependencies = [ dependencies = [
"tinystr",
"unic-langid", "unic-langid",
] ]
@ -2216,25 +2203,16 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
dependencies = [
"adler 0.2.3",
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.5.3" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
dependencies = [ dependencies = [
"adler 1.0.2", "adler",
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
] ]
[[package]] [[package]]
@ -2246,6 +2224,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "miow"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7377f7792b3afb6a3cba68daa54ca23c032137010460d667fda53a8d66be00e"
dependencies = [
"windows-sys 0.28.0",
]
[[package]] [[package]]
name = "miri" name = "miri"
version = "0.1.0" version = "0.1.0"
@ -2262,11 +2249,19 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"rustc-workspace-hack", "rustc-workspace-hack",
"rustc_version",
"shell-escape", "shell-escape",
"smallvec", "smallvec",
"ui_test", "ui_test",
] ]
[[package]]
name = "miropt-test-tools"
version = "0.1.0"
dependencies = [
"regex",
]
[[package]] [[package]]
name = "new_debug_unreachable" name = "new_debug_unreachable"
version = "1.0.4" version = "1.0.4"
@ -2319,29 +2314,20 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "object"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
dependencies = [
"compiler_builtins",
"memchr",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.29.0" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [ dependencies = [
"compiler_builtins",
"crc32fast", "crc32fast",
"flate2", "flate2",
"hashbrown", "hashbrown",
"indexmap", "indexmap",
"memchr", "memchr",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
] ]
[[package]] [[package]]
@ -2459,7 +2445,7 @@ name = "panic_abort"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"alloc", "alloc",
"cfg-if 0.1.10", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",
@ -2470,7 +2456,7 @@ name = "panic_unwind"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"alloc", "alloc",
"cfg-if 0.1.10", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",
@ -2495,7 +2481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core 0.9.3", "parking_lot_core 0.9.4",
] ]
[[package]] [[package]]
@ -2514,15 +2500,15 @@ dependencies = [
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.9.3" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec",
"windows-sys", "windows-sys 0.42.0",
] ]
[[package]] [[package]]
@ -2747,9 +2733,9 @@ dependencies = [
[[package]] [[package]]
name = "psm" name = "psm"
version = "0.1.16" version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69" checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -2798,7 +2784,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [ dependencies = [
"getrandom 0.1.14", "getrandom 0.1.16",
"libc", "libc",
"rand_chacha 0.2.2", "rand_chacha 0.2.2",
"rand_core 0.5.1", "rand_core 0.5.1",
@ -2842,7 +2828,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [ dependencies = [
"getrandom 0.1.14", "getrandom 0.1.16",
] ]
[[package]] [[package]]
@ -3278,7 +3264,7 @@ dependencies = [
"cstr", "cstr",
"libc", "libc",
"measureme", "measureme",
"object 0.29.0", "object",
"rustc-demangle", "rustc-demangle",
"rustc_ast", "rustc_ast",
"rustc_attr", "rustc_attr",
@ -3312,7 +3298,7 @@ dependencies = [
"itertools", "itertools",
"jobserver", "jobserver",
"libc", "libc",
"object 0.29.0", "object",
"pathdiff", "pathdiff",
"regex", "regex",
"rustc_arena", "rustc_arena",
@ -3645,7 +3631,6 @@ dependencies = [
name = "rustc_interface" name = "rustc_interface"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"libc",
"libloading", "libloading",
"rustc-rayon", "rustc-rayon",
"rustc-rayon-core", "rustc-rayon-core",
@ -3688,7 +3673,6 @@ dependencies = [
"rustc_ty_utils", "rustc_ty_utils",
"smallvec", "smallvec",
"tracing", "tracing",
"winapi",
] ]
[[package]] [[package]]
@ -4108,6 +4092,7 @@ name = "rustc_session"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"getopts", "getopts",
"libc",
"rustc_ast", "rustc_ast",
"rustc_data_structures", "rustc_data_structures",
"rustc_errors", "rustc_errors",
@ -4119,7 +4104,9 @@ dependencies = [
"rustc_serialize", "rustc_serialize",
"rustc_span", "rustc_span",
"rustc_target", "rustc_target",
"smallvec",
"tracing", "tracing",
"winapi",
] ]
[[package]] [[package]]
@ -4609,9 +4596,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e"
[[package]] [[package]]
name = "snapbox" name = "snapbox"
version = "0.3.3" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7" checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293"
dependencies = [ dependencies = [
"concolor", "concolor",
"content_inspector", "content_inspector",
@ -4649,9 +4636,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "stacker" name = "stacker"
version = "0.1.14" version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90939d5171a4420b3ff5fbc8954d641e7377335454c259dcb80786f3f21dc9b4" checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",
@ -4670,7 +4657,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
name = "std" name = "std"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"addr2line 0.16.0", "addr2line",
"alloc", "alloc",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
@ -4680,8 +4667,8 @@ dependencies = [
"hashbrown", "hashbrown",
"hermit-abi 0.2.6", "hermit-abi 0.2.6",
"libc", "libc",
"miniz_oxide 0.4.0", "miniz_oxide",
"object 0.26.2", "object",
"panic_abort", "panic_abort",
"panic_unwind", "panic_unwind",
"profiler_builtins", "profiler_builtins",
@ -4868,9 +4855,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thin-vec" name = "thin-vec"
version = "0.2.8" version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87" checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
@ -4898,9 +4885,9 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6cb0c7868d7f90407531108ab03263d9452a8811b7cdd87675343a40d4aa254" checksum = "e6cb0c7868d7f90407531108ab03263d9452a8811b7cdd87675343a40d4aa254"
dependencies = [ dependencies = [
"gimli 0.26.1", "gimli",
"hashbrown", "hashbrown",
"object 0.29.0", "object",
"tracing", "tracing",
] ]
@ -4918,7 +4905,9 @@ name = "tidy"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cargo_metadata 0.14.0", "cargo_metadata 0.14.0",
"ignore",
"lazy_static", "lazy_static",
"miropt-test-tools",
"regex", "regex",
"walkdir", "walkdir",
] ]
@ -4939,9 +4928,12 @@ dependencies = [
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.3.4" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2"
dependencies = [
"displaydoc",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
@ -5177,9 +5169,9 @@ dependencies = [
[[package]] [[package]]
name = "unic-langid" name = "unic-langid"
version = "0.9.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"
dependencies = [ dependencies = [
"unic-langid-impl", "unic-langid-impl",
"unic-langid-macros", "unic-langid-macros",
@ -5187,18 +5179,18 @@ dependencies = [
[[package]] [[package]]
name = "unic-langid-impl" name = "unic-langid-impl"
version = "0.9.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"
dependencies = [ dependencies = [
"tinystr", "tinystr",
] ]
[[package]] [[package]]
name = "unic-langid-macros" name = "unic-langid-macros"
version = "0.9.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18f980d6d87e8805f2836d64b4138cc95aa7986fa63b1f51f67d5fbff64dd6e5" checksum = "055e618bf694161ffff0466d95cef3e1a5edc59f6ba1888e97801f2b4ebdc4fe"
dependencies = [ dependencies = [
"proc-macro-hack", "proc-macro-hack",
"tinystr", "tinystr",
@ -5208,9 +5200,9 @@ dependencies = [
[[package]] [[package]]
name = "unic-langid-macros-impl" name = "unic-langid-macros-impl"
version = "0.9.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29396ffd97e27574c3e01368b1a64267d3064969e4848e2e130ff668be9daa9f" checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8"
dependencies = [ dependencies = [
"proc-macro-hack", "proc-macro-hack",
"quote", "quote",
@ -5334,7 +5326,7 @@ name = "unwind"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if 0.1.10", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",
@ -5453,46 +5445,103 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.36.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
dependencies = [ dependencies = [
"windows_aarch64_msvc", "windows_aarch64_msvc 0.28.0",
"windows_i686_gnu", "windows_i686_gnu 0.28.0",
"windows_i686_msvc", "windows_i686_msvc 0.28.0",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.28.0",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.28.0",
] ]
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows-sys"
version = "0.36.1" version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0",
"windows_i686_gnu 0.42.0",
"windows_i686_msvc 0.42.0",
"windows_x86_64_gnu 0.42.0",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.36.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.36.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.36.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.36.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]] [[package]]
name = "xattr" name = "xattr"

View File

@ -11,6 +11,7 @@ members = [
"src/tools/error_index_generator", "src/tools/error_index_generator",
"src/tools/linkchecker", "src/tools/linkchecker",
"src/tools/lint-docs", "src/tools/lint-docs",
"src/tools/miropt-test-tools",
"src/tools/rustbook", "src/tools/rustbook",
"src/tools/unstable-book-gen", "src/tools/unstable-book-gen",
"src/tools/tidy", "src/tools/tidy",

View File

@ -1,9 +0,0 @@
Copyright (c) <year> <owner>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,3 +1,109 @@
Version 1.65.0 (2022-11-03)
==========================
Language
--------
- [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/)
- [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/)
- [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/)
- [Add lints `let_underscore_drop` and `let_underscore_lock` from Clippy](https://github.com/rust-lang/rust/pull/97739/)
- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/)
- [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/).
Usage of `MaybeUninit` is the correct way to work with uninitialized memory.
- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a](https://github.com/rust-lang/rust/pull/99916/)
- [Do not allow `Drop` impl on foreign ADTs](https://github.com/rust-lang/rust/pull/99576/)
Compiler
--------
- [Stabilize -Csplit-debuginfo on Linux](https://github.com/rust-lang/rust/pull/98051/)
- [Use niche-filling optimization even when multiple variants have data](https://github.com/rust-lang/rust/pull/94075/)
- [Associated type projections are now verified to be well-formed prior to resolving the underlying type](https://github.com/rust-lang/rust/pull/99217/#issuecomment-1209365630)
- [Stringify non-shorthand visibility correctly](https://github.com/rust-lang/rust/pull/100350/)
- [Normalize struct field types when unsizing](https://github.com/rust-lang/rust/pull/101831/)
- [Update to LLVM 15](https://github.com/rust-lang/rust/pull/99464/)
- [Fix aarch64 call abi to correctly zeroext when needed](https://github.com/rust-lang/rust/pull/97800/)
- [debuginfo: Generalize C++-like encoding for enums](https://github.com/rust-lang/rust/pull/98393/)
- [Add `special_module_name` lint](https://github.com/rust-lang/rust/pull/94467/)
- [Add support for generating unique profraw files by default when using `-C instrument-coverage`](https://github.com/rust-lang/rust/pull/100384/)
- [Allow dynamic linking for iOS/tvOS targets](https://github.com/rust-lang/rust/pull/100636/)
New targets:
- [Add armv4t-none-eabi as a tier 3 target](https://github.com/rust-lang/rust/pull/100244/)
- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets](https://github.com/rust-lang/rust/pull/101025/)
- Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.
Libraries
---------
- [Don't generate `PartialEq::ne` in derive(PartialEq)](https://github.com/rust-lang/rust/pull/98655/)
- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default](https://github.com/rust-lang/rust/pull/101325/)
- [Forbid mixing `System` with direct system allocator calls](https://github.com/rust-lang/rust/pull/101394/)
- [Document no support for writing to non-blocking stdio/stderr](https://github.com/rust-lang/rust/pull/101416/)
- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295)
This also changes the safety conditions on `Layout::from_size_align_unchecked`.
Stabilized APIs
---------------
- [`std::backtrace::Backtrace`](https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html)
- [`Bound::as_ref`](https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref)
- [`std::io::read_to_string`](https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html)
- [`<*const T>::cast_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut)
- [`<*mut T>::cast_const`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const)
These APIs are now stable in const contexts:
- [`<*const T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
- [`<*mut T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
Cargo
-----
- [Apply GitHub fast path even for partial hashes](https://github.com/rust-lang/cargo/pull/10807/)
- [Do not add home bin path to PATH if it's already there](https://github.com/rust-lang/cargo/pull/11023/)
- [Take priority into account within the pending queue](https://github.com/rust-lang/cargo/pull/11032/).
This slightly optimizes job scheduling by Cargo, with typically small improvements on larger crate graph builds.
Compatibility Notes
-------------------
- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295).
This also changes the safety conditions on `Layout::from_size_align_unchecked`.
- [`PollFn` now only implements `Unpin` if the closure is `Unpin`](https://github.com/rust-lang/rust/pull/102737).
This is a possible breaking change if users were relying on the blanket unpin implementation.
See discussion on the PR for details of why this change was made.
- [Drop ExactSizeIterator impl from std::char::EscapeAscii](https://github.com/rust-lang/rust/pull/99880)
This is a backwards-incompatible change to the standard library's surface
area, but is unlikely to affect real world usage.
- [Do not consider a single repeated lifetime eligible for elision in the return type](https://github.com/rust-lang/rust/pull/103450)
This behavior was unintentionally changed in 1.64.0, and this release reverts that change by making this an error again.
- [Reenable disabled early syntax gates as future-incompatibility lints](https://github.com/rust-lang/rust/pull/99935/)
- [Update the minimum external LLVM to 13](https://github.com/rust-lang/rust/pull/100460/)
- [Don't duplicate file descriptors into stdio fds](https://github.com/rust-lang/rust/pull/101426/)
- [Sunset RLS](https://github.com/rust-lang/rust/pull/100863/)
- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the crate type](https://github.com/rust-lang/rust/pull/99784/)
This strengthens the forward compatibility lint deprecated_cfg_attr_crate_type_name to deny.
- [`llvm-has-rust-patches` allows setting the build system to treat the LLVM as having Rust-specific patches](https://github.com/rust-lang/rust/pull/101072)
This option may need to be set for distributions that are building Rust with a patched LLVM via `llvm-config`, not the built-in LLVM.
- Combining three or more languages (e.g. Objective C, C++ and Rust) into one binary may hit linker limitations when using `lld`. For more information, see [issue 102754][102754].
[102754]: https://github.com/rust-lang/rust/issues/102754
Internal Changes
----------------
These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
- [Add `x.sh` and `x.ps1` shell scripts](https://github.com/rust-lang/rust/pull/99992/)
- [compiletest: use target cfg instead of hard-coded tables](https://github.com/rust-lang/rust/pull/100260/)
- [Use object instead of LLVM for reading bitcode from rlibs](https://github.com/rust-lang/rust/pull/98100/)
- [Enable MIR inlining for optimized compilations](https://github.com/rust-lang/rust/pull/91743)
This provides a 3-10% improvement in compiletimes for real world crates. See [perf results](https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u).
Version 1.64.0 (2022-09-22) Version 1.64.0 (2022-09-22)
=========================== ===========================

View File

@ -1,3 +1,5 @@
#![feature(unix_sigpipe)]
// A note about jemalloc: rustc uses jemalloc when built for CI and // A note about jemalloc: rustc uses jemalloc when built for CI and
// distribution. The obvious way to do this is with the `#[global_allocator]` // distribution. The obvious way to do this is with the `#[global_allocator]`
// mechanism. However, for complicated reasons (see // mechanism. However, for complicated reasons (see
@ -23,6 +25,7 @@
// libraries. So we must reference jemalloc symbols one way or another, because // libraries. So we must reference jemalloc symbols one way or another, because
// this file is the only object code in the rustc executable. // this file is the only object code in the rustc executable.
#[unix_sigpipe = "sig_dfl"]
fn main() { fn main() {
// See the comment at the top of this file for an explanation of this. // See the comment at the top of this file for an explanation of this.
#[cfg(feature = "jemalloc-sys")] #[cfg(feature = "jemalloc-sys")]
@ -58,6 +61,5 @@ fn main() {
} }
} }
rustc_driver::set_sigpipe_handler();
rustc_driver::main() rustc_driver::main()
} }

View File

@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" } rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View File

@ -392,15 +392,7 @@ pub struct Generics {
impl Default for Generics { impl Default for Generics {
/// Creates an instance of `Generics`. /// Creates an instance of `Generics`.
fn default() -> Generics { fn default() -> Generics {
Generics { Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP }
params: Vec::new(),
where_clause: WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: DUMMY_SP,
},
span: DUMMY_SP,
}
} }
} }
@ -415,6 +407,12 @@ pub struct WhereClause {
pub span: Span, pub span: Span,
} }
impl Default for WhereClause {
fn default() -> WhereClause {
WhereClause { has_where_token: false, predicates: Vec::new(), span: DUMMY_SP }
}
}
/// A single predicate in a where-clause. /// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicate { pub enum WherePredicate {
@ -1112,24 +1110,6 @@ pub struct Expr {
} }
impl Expr { impl Expr {
/// Returns `true` if this expression would be valid somewhere that expects a value;
/// for example, an `if` condition.
pub fn returns(&self) -> bool {
if let ExprKind::Block(ref block, _) = self.kind {
match block.stmts.last().map(|last_stmt| &last_stmt.kind) {
// Implicit return
Some(StmtKind::Expr(_)) => true,
// Last statement is an explicit return?
Some(StmtKind::Semi(expr)) => matches!(expr.kind, ExprKind::Ret(_)),
// This is a block that doesn't end in either an implicit or explicit return.
_ => false,
}
} else {
// This is not a block, it is a value.
true
}
}
/// Is this expr either `N`, or `{ N }`. /// Is this expr either `N`, or `{ N }`.
/// ///
/// If this is not the case, name resolution does not resolve `N` when using /// If this is not the case, name resolution does not resolve `N` when using
@ -1226,7 +1206,7 @@ impl Expr {
ExprKind::Tup(_) => ExprPrecedence::Tup, ExprKind::Tup(_) => ExprPrecedence::Tup,
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
ExprKind::Unary(..) => ExprPrecedence::Unary, ExprKind::Unary(..) => ExprPrecedence::Unary,
ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
ExprKind::Let(..) => ExprPrecedence::Let, ExprKind::Let(..) => ExprPrecedence::Let,
ExprKind::If(..) => ExprPrecedence::If, ExprKind::If(..) => ExprPrecedence::If,
@ -1464,6 +1444,12 @@ pub enum ExprKind {
/// with an optional value to be returned. /// with an optional value to be returned.
Yeet(Option<P<Expr>>), Yeet(Option<P<Expr>>),
/// Bytes included via `include_bytes!`
/// Added for optimization purposes to avoid the need to escape
/// large binary blobs - should always behave like [`ExprKind::Lit`]
/// with a `ByteStr` literal.
IncludedBytes(Lrc<[u8]>),
/// Placeholder for an expression that wasn't syntactically well formed in some way. /// Placeholder for an expression that wasn't syntactically well formed in some way.
Err, Err,
} }

View File

@ -29,6 +29,7 @@ extern crate rustc_macros;
extern crate tracing; extern crate tracing;
pub mod util { pub mod util {
pub mod case;
pub mod classify; pub mod classify;
pub mod comments; pub mod comments;
pub mod literal; pub mod literal;

View File

@ -152,6 +152,12 @@ pub trait MutVisitor: Sized {
noop_visit_expr(e, self); noop_visit_expr(e, self);
} }
/// This method is a hack to workaround unstable of `stmt_expr_attributes`.
/// It can be removed once that feature is stabilized.
fn visit_method_receiver_expr(&mut self, ex: &mut P<Expr>) {
self.visit_expr(ex)
}
fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
noop_filter_map_expr(e, self) noop_filter_map_expr(e, self)
} }
@ -1301,7 +1307,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_ident(ident); vis.visit_ident(ident);
vis.visit_id(id); vis.visit_id(id);
visit_opt(args, |args| vis.visit_generic_args(args)); visit_opt(args, |args| vis.visit_generic_args(args));
vis.visit_expr(receiver); vis.visit_method_receiver_expr(receiver);
visit_exprs(exprs, vis); visit_exprs(exprs, vis);
vis.visit_span(span); vis.visit_span(span);
} }
@ -1422,7 +1428,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
} }
ExprKind::Try(expr) => vis.visit_expr(expr), ExprKind::Try(expr) => vis.visit_expr(expr),
ExprKind::TryBlock(body) => vis.visit_block(body), ExprKind::TryBlock(body) => vis.visit_block(body),
ExprKind::Lit(_) | ExprKind::Err => {} ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
} }
vis.visit_id(id); vis.visit_id(id);
vis.visit_span(span); vis.visit_span(span);
@ -1589,3 +1595,9 @@ impl DummyAstNode for Crate {
} }
} }
} }
impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNodeWrapper<N, T> {
fn dummy() -> Self {
crate::ast_traits::AstNodeWrapper::new(N::dummy(), T::dummy())
}
}

View File

@ -5,6 +5,7 @@ pub use TokenKind::*;
use crate::ast; use crate::ast;
use crate::ptr::P; use crate::ptr::P;
use crate::util::case::Case;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -615,6 +616,15 @@ impl Token {
self.is_non_raw_ident_where(|id| id.name == kw) self.is_non_raw_ident_where(|id| id.name == kw)
} }
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool {
self.is_keyword(kw)
|| (case == Case::Insensitive
&& self.is_non_raw_ident_where(|id| {
id.name.as_str().to_lowercase() == kw.as_str().to_lowercase()
}))
}
pub fn is_path_segment_keyword(&self) -> bool { pub fn is_path_segment_keyword(&self) -> bool {
self.is_non_raw_ident_where(Ident::is_path_segment_keyword) self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
} }

View File

@ -0,0 +1,6 @@
/// Whatever to ignore case (`fn` vs `Fn` vs `FN`) or not. Used for recovering.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Case {
Sensitive,
Insensitive,
}

View File

@ -2,12 +2,10 @@
use crate::ast::{self, Lit, LitKind}; use crate::ast::{self, Lit, LitKind};
use crate::token::{self, Token}; use crate::token::{self, Token};
use rustc_data_structures::sync::Lrc;
use rustc_lexer::unescape::{unescape_byte, unescape_char}; use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode};
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
use std::ascii; use std::ascii;
pub enum LitError { pub enum LitError {
@ -109,15 +107,13 @@ impl LitKind {
let s = symbol.as_str(); let s = symbol.as_str();
let mut buf = Vec::with_capacity(s.len()); let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| { unescape_literal(&s, Mode::ByteStr, &mut |_, c| match c {
match unescaped_byte { Ok(c) => buf.push(byte_from_char(c)),
Ok(c) => buf.push(c),
Err(err) => { Err(err) => {
if err.is_fatal() { if err.is_fatal() {
error = Err(LitError::LexerError); error = Err(LitError::LexerError);
} }
} }
}
}); });
error?; error?;
LitKind::ByteStr(buf.into()) LitKind::ByteStr(buf.into())
@ -127,15 +123,13 @@ impl LitKind {
let bytes = if s.contains('\r') { let bytes = if s.contains('\r') {
let mut buf = Vec::with_capacity(s.len()); let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| { unescape_literal(&s, Mode::RawByteStr, &mut |_, c| match c {
match unescaped_byte { Ok(c) => buf.push(byte_from_char(c)),
Ok(c) => buf.push(c),
Err(err) => { Err(err) => {
if err.is_fatal() { if err.is_fatal() {
error = Err(LitError::LexerError); error = Err(LitError::LexerError);
} }
} }
}
}); });
error?; error?;
buf buf
@ -238,6 +232,13 @@ impl Lit {
Lit { token_lit: kind.to_token_lit(), kind, span } Lit { token_lit: kind.to_token_lit(), kind, span }
} }
/// Recovers an AST literal from a string of bytes produced by `include_bytes!`.
/// This requires ASCII-escaping the string, which can result in poor performance
/// for very large strings of bytes.
pub fn from_included_bytes(bytes: &Lrc<[u8]>, span: Span) -> Lit {
Self::from_lit_kind(LitKind::ByteStr(bytes.clone()), span)
}
/// Losslessly convert an AST literal into a token. /// Losslessly convert an AST literal into a token.
pub fn to_token(&self) -> Token { pub fn to_token(&self) -> Token {
let kind = match self.token_lit.kind { let kind = match self.token_lit.kind {

View File

@ -140,6 +140,11 @@ pub trait Visitor<'ast>: Sized {
fn visit_expr(&mut self, ex: &'ast Expr) { fn visit_expr(&mut self, ex: &'ast Expr) {
walk_expr(self, ex) walk_expr(self, ex)
} }
/// This method is a hack to workaround unstable of `stmt_expr_attributes`.
/// It can be removed once that feature is stabilized.
fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) {
self.visit_expr(ex)
}
fn visit_expr_post(&mut self, _ex: &'ast Expr) {} fn visit_expr_post(&mut self, _ex: &'ast Expr) {}
fn visit_ty(&mut self, t: &'ast Ty) { fn visit_ty(&mut self, t: &'ast Ty) {
walk_ty(self, t) walk_ty(self, t)
@ -246,7 +251,7 @@ pub trait Visitor<'ast>: Sized {
macro_rules! walk_list { macro_rules! walk_list {
($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => { ($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => {
{ {
#[cfg_attr(not(bootstrap), allow(for_loops_over_fallibles))] #[allow(for_loops_over_fallibles)]
for elem in $list { for elem in $list {
$visitor.$method(elem $(, $($extra_args,)* )?) $visitor.$method(elem $(, $($extra_args,)* )?)
} }
@ -896,7 +901,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
} }
ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression),
ExprKind::TryBlock(ref body) => visitor.visit_block(body), ExprKind::TryBlock(ref body) => visitor.visit_block(body),
ExprKind::Lit(_) | ExprKind::Err => {} ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
} }
visitor.visit_expr_post(expression) visitor.visit_expr_post(expression)

View File

@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View File

@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> {
pub struct SubTupleBinding<'a> { pub struct SubTupleBinding<'a> {
#[primary_span] #[primary_span]
#[label] #[label]
#[suggestion_verbose( #[suggestion(
ast_lowering_sub_tuple_binding_suggestion, ast_lowering_sub_tuple_binding_suggestion,
style = "verbose",
code = "..", code = "..",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]

View File

@ -87,6 +87,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Lit(ref l) => { ExprKind::Lit(ref l) => {
hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone())) hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone()))
} }
ExprKind::IncludedBytes(ref bytes) => hir::ExprKind::Lit(respan(
self.lower_span(e.span),
LitKind::ByteStr(bytes.clone()),
)),
ExprKind::Cast(ref expr, ref ty) => { ExprKind::Cast(ref expr, ref ty) => {
let expr = self.lower_expr(expr); let expr = self.lower_expr(expr);
let ty = let ty =

View File

@ -112,19 +112,19 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_nested_item(&mut self, item: ItemId) { fn visit_nested_item(&mut self, item: ItemId) {
debug!("visit_nested_item: {:?}", item); debug!("visit_nested_item: {:?}", item);
self.insert_nested(item.def_id.def_id); self.insert_nested(item.owner_id.def_id);
} }
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) { fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
self.insert_nested(item_id.def_id.def_id); self.insert_nested(item_id.owner_id.def_id);
} }
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) { fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
self.insert_nested(item_id.def_id.def_id); self.insert_nested(item_id.owner_id.def_id);
} }
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) { fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
self.insert_nested(foreign_id.def_id.def_id); self.insert_nested(foreign_id.owner_id.def_id);
} }
fn visit_nested_body(&mut self, id: BodyId) { fn visit_nested_body(&mut self, id: BodyId) {
@ -143,7 +143,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_item(&mut self, i: &'hir Item<'hir>) { fn visit_item(&mut self, i: &'hir Item<'hir>) {
debug_assert_eq!(i.def_id, self.owner); debug_assert_eq!(i.owner_id, self.owner);
self.with_parent(i.hir_id(), |this| { self.with_parent(i.hir_id(), |this| {
if let ItemKind::Struct(ref struct_def, _) = i.kind { if let ItemKind::Struct(ref struct_def, _) = i.kind {
// If this is a tuple or unit-like struct, register the constructor. // If this is a tuple or unit-like struct, register the constructor.
@ -157,7 +157,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) { fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
debug_assert_eq!(fi.def_id, self.owner); debug_assert_eq!(fi.owner_id, self.owner);
self.with_parent(fi.hir_id(), |this| { self.with_parent(fi.hir_id(), |this| {
intravisit::walk_foreign_item(this, fi); intravisit::walk_foreign_item(this, fi);
}); });
@ -176,7 +176,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) { fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
debug_assert_eq!(ti.def_id, self.owner); debug_assert_eq!(ti.owner_id, self.owner);
self.with_parent(ti.hir_id(), |this| { self.with_parent(ti.hir_id(), |this| {
intravisit::walk_trait_item(this, ti); intravisit::walk_trait_item(this, ti);
}); });
@ -184,7 +184,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) { fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
debug_assert_eq!(ii.def_id, self.owner); debug_assert_eq!(ii.owner_id, self.owner);
self.with_parent(ii.hir_id(), |this| { self.with_parent(ii.hir_id(), |this| {
intravisit::walk_impl_item(this, ii); intravisit::walk_impl_item(this, ii);
}); });

View File

@ -178,7 +178,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let mut node_ids = let mut node_ids =
smallvec![hir::ItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }]; smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
if let ItemKind::Use(ref use_tree) = &i.kind { if let ItemKind::Use(ref use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids); self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
} }
@ -195,7 +195,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
UseTreeKind::Nested(ref nested_vec) => { UseTreeKind::Nested(ref nested_vec) => {
for &(ref nested, id) in nested_vec { for &(ref nested, id) in nested_vec {
vec.push(hir::ItemId { vec.push(hir::ItemId {
def_id: hir::OwnerId { def_id: self.local_def_id(id) }, owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
}); });
self.lower_item_id_use_tree(nested, id, vec); self.lower_item_id_use_tree(nested, id, vec);
} }
@ -206,7 +206,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2]) iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
{ {
vec.push(hir::ItemId { vec.push(hir::ItemId {
def_id: hir::OwnerId { def_id: self.local_def_id(id) }, owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
}); });
} }
} }
@ -220,7 +220,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let attrs = self.lower_attrs(hir_id, &i.attrs); let attrs = self.lower_attrs(hir_id, &i.attrs);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
let item = hir::Item { let item = hir::Item {
def_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
ident: self.lower_ident(ident), ident: self.lower_ident(ident),
kind, kind,
vis_span, vis_span,
@ -562,7 +562,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
let item = hir::Item { let item = hir::Item {
def_id: hir::OwnerId { def_id: new_id }, owner_id: hir::OwnerId { def_id: new_id },
ident: this.lower_ident(ident), ident: this.lower_ident(ident),
kind, kind,
vis_span, vis_span,
@ -640,7 +640,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
let item = hir::Item { let item = hir::Item {
def_id: hir::OwnerId { def_id: new_hir_id }, owner_id: hir::OwnerId { def_id: new_hir_id },
ident: this.lower_ident(ident), ident: this.lower_ident(ident),
kind, kind,
vis_span, vis_span,
@ -660,10 +660,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = self.lower_node_id(i.id); let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner(); let owner_id = hir_id.expect_owner();
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let item = hir::ForeignItem { let item = hir::ForeignItem {
def_id, owner_id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
kind: match i.kind { kind: match i.kind {
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
@ -702,7 +702,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef { fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
hir::ForeignItemRef { hir::ForeignItemRef {
id: hir::ForeignItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }, id: hir::ForeignItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
span: self.lower_span(i.span), span: self.lower_span(i.span),
} }
@ -845,7 +845,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let item = hir::TraitItem { let item = hir::TraitItem {
def_id: trait_item_def_id, owner_id: trait_item_def_id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
generics, generics,
kind, kind,
@ -864,7 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
AssocItemKind::MacCall(..) => unimplemented!(), AssocItemKind::MacCall(..) => unimplemented!(),
}; };
let id = hir::TraitItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }; let id = hir::TraitItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
hir::TraitItemRef { hir::TraitItemRef {
id, id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
@ -931,7 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = self.lower_node_id(i.id); let hir_id = self.lower_node_id(i.id);
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let item = hir::ImplItem { let item = hir::ImplItem {
def_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
generics, generics,
kind, kind,
@ -944,7 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef { fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
hir::ImplItemRef { hir::ImplItemRef {
id: hir::ImplItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }, id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
span: self.lower_span(i.span), span: self.lower_span(i.span),
kind: match &i.kind { kind: match &i.kind {

View File

@ -1574,7 +1574,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`. // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
hir::TyKind::OpaqueDef( hir::TyKind::OpaqueDef(
hir::ItemId { def_id: hir::OwnerId { def_id: opaque_ty_def_id } }, hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
lifetimes, lifetimes,
in_trait, in_trait,
) )
@ -1593,7 +1593,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Generate an `type Foo = impl Trait;` declaration. // Generate an `type Foo = impl Trait;` declaration.
trace!("registering opaque type with id {:#?}", opaque_ty_id); trace!("registering opaque type with id {:#?}", opaque_ty_id);
let opaque_ty_item = hir::Item { let opaque_ty_item = hir::Item {
def_id: hir::OwnerId { def_id: opaque_ty_id }, owner_id: hir::OwnerId { def_id: opaque_ty_id },
ident: Ident::empty(), ident: Ident::empty(),
kind: opaque_ty_item_kind, kind: opaque_ty_item_kind,
vis_span: self.lower_span(span.shrink_to_lo()), vis_span: self.lower_span(span.shrink_to_lo()),
@ -2044,7 +2044,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// 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. // only the lifetime parameters that we must supply.
let opaque_ty_ref = hir::TyKind::OpaqueDef( let opaque_ty_ref = hir::TyKind::OpaqueDef(
hir::ItemId { def_id: hir::OwnerId { def_id: opaque_ty_def_id } }, hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
generic_args, generic_args,
in_trait, in_trait,
); );

View File

@ -323,7 +323,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// ``` // ```
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> { fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
match expr.kind { match expr.kind {
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {} ExprKind::Lit(..)
| ExprKind::ConstBlock(..)
| ExprKind::IncludedBytes(..)
| ExprKind::Err => {}
ExprKind::Path(..) if allow_paths => {} ExprKind::Path(..) if allow_paths => {}
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
_ => { _ => {

View File

@ -191,7 +191,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
} }
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Ok => {
self.lower_parenthesized_parameter_data(data, itctx)
}
ParenthesizedGenericArgs::Err => { ParenthesizedGenericArgs::Err => {
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
let sub = if !data.inputs.is_empty() { let sub = if !data.inputs.is_empty() {
@ -344,6 +346,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_parenthesized_parameter_data( fn lower_parenthesized_parameter_data(
&mut self, &mut self,
data: &ParenthesizedArgs, data: &ParenthesizedArgs,
itctx: &ImplTraitContext,
) -> (GenericArgsCtor<'hir>, bool) { ) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this // Switch to `PassThrough` mode for anonymous lifetimes; this
// means that we permit things like `&Ref<T>`, where `Ref` has // means that we permit things like `&Ref<T>`, where `Ref` has
@ -355,6 +358,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
})); }));
let output_ty = match output { let output_ty = match output {
// Only allow `impl Trait` in return position. i.e.:
// ```rust
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
// ```
FnRetTy::Ty(ty)
if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. })
&& self.tcx.features().impl_trait_in_fn_trait_return =>
{
self.lower_ty(&ty, itctx)
}
FnRetTy::Ty(ty) => { FnRetTy::Ty(ty) => {
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
} }

View File

@ -1051,6 +1051,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl); walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
}); });
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Impl(box Impl { ItemKind::Impl(box Impl {
@ -1168,7 +1169,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}); });
walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait); walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait);
walk_list!(self, visit_attribute, &item.attrs); walk_list!(self, visit_attribute, &item.attrs);
return; return; // Avoid visiting again
} }
ItemKind::Mod(unsafety, ref mod_kind) => { ItemKind::Mod(unsafety, ref mod_kind) => {
if let Unsafe::Yes(span) = unsafety { if let Unsafe::Yes(span) = unsafety {

View File

@ -1,7 +1,7 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId}; use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
use rustc_ast::{PatKind, RangeEnd, VariantData}; use rustc_ast::{PatKind, RangeEnd};
use rustc_errors::{struct_span_err, Applicability, StashKey}; use rustc_errors::{struct_span_err, Applicability, StashKey};
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
@ -116,46 +116,6 @@ impl<'a> PostExpansionVisitor<'a> {
} }
} }
fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
let has_fields = variants.iter().any(|variant| match variant.data {
VariantData::Tuple(..) | VariantData::Struct(..) => true,
VariantData::Unit(..) => false,
});
let discriminant_spans = variants
.iter()
.filter(|variant| match variant.data {
VariantData::Tuple(..) | VariantData::Struct(..) => false,
VariantData::Unit(..) => true,
})
.filter_map(|variant| variant.disr_expr.as_ref().map(|c| c.value.span))
.collect::<Vec<_>>();
if !discriminant_spans.is_empty() && has_fields {
let mut err = feature_err(
&self.sess.parse_sess,
sym::arbitrary_enum_discriminant,
discriminant_spans.clone(),
"custom discriminant values are not allowed in enums with tuple or struct variants",
);
for sp in discriminant_spans {
err.span_label(sp, "disallowed custom discriminant");
}
for variant in variants.iter() {
match &variant.data {
VariantData::Struct(..) => {
err.span_label(variant.span, "struct variant defined here");
}
VariantData::Tuple(..) => {
err.span_label(variant.span, "tuple variant defined here");
}
VariantData::Unit(..) => {}
}
}
err.emit();
}
}
/// Feature gate `impl Trait` inside `type Alias = $type_expr;`. /// Feature gate `impl Trait` inside `type Alias = $type_expr;`.
fn check_impl_trait(&self, ty: &ast::Ty) { fn check_impl_trait(&self, ty: &ast::Ty) {
struct ImplTraitVisitor<'a> { struct ImplTraitVisitor<'a> {
@ -273,26 +233,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
} }
} }
ast::ItemKind::Enum(ast::EnumDef { ref variants, .. }, ..) => {
for variant in variants {
match (&variant.data, &variant.disr_expr) {
(ast::VariantData::Unit(..), _) => {}
(_, Some(disr_expr)) => gate_feature_post!(
&self,
arbitrary_enum_discriminant,
disr_expr.value.span,
"discriminants on non-unit variants are experimental"
),
_ => {}
}
}
let has_feature = self.features.arbitrary_enum_discriminant;
if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
self.maybe_report_invalid_custom_discriminants(&variants);
}
}
ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => { ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => {
if let ast::ImplPolarity::Negative(span) = polarity { if let ast::ImplPolarity::Negative(span) = polarity {
gate_feature_post!( gate_feature_post!(

View File

@ -322,6 +322,10 @@ impl<'a> State<'a> {
ast::ExprKind::Lit(ref lit) => { ast::ExprKind::Lit(ref lit) => {
self.print_literal(lit); self.print_literal(lit);
} }
ast::ExprKind::IncludedBytes(ref bytes) => {
let lit = ast::Lit::from_included_bytes(bytes, expr.span);
self.print_literal(&lit)
}
ast::ExprKind::Cast(ref expr, ref ty) => { ast::ExprKind::Cast(ref expr, ref ty) => {
let prec = AssocOp::As.precedence() as i8; let prec = AssocOp::As.precedence() as i8;
self.print_expr_maybe_paren(expr, prec); self.print_expr_maybe_paren(expr, prec);

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::nll::ToRegionVid; use crate::nll::ToRegionVid;
use crate::path_utils::allow_two_phase_borrow; use crate::path_utils::allow_two_phase_borrow;
use crate::place_ext::PlaceExt; use crate::place_ext::PlaceExt;

View File

@ -8,9 +8,18 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn cannot_move_when_borrowed( pub(crate) fn cannot_move_when_borrowed(
&self, &self,
span: Span, span: Span,
desc: &str, borrow_span: Span,
place: &str,
borrow_place: &str,
value_place: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,) self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow {
place,
span,
borrow_place,
value_place,
borrow_span,
})
} }
pub(crate) fn cannot_use_when_mutably_borrowed( pub(crate) fn cannot_use_when_mutably_borrowed(

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_infer::infer::InferCtxt; use rustc_infer::infer::InferCtxt;
use rustc_middle::mir::visit::TyContext; use rustc_middle::mir::visit::TyContext;
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;

View File

@ -163,6 +163,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
span: DUMMY_SP, span: DUMMY_SP,
category: ConstraintCategory::Internal, category: ConstraintCategory::Internal,
variance_info: VarianceDiagInfo::default(), variance_info: VarianceDiagInfo::default(),
from_closure: false,
}) })
} else { } else {
None None

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::scc::Sccs;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
@ -92,10 +95,13 @@ pub struct OutlivesConstraint<'tcx> {
pub span: Span, pub span: Span,
/// What caused this constraint? /// What caused this constraint?
pub category: ConstraintCategory, pub category: ConstraintCategory<'tcx>,
/// Variance diagnostic information /// Variance diagnostic information
pub variance_info: VarianceDiagInfo<'tcx>, pub variance_info: VarianceDiagInfo<'tcx>,
/// If this constraint is promoted from closure requirements.
pub from_closure: bool,
} }
impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This file provides API for compiler consumers. //! This file provides API for compiler consumers.
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{self, BasicBlock, Body, Location, Place}; use rustc_middle::mir::{self, BasicBlock, Body, Location, Place};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_middle::mir::visit::{ use rustc_middle::mir::visit::{
MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
}; };

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
@ -5,14 +8,14 @@ use rustc_infer::infer::region_constraints::Constraint;
use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt}; use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::RegionVid; use rustc_middle::ty::RegionVid;
use rustc_middle::ty::UniverseIndex; use rustc_middle::ty::UniverseIndex;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::query::type_op; use rustc_trait_selection::traits::query::type_op;
use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _}; use rustc_trait_selection::traits::ObligationCtxt;
use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause}; use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
use std::fmt; use std::fmt;
@ -158,6 +161,7 @@ trait TypeOpInfo<'tcx> {
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>;
#[instrument(level = "debug", skip(self, mbcx))]
fn report_error( fn report_error(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
@ -167,6 +171,7 @@ trait TypeOpInfo<'tcx> {
) { ) {
let tcx = mbcx.infcx.tcx; let tcx = mbcx.infcx.tcx;
let base_universe = self.base_universe(); let base_universe = self.base_universe();
debug!(?base_universe);
let Some(adjusted_universe) = let Some(adjusted_universe) =
placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) placeholder.universe.as_u32().checked_sub(base_universe.as_u32())
@ -240,9 +245,9 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(infcx);
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause); type_op_prove_predicate_with_cause(&ocx, key, cause);
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
} }
} }
@ -281,9 +286,7 @@ where
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(infcx);
let mut selcx = SelectionContext::new(infcx);
// FIXME(lqd): Unify and de-duplicate the following with the actual // FIXME(lqd): Unify and de-duplicate the following with the actual
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the // `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
@ -292,11 +295,9 @@ where
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check // to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check
// after #85499 lands to see if its fixes have erased this difference. // after #85499 lands to see if its fixes have erased this difference.
let (param_env, value) = key.into_parts(); let (param_env, value) = key.into_parts();
let Normalized { value: _, obligations } = let _ = ocx.normalize(cause, param_env, value.value);
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
fulfill_cx.register_predicate_obligations(infcx, obligations);
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
} }
} }
@ -329,9 +330,9 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(infcx);
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?; type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
} }
} }
@ -372,28 +373,28 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
} }
} }
#[instrument(skip(fulfill_cx, infcx), level = "debug")] #[instrument(skip(ocx), level = "debug")]
fn try_extract_error_from_fulfill_cx<'tcx>( fn try_extract_error_from_fulfill_cx<'tcx>(
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
infcx: &InferCtxt<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
// We generally shouldn't have errors here because the query was // We generally shouldn't have errors here because the query was
// already run, but there's no point using `delay_span_bug` // already run, but there's no point using `delay_span_bug`
// when we're going to emit an error here anyway. // when we're going to emit an error here anyway.
let _errors = fulfill_cx.select_all_or_error(infcx); let _errors = ocx.select_all_or_error();
let region_constraints = infcx.with_region_constraints(|r| r.clone()); let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
try_extract_error_from_region_constraints( try_extract_error_from_region_constraints(
infcx, ocx.infcx,
placeholder_region, placeholder_region,
error_region, error_region,
&region_constraints, &region_constraints,
|vid| infcx.region_var_origin(vid), |vid| ocx.infcx.region_var_origin(vid),
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))), |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))),
) )
} }
#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
fn try_extract_error_from_region_constraints<'tcx>( fn try_extract_error_from_region_constraints<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,

View File

@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{BytePos, Span, Symbol}; use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::TraitEngineExt as _;
use crate::borrow_set::TwoPhaseActivation; use crate::borrow_set::TwoPhaseActivation;
use crate::borrowck_errors; use crate::borrowck_errors;
@ -225,10 +224,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
use_spans.var_span_label_path_only( use_spans.var_path_only_subdiag(&mut err, desired_action);
&mut err,
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
);
if !is_loop_move { if !is_loop_move {
err.span_label( err.span_label(
@ -405,10 +401,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let used = desired_action.as_general_verb_in_past_tense(); let used = desired_action.as_general_verb_in_past_tense();
let mut err = let mut err =
struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}"); struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}");
use_spans.var_span_label_path_only( use_spans.var_path_only_subdiag(&mut err, desired_action);
&mut err,
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
);
if let InitializationRequiringAction::PartialAssignment if let InitializationRequiringAction::PartialAssignment
| InitializationRequiringAction::Assignment = desired_action | InitializationRequiringAction::Assignment = desired_action
@ -613,24 +606,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
else { return; }; else { return; };
// Try to find predicates on *generic params* that would allow copying `ty` // Try to find predicates on *generic params* that would allow copying `ty`
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
let cause = ObligationCause::new( let cause = ObligationCause::new(
span, span,
self.mir_hir_id(), self.mir_hir_id(),
rustc_infer::traits::ObligationCauseCode::MiscObligation, rustc_infer::traits::ObligationCauseCode::MiscObligation,
); );
fulfill_cx.register_bound( let errors = rustc_trait_selection::traits::fully_solve_bound(
&infcx, &infcx,
cause,
self.param_env, self.param_env,
// Erase any region vids from the type, which may not be resolved // Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty), infcx.tcx.erase_regions(ty),
copy_did, copy_did,
cause,
); );
// Select all, including ambiguous predicates
let errors = fulfill_cx.select_all_or_error(&infcx);
// Only emit suggestion if all required predicates are on generic // Only emit suggestion if all required predicates are on generic
let predicates: Result<Vec<_>, _> = errors let predicates: Result<Vec<_>, _> = errors
@ -678,16 +667,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let move_spans = self.move_spans(place.as_ref(), location); let move_spans = self.move_spans(place.as_ref(), location);
let span = move_spans.args_or_use(); let span = move_spans.args_or_use();
let mut err = let mut err = self.cannot_move_when_borrowed(
self.cannot_move_when_borrowed(span, &self.describe_any_place(place.as_ref())); span,
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); borrow_span,
err.span_label(span, format!("move out of {} occurs here", value_msg)); &self.describe_any_place(place.as_ref()),
&borrow_msg,
borrow_spans.var_span_label_path_only( &value_msg,
&mut err,
format!("borrow occurs due to use{}", borrow_spans.describe()),
); );
borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
move_spans.var_span_label( move_spans.var_span_label(
&mut err, &mut err,
format!("move occurs due to use{}", move_spans.describe()), format!("move occurs due to use{}", move_spans.describe()),
@ -729,16 +718,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_span, borrow_span,
&self.describe_any_place(borrow.borrowed_place.as_ref()), &self.describe_any_place(borrow.borrowed_place.as_ref()),
); );
borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
borrow_spans.var_span_label( use crate::session_diagnostics::CaptureVarCause::*;
&mut err,
{
let place = &borrow.borrowed_place; let place = &borrow.borrowed_place;
let desc_place = self.describe_any_place(place.as_ref()); let desc_place = self.describe_any_place(place.as_ref());
format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe()) match kind {
}, Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
"mutable", None => BorrowUsePlaceClosure { place: desc_place, var_span },
); }
});
self.explain_why_borrow_contains_point(location, borrow, None) self.explain_why_borrow_contains_point(location, borrow, None)
.add_explanation_to_diagnostic( .add_explanation_to_diagnostic(
@ -983,7 +971,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err: &mut Diagnostic, err: &mut Diagnostic,
location: Location, location: Location,
issued_borrow: &BorrowData<'tcx>, issued_borrow: &BorrowData<'tcx>,
explanation: BorrowExplanation, explanation: BorrowExplanation<'tcx>,
) { ) {
let used_in_call = matches!( let used_in_call = matches!(
explanation, explanation,
@ -1333,7 +1321,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow: &BorrowData<'tcx>, borrow: &BorrowData<'tcx>,
drop_span: Span, drop_span: Span,
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
explanation: BorrowExplanation, explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
debug!( debug!(
"report_local_value_does_not_live_long_enough(\ "report_local_value_does_not_live_long_enough(\
@ -1539,7 +1527,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
drop_span: Span, drop_span: Span,
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
proper_span: Span, proper_span: Span,
explanation: BorrowExplanation, explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation explanation
@ -1556,7 +1544,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
let mut err = self.temporary_value_borrowed_for_too_long(proper_span); let mut err = self.temporary_value_borrowed_for_too_long(proper_span);
err.span_label(proper_span, "creates a temporary which is freed while still in use"); err.span_label(proper_span, "creates a temporary value which is freed while still in use");
err.span_label(drop_span, "temporary value is freed at the end of this statement"); err.span_label(drop_span, "temporary value is freed at the end of this statement");
match explanation { match explanation {
@ -1653,7 +1641,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow: &BorrowData<'tcx>, borrow: &BorrowData<'tcx>,
borrow_span: Span, borrow_span: Span,
return_span: Span, return_span: Span,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
opt_place_desc: Option<&String>, opt_place_desc: Option<&String>,
) -> Option<DiagnosticBuilder<'cx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'cx, ErrorGuaranteed>> {
let return_kind = match category { let return_kind = match category {
@ -1748,7 +1736,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
use_span: UseSpans<'tcx>, use_span: UseSpans<'tcx>,
var_span: Span, var_span: Span,
fr_name: &RegionName, fr_name: &RegionName,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
constraint_span: Span, constraint_span: Span,
captured_var: &str, captured_var: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {

View File

@ -21,7 +21,7 @@ use crate::{
use super::{find_use, RegionName, UseSpans}; use super::{find_use, RegionName, UseSpans};
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum BorrowExplanation { pub(crate) enum BorrowExplanation<'tcx> {
UsedLater(LaterUseKind, Span, Option<Span>), UsedLater(LaterUseKind, Span, Option<Span>),
UsedLaterInLoop(LaterUseKind, Span, Option<Span>), UsedLaterInLoop(LaterUseKind, Span, Option<Span>),
UsedLaterWhenDropped { UsedLaterWhenDropped {
@ -30,7 +30,7 @@ pub(crate) enum BorrowExplanation {
should_note_order: bool, should_note_order: bool,
}, },
MustBeValidFor { MustBeValidFor {
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
from_closure: bool, from_closure: bool,
span: Span, span: Span,
region_name: RegionName, region_name: RegionName,
@ -49,7 +49,7 @@ pub(crate) enum LaterUseKind {
Other, Other,
} }
impl<'tcx> BorrowExplanation { impl<'tcx> BorrowExplanation<'tcx> {
pub(crate) fn is_explained(&self) -> bool { pub(crate) fn is_explained(&self) -> bool {
!matches!(self, BorrowExplanation::Unexplained) !matches!(self, BorrowExplanation::Unexplained)
} }
@ -284,7 +284,7 @@ impl<'tcx> BorrowExplanation {
fn add_lifetime_bound_suggestion_to_diagnostic( fn add_lifetime_bound_suggestion_to_diagnostic(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
category: &ConstraintCategory, category: &ConstraintCategory<'tcx>,
span: Span, span: Span,
region_name: &RegionName, region_name: &RegionName,
) { ) {
@ -316,7 +316,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
borrow_region: RegionVid, borrow_region: RegionVid,
outlived_region: RegionVid, outlived_region: RegionVid,
) -> (ConstraintCategory, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) { ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) {
let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint( let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint(
borrow_region, borrow_region,
NllRegionVariableOrigin::FreeRegion, NllRegionVariableOrigin::FreeRegion,
@ -348,7 +348,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location, location: Location,
borrow: &BorrowData<'tcx>, borrow: &BorrowData<'tcx>,
kind_place: Option<(WriteKind, Place<'tcx>)>, kind_place: Option<(WriteKind, Place<'tcx>)>,
) -> BorrowExplanation { ) -> BorrowExplanation<'tcx> {
let regioncx = &self.regioncx; let regioncx = &self.regioncx;
let body: &Body<'_> = &self.body; let body: &Body<'_> = &self.body;
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::BTreeSet; use std::collections::BTreeSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::visit::{PlaceContext, Visitor};

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::VecDeque; use std::collections::VecDeque;
use std::rc::Rc; use std::rc::Rc;

View File

@ -595,11 +595,34 @@ impl UseSpans<'_> {
} }
} }
// Add a span label to the use of the captured variable, if it exists. /// Add a span label to the use of the captured variable, if it exists.
// only adds label to the `path_span` /// only adds label to the `path_span`
pub(super) fn var_span_label_path_only(self, err: &mut Diagnostic, message: impl Into<String>) { pub(super) fn var_path_only_subdiag(
if let UseSpans::ClosureUse { path_span, .. } = self { self,
err.span_label(path_span, message); err: &mut Diagnostic,
action: crate::InitializationRequiringAction,
) {
use crate::session_diagnostics::CaptureVarPathUseCause::*;
use crate::InitializationRequiringAction::*;
if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self {
match generator_kind {
Some(_) => {
err.subdiagnostic(match action {
Borrow => BorrowInGenerator { path_span },
MatchOn | Use => UseInGenerator { path_span },
Assignment => AssignInGenerator { path_span },
PartialAssignment => AssignPartInGenerator { path_span },
});
}
None => {
err.subdiagnostic(match action {
Borrow => BorrowInClosure { path_span },
MatchOn | Use => UseInClosure { path_span },
Assignment => AssignInClosure { path_span },
PartialAssignment => AssignPartInClosure { path_span },
});
}
}
} }
} }
@ -623,6 +646,35 @@ impl UseSpans<'_> {
} }
} }
/// Add a subdiagnostic to the use of the captured variable, if it exists.
pub(super) fn var_subdiag(
self,
err: &mut Diagnostic,
kind: Option<rustc_middle::mir::BorrowKind>,
f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
) {
use crate::session_diagnostics::CaptureVarKind::*;
if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
if capture_kind_span != path_span {
err.subdiagnostic(match kind {
Some(kd) => match kd {
rustc_middle::mir::BorrowKind::Shared
| rustc_middle::mir::BorrowKind::Shallow
| rustc_middle::mir::BorrowKind::Unique => {
Immute { kind_span: capture_kind_span }
}
rustc_middle::mir::BorrowKind::Mut { .. } => {
Mut { kind_span: capture_kind_span }
}
},
None => Move { kind_span: capture_kind_span },
});
};
err.subdiagnostic(f(generator_kind, path_span));
}
}
/// Returns `false` if this place is not used in a closure. /// Returns `false` if this place is not used in a closure.
pub(super) fn for_closure(&self) -> bool { pub(super) fn for_closure(&self) -> bool {
match *self { match *self {

View File

@ -1,6 +1,4 @@
use rustc_errors::{ use rustc_errors::{Applicability, Diagnostic};
Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::Node; use rustc_hir::Node;
@ -629,25 +627,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.buffer_error(err); self.buffer_error(err);
} }
fn suggest_map_index_mut_alternatives( fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) {
&self,
ty: Ty<'_>,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
span: Span,
) {
let Some(adt) = ty.ty_adt_def() else { return }; let Some(adt) = ty.ty_adt_def() else { return };
let did = adt.did(); let did = adt.did();
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
|| self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did) || self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
{ {
struct V<'a, 'b, 'tcx, G: EmissionGuarantee> { struct V<'a, 'tcx> {
assign_span: Span, assign_span: Span,
err: &'a mut DiagnosticBuilder<'b, G>, err: &'a mut Diagnostic,
ty: Ty<'tcx>, ty: Ty<'tcx>,
suggested: bool, suggested: bool,
} }
impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> { impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> {
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
hir::intravisit::walk_stmt(self, stmt); hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind { let expr = match stmt.kind {
hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr, hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
@ -705,7 +698,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
), ),
(rv.span.shrink_to_hi(), ")".to_string()), (rv.span.shrink_to_hi(), ")".to_string()),
], ],
].into_iter(), ],
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
self.suggested = true; self.suggested = true;

View File

@ -161,7 +161,7 @@ impl OutlivesSuggestionBuilder {
pub(crate) fn intermediate_suggestion( pub(crate) fn intermediate_suggestion(
&mut self, &mut self,
mbcx: &MirBorrowckCtxt<'_, '_>, mbcx: &MirBorrowckCtxt<'_, '_>,
errci: &ErrorConstraintInfo, errci: &ErrorConstraintInfo<'_>,
diag: &mut Diagnostic, diag: &mut Diagnostic,
) { ) {
// Emit an intermediate note. // Emit an intermediate note.

View File

@ -2,8 +2,7 @@
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
//! Error reporting machinery for lifetime errors. //! Error reporting machinery for lifetime errors.
use either::Either; use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -17,7 +16,7 @@ use rustc_infer::infer::{
NllRegionVariableOrigin, RelateParamBound, NllRegionVariableOrigin, RelateParamBound,
}; };
use rustc_middle::hir::place::PlaceBase; use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint, TerminatorKind}; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::Region; use rustc_middle::ty::Region;
use rustc_middle::ty::TypeVisitor; use rustc_middle::ty::TypeVisitor;
@ -40,7 +39,7 @@ use crate::{
MirBorrowckCtxt, MirBorrowckCtxt,
}; };
impl ConstraintDescription for ConstraintCategory { impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
// Must end with a space. Allows for empty names to be provided. // Must end with a space. Allows for empty names to be provided.
match self { match self {
@ -116,7 +115,7 @@ pub(crate) enum RegionErrorKind<'tcx> {
/// Information about the various region constraints involved in a borrow checker error. /// Information about the various region constraints involved in a borrow checker error.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ErrorConstraintInfo { pub struct ErrorConstraintInfo<'tcx> {
// fr: outlived_fr // fr: outlived_fr
pub(super) fr: RegionVid, pub(super) fr: RegionVid,
pub(super) fr_is_local: bool, pub(super) fr_is_local: bool,
@ -124,7 +123,7 @@ pub struct ErrorConstraintInfo {
pub(super) outlived_fr_is_local: bool, pub(super) outlived_fr_is_local: bool,
// Category and span for best blame constraint // Category and span for best blame constraint
pub(super) category: ConstraintCategory, pub(super) category: ConstraintCategory<'tcx>,
pub(super) span: Span, pub(super) span: Span,
} }
@ -182,7 +181,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// Try to convert the lower-bound region into something named we can print for the user. // Try to convert the lower-bound region into something named we can print for the user.
let lower_bound_region = self.to_error_region(type_test.lower_bound); let lower_bound_region = self.to_error_region(type_test.lower_bound);
let type_test_span = type_test.locations.span(&self.body); let type_test_span = type_test.span;
if let Some(lower_bound_region) = lower_bound_region { if let Some(lower_bound_region) = lower_bound_region {
let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx); let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx);
@ -277,7 +276,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn get_impl_ident_and_self_ty_from_trait( fn get_impl_ident_and_self_ty_from_trait(
&self, &self,
def_id: DefId, def_id: DefId,
trait_objects: &FxHashSet<DefId>, trait_objects: &FxIndexSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
match tcx.hir().get_if_local(def_id) { match tcx.hir().get_if_local(def_id) {
@ -499,7 +498,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// ``` /// ```
fn report_fnmut_error( fn report_fnmut_error(
&self, &self,
errci: &ErrorConstraintInfo, errci: &ErrorConstraintInfo<'tcx>,
kind: ReturnConstraint, kind: ReturnConstraint,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
@ -572,7 +571,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn report_escaping_data_error( fn report_escaping_data_error(
&self, &self,
errci: &ErrorConstraintInfo, errci: &ErrorConstraintInfo<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let ErrorConstraintInfo { span, category, .. } = errci; let ErrorConstraintInfo { span, category, .. } = errci;
@ -676,7 +675,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// ``` /// ```
fn report_general_error( fn report_general_error(
&self, &self,
errci: &ErrorConstraintInfo, errci: &ErrorConstraintInfo<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let ErrorConstraintInfo { let ErrorConstraintInfo {
fr, fr,
@ -789,7 +788,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
diag: &mut Diagnostic, diag: &mut Diagnostic,
f: Region<'tcx>, f: Region<'tcx>,
o: Region<'tcx>, o: Region<'tcx>,
category: &ConstraintCategory, category: &ConstraintCategory<'tcx>,
) { ) {
if !o.is_static() { if !o.is_static() {
return; return;
@ -797,12 +796,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let instance = let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
if let ConstraintCategory::CallArgument(location) = category
&& let Either::Right(term) = self.body.stmt_at(*location)
&& let TerminatorKind::Call { func, .. } = &term.kind
{
let func_ty = func.ty(self.body, tcx);
let (fn_did, substs) = match func_ty.kind() { let (fn_did, substs) = match func_ty.kind() {
ty::FnDef(fn_did, substs) => (fn_did, substs), ty::FnDef(fn_did, substs) => (fn_did, substs),
_ => return, _ => return,
@ -836,7 +830,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}; };
debug!(?param); debug!(?param);
let mut visitor = TraitObjectVisitor(FxHashSet::default()); let mut visitor = TraitObjectVisitor(FxIndexSet::default());
visitor.visit_ty(param.param_ty); visitor.visit_ty(param.param_ty);
let Some((ident, self_ty)) = let Some((ident, self_ty)) =
@ -849,7 +843,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn suggest_constrain_dyn_trait_in_impl( fn suggest_constrain_dyn_trait_in_impl(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
found_dids: &FxHashSet<DefId>, found_dids: &FxIndexSet<DefId>,
ident: Ident, ident: Ident,
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,
) -> bool { ) -> bool {

View File

@ -251,7 +251,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr)); .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
if let Some(ref value) = value { if let Some(ref value) = value {
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone()); self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
@ -354,7 +355,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}) })
} }
ty::BoundRegionKind::BrAnon(_) => None, ty::BoundRegionKind::BrAnon(..) => None,
}, },
ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None, ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None,
@ -869,13 +870,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None; return None;
} }
let mut found = false; let found = tcx
tcx.fold_regions(tcx.type_of(region_parent), |r: ty::Region<'tcx>, _| { .any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region));
if *r == ty::ReEarlyBound(region) {
found = true;
}
r
});
Some(RegionName { Some(RegionName {
name: self.synthesize_region_name(), name: self.synthesize_region_name(),
@ -888,4 +884,92 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
), ),
}) })
} }
fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait(
&self,
fr: RegionVid,
) -> Option<RegionName> {
let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else {
return None;
};
if region.has_name() {
return None;
};
let predicates = self
.infcx
.tcx
.predicates_of(self.body.source.def_id())
.instantiate_identity(self.infcx.tcx)
.predicates;
if let Some(upvar_index) = self
.regioncx
.universal_regions()
.defining_ty
.upvar_tys()
.position(|ty| self.any_param_predicate_mentions(&predicates, ty, region))
{
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
self.infcx.tcx,
&self.upvars,
upvar_index,
);
let region_name = self.synthesize_region_name();
Some(RegionName {
name: region_name,
source: RegionNameSource::AnonRegionFromUpvar(upvar_span, upvar_name),
})
} else if let Some(arg_index) = self
.regioncx
.universal_regions()
.unnormalized_input_tys
.iter()
.position(|ty| self.any_param_predicate_mentions(&predicates, *ty, region))
{
let (arg_name, arg_span) = self.regioncx.get_argument_name_and_span_for_region(
self.body,
&self.local_names,
arg_index,
);
let region_name = self.synthesize_region_name();
Some(RegionName {
name: region_name,
source: RegionNameSource::AnonRegionFromArgument(
RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?.to_string()),
),
})
} else {
None
}
}
fn any_param_predicate_mentions(
&self,
predicates: &[ty::Predicate<'tcx>],
ty: Ty<'tcx>,
region: ty::EarlyBoundRegion,
) -> bool {
let tcx = self.infcx.tcx;
ty.walk().any(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(_) = ty.kind()
{
predicates.iter().any(|pred| {
match pred.kind().skip_binder() {
ty::PredicateKind::Trait(data) if data.self_ty() == ty => {}
ty::PredicateKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
_ => return false,
}
tcx.any_free_region_meets(pred, |r| {
*r == ty::ReEarlyBound(region)
})
})
} else {
false
}
})
}
} }

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::Upvar; use crate::Upvar;
use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::location::{LocationIndex, LocationTable}; use crate::location::{LocationIndex, LocationTable};
use crate::BorrowIndex; use crate::BorrowIndex;
use polonius_engine::AllFacts as PoloniusFacts; use polonius_engine::AllFacts as PoloniusFacts;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue}; use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};

View File

@ -18,6 +18,7 @@ extern crate tracing;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::dominators::Dominators;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
@ -129,6 +130,19 @@ fn mir_borrowck<'tcx>(
) -> &'tcx BorrowCheckResult<'tcx> { ) -> &'tcx BorrowCheckResult<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def); let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
if input_body.borrow().should_skip() {
debug!("Skipping borrowck because of injected body");
// Let's make up a borrowck result! Fun times!
let result = BorrowCheckResult {
concrete_opaque_types: VecMap::new(),
closure_requirements: None,
used_mut_upvars: SmallVec::new(),
tainted_by_errors: None,
};
return tcx.arena.alloc(result);
}
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let infcx = let infcx =

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::{BasicBlock, Body, Location}; use rustc_middle::mir::{BasicBlock, Body, Location};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! The entry point of the NLL borrow checker. //! The entry point of the NLL borrow checker.
use rustc_data_structures::vec_map::VecMap; use rustc_data_structures::vec_map::VecMap;
@ -242,7 +244,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
mut liveness_constraints, mut liveness_constraints,
outlives_constraints, outlives_constraints,
member_constraints, member_constraints,
closure_bounds_mapping,
universe_causes, universe_causes,
type_tests, type_tests,
} = constraints; } = constraints;
@ -264,7 +265,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
universal_region_relations, universal_region_relations,
outlives_constraints, outlives_constraints,
member_constraints, member_constraints,
closure_bounds_mapping,
universe_causes, universe_causes,
type_tests, type_tests,
liveness_constraints, liveness_constraints,

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
use crate::places_conflict; use crate::places_conflict;
use crate::AccessDepth; use crate::AccessDepth;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::LocalsStateAtExit; use crate::borrow_set::LocalsStateAtExit;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::mir::ProjectionElem; use rustc_middle::mir::ProjectionElem;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::ArtificialField; use crate::ArtificialField;
use crate::Overlap; use crate::Overlap;
use crate::{AccessDepth, Deep, Shallow}; use crate::{AccessDepth, Deep, Shallow};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that //! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] " //! we stop when we reach the deref of a shared reference. [...] "

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! As part of generating the regions, if you enable `-Zdump-mir=nll`, //! As part of generating the regions, if you enable `-Zdump-mir=nll`,
//! we will generate an annotated copy of the MIR that includes the //! we will generate an annotated copy of the MIR that includes the
//! state of region inference. This code handles emitting the region //! state of region inference. This code handles emitting the region
@ -74,8 +76,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
constraints.sort_by_key(|c| (c.sup, c.sub)); constraints.sort_by_key(|c| (c.sup, c.sub));
for constraint in &constraints { for constraint in &constraints {
let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } = let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint;
constraint;
let (name, arg) = match locations { let (name, arg) = match locations {
Locations::All(span) => { Locations::All(span) => {
("All", tcx.sess.source_map().span_to_embeddable_string(*span)) ("All", tcx.sess.source_map().span_to_embeddable_string(*span))

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This module provides linkage between RegionInferenceContext and //! This module provides linkage between RegionInferenceContext and
//! `rustc_graphviz` traits, specialized to attaching borrowck analysis //! `rustc_graphviz` traits, specialized to attaching borrowck analysis
//! data to rendered labels. //! data to rendered labels.

View File

@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::scc::Sccs;
use rustc_errors::Diagnostic; use rustc_errors::Diagnostic;
use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::CRATE_HIR_ID; use rustc_hir::CRATE_HIR_ID;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::outlives::test_type_match;
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
@ -19,9 +18,7 @@ use rustc_middle::mir::{
}; };
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{ use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable};
self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable,
};
use rustc_span::Span; use rustc_span::Span;
use crate::{ use crate::{
@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> {
/// `member_region_scc`. /// `member_region_scc`.
member_constraints_applied: Vec<AppliedMemberConstraint>, member_constraints_applied: Vec<AppliedMemberConstraint>,
/// Map closure bounds to a `Span` that should be used for error reporting.
closure_bounds_mapping:
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
/// Map universe indexes to information on why we created it. /// Map universe indexes to information on why we created it.
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
@ -221,8 +214,8 @@ pub struct TypeTest<'tcx> {
/// The region `'x` that the type must outlive. /// The region `'x` that the type must outlive.
pub lower_bound: RegionVid, pub lower_bound: RegionVid,
/// Where did this constraint arise and why? /// The span to blame.
pub locations: Locations, pub span: Span,
/// A test which, if met by the region `'x`, proves that this type /// A test which, if met by the region `'x`, proves that this type
/// constraint is satisfied. /// constraint is satisfied.
@ -265,10 +258,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
outlives_constraints: OutlivesConstraintSet<'tcx>, outlives_constraints: OutlivesConstraintSet<'tcx>,
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
closure_bounds_mapping: FxHashMap<
Location,
FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>,
>,
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>, type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues<RegionVid>, liveness_constraints: LivenessValues<RegionVid>,
@ -310,7 +299,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
rev_scc_graph: None, rev_scc_graph: None,
member_constraints, member_constraints,
member_constraints_applied: Vec::new(), member_constraints_applied: Vec::new(),
closure_bounds_mapping,
universe_causes, universe_causes,
scc_universes, scc_universes,
scc_representatives, scc_representatives,
@ -882,13 +870,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
if deduplicate_errors.insert(( if deduplicate_errors.insert((
erased_generic_kind, erased_generic_kind,
type_test.lower_bound, type_test.lower_bound,
type_test.locations, type_test.span,
)) { )) {
debug!( debug!(
"check_type_test: reporting error for erased_generic_kind={:?}, \ "check_type_test: reporting error for erased_generic_kind={:?}, \
lower_bound_region={:?}, \ lower_bound_region={:?}, \
type_test.locations={:?}", type_test.span={:?}",
erased_generic_kind, type_test.lower_bound, type_test.locations, erased_generic_kind, type_test.lower_bound, type_test.span,
); );
errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() });
@ -931,7 +919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) -> bool { ) -> bool {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test; let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test;
let generic_ty = generic_kind.to_ty(tcx); let generic_ty = generic_kind.to_ty(tcx);
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
@ -959,7 +947,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements.push(ClosureOutlivesRequirement { propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: static_r, outlived_free_region: static_r,
blame_span: locations.span(body), blame_span: type_test.span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}); });
@ -1011,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let requirement = ClosureOutlivesRequirement { let requirement = ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: upper_bound, outlived_free_region: upper_bound,
blame_span: locations.span(body), blame_span: type_test.span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}; };
debug!("try_promote_type_test: pushing {:#?}", requirement); debug!("try_promote_type_test: pushing {:#?}", requirement);
@ -1804,25 +1792,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
} }
pub(crate) fn retrieve_closure_constraint_info(
&self,
constraint: OutlivesConstraint<'tcx>,
) -> Option<(ConstraintCategory, Span)> {
match constraint.locations {
Locations::All(_) => None,
Locations::Single(loc) => {
self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied()
}
}
}
/// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`. /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
pub(crate) fn find_outlives_blame_span( pub(crate) fn find_outlives_blame_span(
&self, &self,
fr1: RegionVid, fr1: RegionVid,
fr1_origin: NllRegionVariableOrigin, fr1_origin: NllRegionVariableOrigin,
fr2: RegionVid, fr2: RegionVid,
) -> (ConstraintCategory, ObligationCause<'tcx>) { ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) {
let BlameConstraint { category, cause, .. } = self let BlameConstraint { category, cause, .. } = self
.best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2)) .best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2))
.0; .0;
@ -1921,6 +1897,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
span: p_c.definition_span, span: p_c.definition_span,
category: ConstraintCategory::OpaqueType, category: ConstraintCategory::OpaqueType,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: false,
}; };
handle_constraint(constraint); handle_constraint(constraint);
} }
@ -2066,31 +2043,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Classify each of the constraints along the path. // Classify each of the constraints along the path.
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
.iter() .iter()
.map(|constraint| { .map(|constraint| BlameConstraint {
let (category, span, from_closure, cause_code) = category: constraint.category,
if constraint.category == ConstraintCategory::ClosureBounds { from_closure: constraint.from_closure,
if let Some((category, span)) = cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()),
self.retrieve_closure_constraint_info(*constraint)
{
(category, span, true, ObligationCauseCode::MiscObligation)
} else {
(
constraint.category,
constraint.span,
false,
ObligationCauseCode::MiscObligation,
)
}
} else {
(constraint.category, constraint.span, false, cause_code.clone())
};
BlameConstraint {
category,
from_closure,
cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code),
variance_info: constraint.variance_info, variance_info: constraint.variance_info,
outlives_constraint: *constraint, outlives_constraint: *constraint,
}
}) })
.collect(); .collect();
debug!("categorized_path={:#?}", categorized_path); debug!("categorized_path={:#?}", categorized_path);
@ -2274,95 +2232,9 @@ impl<'tcx> RegionDefinition<'tcx> {
} }
} }
pub trait ClosureRegionRequirementsExt<'tcx> {
fn apply_requirements(
&self,
tcx: TyCtxt<'tcx>,
closure_def_id: DefId,
closure_substs: SubstsRef<'tcx>,
) -> Vec<QueryOutlivesConstraint<'tcx>>;
}
impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> {
/// Given an instance T of the closure type, this method
/// instantiates the "extra" requirements that we computed for the
/// closure into the inference context. This has the effect of
/// adding new outlives obligations to existing variables.
///
/// As described on `ClosureRegionRequirements`, the extra
/// requirements are expressed in terms of regionvids that index
/// into the free regions that appear on the closure type. So, to
/// do this, we first copy those regions out from the type T into
/// a vector. Then we can just index into that vector to extract
/// out the corresponding region from T and apply the
/// requirements.
fn apply_requirements(
&self,
tcx: TyCtxt<'tcx>,
closure_def_id: DefId,
closure_substs: SubstsRef<'tcx>,
) -> Vec<QueryOutlivesConstraint<'tcx>> {
debug!(
"apply_requirements(closure_def_id={:?}, closure_substs={:?})",
closure_def_id, closure_substs
);
// Extract the values of the free regions in `closure_substs`
// into a vector. These are the regions that we will be
// relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping(
tcx,
closure_substs,
self.num_external_vids,
tcx.typeck_root_def_id(closure_def_id),
);
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
// Create the predicates.
self.outlives_requirements
.iter()
.map(|outlives_requirement| {
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
match outlives_requirement.subject {
ClosureOutlivesSubject::Region(region) => {
let region = closure_mapping[region];
debug!(
"apply_requirements: region={:?} \
outlived_region={:?} \
outlives_requirement={:?}",
region, outlived_region, outlives_requirement,
);
(
ty::Binder::dummy(ty::OutlivesPredicate(
region.into(),
outlived_region,
)),
ConstraintCategory::BoringNoLocation,
)
}
ClosureOutlivesSubject::Ty(ty) => {
debug!(
"apply_requirements: ty={:?} \
outlived_region={:?} \
outlives_requirement={:?}",
ty, outlived_region, outlives_requirement,
);
(
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)),
ConstraintCategory::BoringNoLocation,
)
}
}
})
.collect()
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BlameConstraint<'tcx> { pub struct BlameConstraint<'tcx> {
pub category: ConstraintCategory, pub category: ConstraintCategory<'tcx>,
pub from_closure: bool, pub from_closure: bool,
pub cause: ObligationCause<'tcx>, pub cause: ObligationCause<'tcx>,
pub variance_info: ty::VarianceDiagInfo<'tcx>, pub variance_info: ty::VarianceDiagInfo<'tcx>,

View File

@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId;
use rustc_hir::OpaqueTyOrigin; use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_infer::infer::{DefiningAnchor, InferCtxt}; use rustc_infer::infer::{DefiningAnchor, InferCtxt};
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine}; use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{ use rustc_middle::ty::{
@ -12,7 +12,7 @@ use rustc_middle::ty::{
}; };
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::TraitEngineExt as _; use rustc_trait_selection::traits::ObligationCtxt;
use super::RegionInferenceContext; use super::RegionInferenceContext;
@ -252,50 +252,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
// type-alias-impl-trait/issue-67844-nested-opaque.rs // type-alias-impl-trait/issue-67844-nested-opaque.rs
let infcx = let infcx =
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
let ocx = ObligationCtxt::new(&infcx);
// Require the hidden type to be well-formed with only the generics of the opaque type. // Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds. // hidden type is well formed even without those bounds.
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
.to_predicate(infcx.tcx); .to_predicate(infcx.tcx);
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id());
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies. // the bounds that the function supplies.
match infcx.register_hidden_type( let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
OpaqueTypeKey { def_id, substs: id_substs }, if let Err(err) = ocx.eq(
ObligationCause::misc(instantiated_ty.span, body_id), &ObligationCause::misc(instantiated_ty.span, body_id),
param_env, param_env,
opaque_ty,
definition_ty, definition_ty,
origin,
) { ) {
Ok(infer_ok) => {
for obligation in infer_ok.obligations {
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
}
}
Err(err) => {
infcx infcx
.err_ctxt() .err_ctxt()
.report_mismatched_types( .report_mismatched_types(
&ObligationCause::misc(instantiated_ty.span, body_id), &ObligationCause::misc(instantiated_ty.span, body_id),
self.tcx.mk_opaque(def_id.to_def_id(), id_substs), opaque_ty,
definition_ty, definition_ty,
err, err,
) )
.emit(); .emit();
} }
}
fulfillment_cx.register_predicate_obligation( ocx.register_obligation(Obligation::misc(
&infcx, instantiated_ty.span,
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), body_id,
); param_env,
predicate,
));
// Check that all obligations are satisfied by the implementation's // Check that all obligations are satisfied by the implementation's
// version. // version.
let errors = fulfillment_cx.select_all_or_error(&infcx); let errors = ocx.select_all_or_error();
// This is still required for many(half of the tests in ui/type-alias-impl-trait) // This is still required for many(half of the tests in ui/type-alias-impl-trait)
// tests to pass // tests to pass
@ -304,8 +299,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
if errors.is_empty() { if errors.is_empty() {
definition_ty definition_ty
} else { } else {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
self.tcx.ty_error() self.tcx.ty_error_with_guaranteed(reported)
} }
} }
} }

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::constraints::ConstraintSccIndex; use crate::constraints::ConstraintSccIndex;
use crate::RegionInferenceContext; use crate::RegionInferenceContext;
use itertools::Itertools; use itertools::Itertools;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_index::bit_set::SparseBitMatrix; use rustc_index::bit_set::SparseBitMatrix;
use rustc_index::interval::IntervalSet; use rustc_index::interval::IntervalSet;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::visit::{MutVisitor, TyContext};

View File

@ -49,7 +49,7 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(borrowck_var_does_not_need_mut)] #[diag(borrowck_var_does_not_need_mut)]
pub(crate) struct VarNeedNotMut { pub(crate) struct VarNeedNotMut {
#[suggestion_short(applicability = "machine-applicable", code = "")] #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
pub span: Span, pub span: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
@ -148,3 +148,95 @@ pub(crate) enum RequireStaticErr {
multi_span: MultiSpan, multi_span: MultiSpan,
}, },
} }
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarPathUseCause {
#[label(borrowck_borrow_due_to_use_generator)]
BorrowInGenerator {
#[primary_span]
path_span: Span,
},
#[label(borrowck_use_due_to_use_generator)]
UseInGenerator {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_due_to_use_generator)]
AssignInGenerator {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_part_due_to_use_generator)]
AssignPartInGenerator {
#[primary_span]
path_span: Span,
},
#[label(borrowck_borrow_due_to_use_closure)]
BorrowInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_use_due_to_use_closure)]
UseInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_due_to_use_closure)]
AssignInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_part_due_to_use_closure)]
AssignPartInClosure {
#[primary_span]
path_span: Span,
},
}
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarKind {
#[label(borrowck_capture_immute)]
Immute {
#[primary_span]
kind_span: Span,
},
#[label(borrowck_capture_mut)]
Mut {
#[primary_span]
kind_span: Span,
},
#[label(borrowck_capture_move)]
Move {
#[primary_span]
kind_span: Span,
},
}
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarCause {
#[label(borrowck_var_borrow_by_use_place_in_generator)]
BorrowUsePlaceGenerator {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_borrow_by_use_place_in_closure)]
BorrowUsePlaceClosure {
place: String,
#[primary_span]
var_span: Span,
},
}
#[derive(Diagnostic)]
#[diag(borrowck_cannot_move_when_borrowed, code = "E0505")]
pub(crate) struct MoveBorrow<'a> {
pub place: &'a str,
pub borrow_place: &'a str,
pub value_place: &'a str,
#[primary_span]
#[label(move_label)]
pub span: Span,
#[label]
pub borrow_span: Span,
}

View File

@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
pub(super) fn fully_perform_op<R: fmt::Debug, Op>( pub(super) fn fully_perform_op<R: fmt::Debug, Op>(
&mut self, &mut self,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
op: Op, op: Op,
) -> Fallible<R> ) -> Fallible<R>
where where
@ -85,7 +85,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self, &mut self,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) { ) {
self.prove_predicate( self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
@ -124,7 +124,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self, &mut self,
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>, predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) { ) {
for predicate in predicates { for predicate in predicates {
let predicate = predicate.to_predicate(self.tcx()); let predicate = predicate.to_predicate(self.tcx());
@ -139,7 +139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self, &mut self,
predicate: ty::Predicate<'tcx>, predicate: ty::Predicate<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) { ) {
let param_env = self.param_env; let param_env = self.param_env;
self.fully_perform_op( self.fully_perform_op(
@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self, &mut self,
value: T, value: T,
location: impl NormalizeLocation, location: impl NormalizeLocation,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> T ) -> T
where where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,

View File

@ -1,10 +1,10 @@
use rustc_infer::infer::canonical::QueryOutlivesConstraint; use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
@ -37,7 +37,8 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
from_closure: bool,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
} }
@ -50,7 +51,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
) -> Self { ) -> Self {
Self { Self {
@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
span, span,
category, category,
constraints, constraints,
from_closure: false,
} }
} }
@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
} }
self.constraints.member_constraints = tmp; self.constraints.member_constraints = tmp;
for query_constraint in outlives { for (predicate, constraint_category) in outlives {
self.convert(query_constraint); // At the moment, we never generate any "higher-ranked"
// region constraints like `for<'a> 'a: 'b`. At some point
// when we move to universes, we will, and this assertion
// will start to fail.
let predicate = predicate.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", predicate,);
});
self.convert(predicate, *constraint_category);
} }
} }
fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) { /// Given an instance of the closure type, this method instantiates the "extra" requirements
/// that we computed for the closure. This has the effect of adding new outlives obligations
/// to existing region variables in `closure_substs`.
#[instrument(skip(self), level = "debug")]
pub fn apply_closure_requirements(
&mut self,
closure_requirements: &ClosureRegionRequirements<'tcx>,
closure_def_id: DefId,
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
// relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping(
self.tcx,
closure_substs,
closure_requirements.num_external_vids,
closure_def_id.expect_local(),
);
debug!(?closure_mapping);
// Create the predicates.
let backup = (self.category, self.span, self.from_closure);
self.from_closure = true;
for outlives_requirement in &closure_requirements.outlives_requirements {
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
let subject = match outlives_requirement.subject {
ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
ClosureOutlivesSubject::Ty(ty) => ty.into(),
};
self.category = outlives_requirement.category;
self.span = outlives_requirement.blame_span;
self.convert(ty::OutlivesPredicate(subject, outlived_region), self.category);
}
(self.category, self.span, self.from_closure) = backup;
}
fn convert(
&mut self,
predicate: ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
constraint_category: ConstraintCategory<'tcx>,
) {
debug!("generate: constraints at: {:#?}", self.locations); debug!("generate: constraints at: {:#?}", self.locations);
// Extract out various useful fields we'll need below. // Extract out various useful fields we'll need below.
@ -94,17 +146,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
tcx, region_bound_pairs, implicit_region_bound, param_env, .. tcx, region_bound_pairs, implicit_region_bound, param_env, ..
} = *self; } = *self;
// At the moment, we never generate any "higher-ranked" let ty::OutlivesPredicate(k1, r2) = predicate;
// region constraints like `for<'a> 'a: 'b`. At some point
// when we move to universes, we will, and this assertion
// will start to fail.
let ty::OutlivesPredicate(k1, r2) =
query_constraint.0.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", query_constraint,);
});
let constraint_category = query_constraint.1;
match k1.unpack() { match k1.unpack() {
GenericArgKind::Lifetime(r1) => { GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(r1); let r1_vid = self.to_region_vid(r1);
@ -127,10 +169,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
.type_must_outlive(origin, t1, r2, constraint_category); .type_must_outlive(origin, t1, r2, constraint_category);
} }
GenericArgKind::Const(_) => { GenericArgKind::Const(_) => unreachable!(),
// Consts cannot outlive one another, so we
// don't need to handle any relations here.
}
} }
} }
@ -160,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
verify_bound: VerifyBound<'tcx>, verify_bound: VerifyBound<'tcx>,
) -> TypeTest<'tcx> { ) -> TypeTest<'tcx> {
let lower_bound = self.to_region_vid(region); let lower_bound = self.to_region_vid(region);
TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound } TypeTest { generic_kind, lower_bound, span: self.span, verify_bound }
} }
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
@ -175,7 +214,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
&mut self, &mut self,
sup: ty::RegionVid, sup: ty::RegionVid,
sub: ty::RegionVid, sub: ty::RegionVid,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) { ) {
let category = match self.category { let category = match self.category {
ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category, ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category,
@ -188,6 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
sub, sub,
sup, sup,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: self.from_closure,
}); });
} }
@ -203,7 +243,7 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
_origin: SubregionOrigin<'tcx>, _origin: SubregionOrigin<'tcx>,
a: ty::Region<'tcx>, a: ty::Region<'tcx>,
b: ty::Region<'tcx>, b: ty::Region<'tcx>,
constraint_category: ConstraintCategory, constraint_category: ConstraintCategory<'tcx>,
) { ) {
let b = self.to_region_vid(b); let b = self.to_region_vid(b);
let a = self.to_region_vid(a); let a = self.to_region_vid(a);

View File

@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
.and(type_op::normalize::Normalize::new(ty)) .and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx) .fully_perform(self.infcx)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
self.infcx let reported = self
.infcx
.tcx .tcx
.sess .sess
.delay_span_bug(span, &format!("failed to normalize {:?}", ty)); .delay_span_bug(span, &format!("failed to normalize {:?}", ty));
TypeOpOutput { TypeOpOutput {
output: self.infcx.tcx.ty_error(), output: self.infcx.tcx.ty_error_with_guaranteed(reported),
constraints: None, constraints: None,
error_info: None, error_info: None,
} }

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This pass type-checks the MIR to ensure it is not broken. //! This pass type-checks the MIR to ensure it is not broken.
use std::rc::Rc; use std::rc::Rc;
@ -27,7 +29,7 @@ use rustc_middle::mir::AssertKind;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts}; use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
@ -61,7 +63,7 @@ use crate::{
region_infer::values::{ region_infer::values::{
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
}, },
region_infer::{ClosureRegionRequirementsExt, TypeTest}, region_infer::TypeTest,
type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
universal_regions::{DefiningTy, UniversalRegions}, universal_regions::{DefiningTy, UniversalRegions},
Upvar, Upvar,
@ -144,7 +146,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
liveness_constraints: LivenessValues::new(elements.clone()), liveness_constraints: LivenessValues::new(elements.clone()),
outlives_constraints: OutlivesConstraintSet::default(), outlives_constraints: OutlivesConstraintSet::default(),
member_constraints: MemberConstraintSet::default(), member_constraints: MemberConstraintSet::default(),
closure_bounds_mapping: Default::default(),
type_tests: Vec::default(), type_tests: Vec::default(),
universe_causes: FxHashMap::default(), universe_causes: FxHashMap::default(),
}; };
@ -234,11 +235,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
if hidden_type.has_non_region_infer() { if hidden_type.has_non_region_infer() {
infcx.tcx.sess.delay_span_bug( let reported = infcx.tcx.sess.delay_span_bug(
decl.hidden_type.span, decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.ty.kind()), &format!("could not resolve {:#?}", hidden_type.ty.kind()),
); );
hidden_type.ty = infcx.tcx.ty_error(); hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported);
} }
(opaque_type_key, (hidden_type, decl.origin)) (opaque_type_key, (hidden_type, decl.origin))
@ -584,8 +585,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
// modify their locations. // modify their locations.
let all_facts = &mut None; let all_facts = &mut None;
let mut constraints = Default::default(); let mut constraints = Default::default();
let mut type_tests = Default::default();
let mut closure_bounds = Default::default();
let mut liveness_constraints = let mut liveness_constraints =
LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body))); LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR // Don't try to add borrow_region facts for the promoted MIR
@ -596,11 +595,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
&mut this.cx.borrowck_context.constraints.outlives_constraints, &mut this.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints, &mut constraints,
); );
mem::swap(&mut this.cx.borrowck_context.constraints.type_tests, &mut type_tests);
mem::swap(
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds,
);
mem::swap( mem::swap(
&mut this.cx.borrowck_context.constraints.liveness_constraints, &mut this.cx.borrowck_context.constraints.liveness_constraints,
&mut liveness_constraints, &mut liveness_constraints,
@ -621,13 +615,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
swap_constraints(self); swap_constraints(self);
let locations = location.to_locations(); let locations = location.to_locations();
// Use location of promoted const in collected constraints
for type_test in type_tests.iter() {
let mut type_test = type_test.clone();
type_test.locations = locations;
self.cx.borrowck_context.constraints.type_tests.push(type_test)
}
for constraint in constraints.outlives().iter() { for constraint in constraints.outlives().iter() {
let mut constraint = constraint.clone(); let mut constraint = constraint.clone();
constraint.locations = locations; constraint.locations = locations;
@ -653,18 +640,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
.add_element(region, location); .add_element(region, location);
} }
} }
if !closure_bounds.is_empty() {
let combined_bounds_mapping =
closure_bounds.into_iter().flat_map(|(_, value)| value).collect();
let existing = self
.cx
.borrowck_context
.constraints
.closure_bounds_mapping
.insert(location, combined_bounds_mapping);
assert!(existing.is_none(), "Multiple promoteds/closures at the same location.");
}
} }
fn sanitize_projection( fn sanitize_projection(
@ -941,9 +916,6 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>,
pub(crate) closure_bounds_mapping:
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
pub(crate) type_tests: Vec<TypeTest<'tcx>>, pub(crate) type_tests: Vec<TypeTest<'tcx>>,
@ -1133,7 +1105,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn push_region_constraints( fn push_region_constraints(
&mut self, &mut self,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
data: &QueryRegionConstraints<'tcx>, data: &QueryRegionConstraints<'tcx>,
) { ) {
debug!("constraints generated: {:#?}", data); debug!("constraints generated: {:#?}", data);
@ -1158,7 +1130,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
sub: Ty<'tcx>, sub: Ty<'tcx>,
sup: Ty<'tcx>, sup: Ty<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> Fallible<()> { ) -> Fallible<()> {
// Use this order of parameters because the sup type is usually the // Use this order of parameters because the sup type is usually the
// "expected" type in diagnostics. // "expected" type in diagnostics.
@ -1171,7 +1143,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> Fallible<()> { ) -> Fallible<()> {
self.relate_types(expected, ty::Variance::Invariant, found, locations, category) self.relate_types(expected, ty::Variance::Invariant, found, locations, category)
} }
@ -1183,7 +1155,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
v: ty::Variance, v: ty::Variance,
user_ty: &UserTypeProjection, user_ty: &UserTypeProjection,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> Fallible<()> { ) -> Fallible<()> {
let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
@ -1618,12 +1590,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
} }
let func_ty = if let TerminatorKind::Call { func, .. } = &term.kind {
Some(func.ty(body, self.infcx.tcx))
} else {
None
};
debug!(?func_ty);
for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
let op_arg_ty = op_arg.ty(body, self.tcx()); let op_arg_ty = op_arg.ty(body, self.tcx());
let op_arg_ty = self.normalize(op_arg_ty, term_location); let op_arg_ty = self.normalize(op_arg_ty, term_location);
let category = if from_hir_call { let category = if from_hir_call {
ConstraintCategory::CallArgument(term_location) ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty))
} else { } else {
ConstraintCategory::Boring ConstraintCategory::Boring
}; };
@ -1776,7 +1755,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// `Sized` bound in no way depends on precise regions, so this // `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`. // shouldn't affect `is_sized`.
let erased_ty = tcx.erase_regions(ty); let erased_ty = tcx.erase_regions(ty);
if !erased_ty.is_sized(tcx.at(span), self.param_env) { if !erased_ty.is_sized(tcx, self.param_env) {
// in current MIR construction, all non-control-flow rvalue // in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return // expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough // slot or local, so to find all unsized rvalues it is enough
@ -2555,6 +2534,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span: location.to_locations().span(body), span: location.to_locations().span(body),
category, category,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: false,
}); });
match mutbl { match mutbl {
@ -2672,62 +2652,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
location: Location, location: Location,
) -> ty::InstantiatedPredicates<'tcx> { ) -> ty::InstantiatedPredicates<'tcx> {
if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements if let Some(ref closure_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
{ constraint_conversion::ConstraintConversion::new(
let closure_constraints = QueryRegionConstraints { self.infcx,
outlives: closure_region_requirements.apply_requirements( self.borrowck_context.universal_regions,
tcx, self.region_bound_pairs,
self.implicit_region_bound,
self.param_env,
location.to_locations(),
DUMMY_SP, // irrelevant; will be overrided.
ConstraintCategory::Boring, // same as above.
&mut self.borrowck_context.constraints,
)
.apply_closure_requirements(
&closure_requirements,
def_id.to_def_id(), def_id.to_def_id(),
substs, substs,
),
// Presently, closures never propagate member
// constraints to their parents -- they are enforced
// locally. This is largely a non-issue as member
// constraints only come from `-> impl Trait` and
// friends which don't appear (thus far...) in
// closures.
member_constraints: vec![],
};
let bounds_mapping = closure_constraints
.outlives
.iter()
.enumerate()
.filter_map(|(idx, constraint)| {
let ty::OutlivesPredicate(k1, r2) =
constraint.0.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", constraint,);
});
match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
// constraint is r1: r2
let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1);
let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2);
let outlives_requirements =
&closure_region_requirements.outlives_requirements[idx];
Some((
(r1_vid, r2_vid),
(outlives_requirements.category, outlives_requirements.blame_span),
))
}
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
}
})
.collect();
let existing = self
.borrowck_context
.constraints
.closure_bounds_mapping
.insert(location, bounds_mapping);
assert!(existing.is_none(), "Multiple closures at the same location.");
self.push_region_constraints(
location.to_locations(),
ConstraintCategory::ClosureBounds,
&closure_constraints,
); );
} }

View File

@ -1,6 +1,6 @@
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::PredicateObligations;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::relate::TypeRelation;
@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
v: ty::Variance, v: ty::Variance,
b: Ty<'tcx>, b: Ty<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> Fallible<()> { ) -> Fallible<()> {
TypeRelating::new( TypeRelating::new(
self.infcx, self.infcx,
@ -45,7 +45,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
a: ty::SubstsRef<'tcx>, a: ty::SubstsRef<'tcx>,
b: ty::SubstsRef<'tcx>, b: ty::SubstsRef<'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
) -> Fallible<()> { ) -> Fallible<()> {
TypeRelating::new( TypeRelating::new(
self.infcx, self.infcx,
@ -64,7 +64,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
locations: Locations, locations: Locations,
/// What category do we assign the resulting `'a: 'b` relationships? /// What category do we assign the resulting `'a: 'b` relationships?
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
/// Information so that error reporting knows what types we are relating /// Information so that error reporting knows what types we are relating
/// when reporting a bound region error. /// when reporting a bound region error.
@ -75,7 +75,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
fn new( fn new(
type_checker: &'me mut TypeChecker<'bccx, 'tcx>, type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
locations: Locations, locations: Locations,
category: ConstraintCategory, category: ConstraintCategory<'tcx>,
universe_info: UniverseInfo<'tcx>, universe_info: UniverseInfo<'tcx>,
) -> Self { ) -> Self {
Self { type_checker, locations, category, universe_info } Self { type_checker, locations, category, universe_info }
@ -136,6 +136,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
span: self.locations.span(self.type_checker.body), span: self.locations.span(self.type_checker.body),
category: self.category, category: self.category,
variance_info: info, variance_info: info,
from_closure: false,
}, },
); );
} }
@ -155,27 +156,16 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
true true
} }
fn register_opaque_type( fn register_opaque_type_obligations(
&mut self, &mut self,
a: Ty<'tcx>, obligations: PredicateObligations<'tcx>,
b: Ty<'tcx>,
a_is_expected: bool,
) -> Result<(), TypeError<'tcx>> { ) -> Result<(), TypeError<'tcx>> {
let param_env = self.param_env();
let span = self.span();
let def_id = self.type_checker.body.source.def_id().expect_local();
let body_id = self.type_checker.tcx().hir().local_def_id_to_hir_id(def_id);
let cause = ObligationCause::misc(span, body_id);
self.type_checker self.type_checker
.fully_perform_op( .fully_perform_op(
self.locations, self.locations,
self.category, self.category,
InstantiateOpaqueType { InstantiateOpaqueType {
obligations: self obligations,
.type_checker
.infcx
.handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
.obligations,
// These fields are filled in during execution of the operation // These fields are filled in during execution of the operation
base_universe: None, base_universe: None,
region_constraints: None, region_constraints: None,

View File

@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{
self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt,
};
use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{InternalSubsts, SubstsRef};
use std::iter; use std::iter;
@ -241,7 +243,7 @@ impl<'tcx> UniversalRegions<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>, closure_substs: SubstsRef<'tcx>,
expected_num_vars: usize, expected_num_vars: usize,
typeck_root_def_id: DefId, closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> { ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars); let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static); region_mapping.push(tcx.lifetimes.re_static);
@ -249,7 +251,7 @@ impl<'tcx> UniversalRegions<'tcx> {
region_mapping.push(fr); region_mapping.push(fr);
}); });
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { for_each_late_bound_region_in_recursive_scope(tcx, tcx.local_parent(closure_def_id), |r| {
region_mapping.push(r); region_mapping.push(r);
}); });
@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// tests, and the resulting print-outs include def-ids // tests, and the resulting print-outs include def-ids
// and other things that are not stable across tests! // and other things that are not stable across tests!
// So we just include the region-vid. Annoying. // So we just include the region-vid. Annoying.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id); for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::Generator(def_id, substs, _) => { DefiningTy::Generator(def_id, substs, _) => {
@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// FIXME: As above, we'd like to print out the region // FIXME: As above, we'd like to print out the region
// `r` but doing so is not stable across architectures // `r` but doing so is not stable across architectures
// and so forth. // and so forth.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id); for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::FnDef(def_id, substs) => { DefiningTy::FnDef(def_id, substs) => {
@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
first_extern_index first_extern_index
} else { } else {
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
// function are actually external regions to us. For example, here, 'a is not local // function/closures are actually external regions to us. For example, here, 'a is not local
// to the closure c (although it is local to the fn foo): // to the closure c (although it is local to the fn foo):
// fn foo<'a>() { // fn foo<'a>() {
// let c = || { let x: &'a u32 = ...; } // let c = || { let x: &'a u32 = ...; }
// } // }
self.infcx for_each_late_bound_region_in_recursive_scope(
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); self.infcx.tcx,
self.infcx.tcx.local_parent(self.mir_def.did),
|r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.infcx.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
},
);
// Any regions created during the execution of `defining_ty` or during the above // Any regions created during the execution of `defining_ty` or during the above
// late-bound region replacement are all considered 'extern' regions // late-bound region replacement are all considered 'extern' regions
self.infcx.num_region_vars() self.infcx.num_region_vars()
@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
bound_inputs_and_output, bound_inputs_and_output,
&mut indices, &mut indices,
); );
// Converse of above, if this is a function then the late-bound regions declared on its // Converse of above, if this is a function/closure then the late-bound regions declared on its
// signature are local to the fn. // signature are local.
if self.mir_def.did.to_def_id() == typeck_root_def_id { for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
self.infcx debug!(?r);
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); if !indices.indices.contains_key(&r) {
let region_vid = self.infcx.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
} }
});
let (unnormalized_output_ty, mut unnormalized_input_tys) = let (unnormalized_output_ty, mut unnormalized_input_tys) =
inputs_and_output.split_last().unwrap(); inputs_and_output.split_last().unwrap();
@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
where where
T: TypeFoldable<'tcx>; T: TypeFoldable<'tcx>;
fn replace_late_bound_regions_with_nll_infer_vars( fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
);
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
&self, &self,
mir_def_id: LocalDefId, mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>, indices: &mut UniversalRegionIndices<'tcx>,
@ -746,13 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the /// set of late-bound regions and checks for any that we have not yet seen, adding them to the
/// inputs vector. /// inputs vector.
#[instrument(skip(self, indices))] #[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars( fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
&self, &self,
mir_def_id: LocalDefId, mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>, indices: &mut UniversalRegionIndices<'tcx>,
) { ) {
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id()); for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| {
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| { debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});
}
#[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
) {
for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| {
debug!(?r); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR); let region_vid = self.next_nll_region_var(FR);
@ -803,21 +839,44 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
} }
} }
/// Iterates over the late-bound regions defined on fn_def_id and /// Iterates over the late-bound regions defined on `mir_def_id` and all of its
/// invokes `f` with the liberated form of each one. /// parents, up to the typeck root, and invokes `f` with the liberated form
fn for_each_late_bound_region_defined_on<'tcx>( /// of each one.
fn for_each_late_bound_region_in_recursive_scope<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
fn_def_id: DefId, mut mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>), mut f: impl FnMut(ty::Region<'tcx>),
) { ) {
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) { let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id()); // Walk up the tree, collecting late-bound regions until we hit the typeck root
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { loop {
scope: fn_def_id, for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f);
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
})); if mir_def_id.to_def_id() == typeck_root_def_id {
f(liberated_region); break;
} else {
mir_def_id = tcx.local_parent(mir_def_id);
} }
} }
} }
/// Iterates over the late-bound regions defined on `mir_def_id` and all of its
/// parents, up to the typeck root, and invokes `f` with the liberated form
/// of each one.
fn for_each_late_bound_region_in_item<'tcx>(
tcx: TyCtxt<'tcx>,
mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if !tcx.def_kind(mir_def_id).is_fn_like() {
return;
}
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
let liberated_region = tcx
.mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region }));
f(liberated_region);
}
}

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{ use rustc_middle::mir::{

View File

@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View File

@ -0,0 +1,104 @@
use crate::util::check_builtin_macro_attribute;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind};
use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use thin_vec::thin_vec;
pub fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> Vec<Annotatable> {
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
let orig_item = item.clone();
let not_function = || {
ecx.sess
.parse_sess
.span_diagnostic
.span_err(item.span(), "alloc_error_handler must be a function");
vec![orig_item.clone()]
};
// Allow using `#[alloc_error_handler]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, sig_span) = match &item {
Annotatable::Item(item) => match item.kind {
ItemKind::Fn(ref fn_kind) => (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)),
_ => return not_function(),
},
Annotatable::Stmt(stmt) => match &stmt.kind {
StmtKind::Item(item_) => match item_.kind {
ItemKind::Fn(ref fn_kind) => {
(item_, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
}
_ => return not_function(),
},
_ => return not_function(),
},
_ => return not_function(),
};
// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
// Generate item statements for the allocator methods.
let stmts = vec![generate_handler(ecx, item.ident, span, sig_span)];
// Generate anonymous constant serving as container for the allocator methods.
let const_ty = ecx.ty(sig_span, TyKind::Tup(Vec::new()));
let const_body = ecx.expr_block(ecx.block(span, stmts));
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
let const_item = if is_stmt {
Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
} else {
Annotatable::Item(const_item)
};
// Return the original item and the new methods.
vec![orig_item, const_item]
}
// #[rustc_std_internal_symbol]
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
// }
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
let ty_usize = cx.ty_path(usize);
let size = Ident::from_str_and_span("size", span);
let align = Ident::from_str_and_span("align", span);
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
let layout_new = cx.expr_path(cx.path(span, layout_new));
let layout =
cx.expr_call(span, layout_new, vec![cx.expr_ident(span, size), cx.expr_ident(span, align)]);
let call = cx.expr_call_ident(sig_span, handler, vec![layout]);
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
let params = vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
let decl = cx.fn_decl(params, never);
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
let sig = FnSig { decl, header, span: span };
let body = Some(cx.block_expr(call));
let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final,
sig,
generics: Generics::default(),
body,
}));
let special = sym::rustc_std_internal_symbol;
let special = cx.meta_word(span, special);
let attrs = thin_vec![cx.attribute(special)];
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
cx.stmt_item(sig_span, item)
}

View File

@ -303,6 +303,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
| ExprKind::Field(_, _) | ExprKind::Field(_, _)
| ExprKind::ForLoop(_, _, _, _) | ExprKind::ForLoop(_, _, _, _)
| ExprKind::If(_, _, _) | ExprKind::If(_, _, _)
| ExprKind::IncludedBytes(..)
| ExprKind::InlineAsm(_) | ExprKind::InlineAsm(_)
| ExprKind::Let(_, _, _) | ExprKind::Let(_, _, _)
| ExprKind::Lit(_) | ExprKind::Lit(_)

View File

@ -34,6 +34,7 @@ impl MultiItemModifier for Expander {
span: Span, span: Span,
meta_item: &ast::MetaItem, meta_item: &ast::MetaItem,
item: Annotatable, item: Annotatable,
_is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> { ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let template = AttributeTemplate { list: Some("path"), ..Default::default() }; let template = AttributeTemplate { list: Some("path"), ..Default::default() };
let attr = &ecx.attribute(meta_item.clone()); let attr = &ecx.attribute(meta_item.clone());

View File

@ -210,8 +210,15 @@ impl CfgEval<'_, '_> {
} }
impl MutVisitor for CfgEval<'_, '_> { impl MutVisitor for CfgEval<'_, '_> {
#[instrument(level = "trace", skip(self))]
fn visit_expr(&mut self, expr: &mut P<ast::Expr>) { fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
self.cfg.configure_expr(expr); self.cfg.configure_expr(expr, false);
mut_visit::noop_visit_expr(expr, self);
}
#[instrument(level = "trace", skip(self))]
fn visit_method_receiver_expr(&mut self, expr: &mut P<ast::Expr>) {
self.cfg.configure_expr(expr, true);
mut_visit::noop_visit_expr(expr, self); mut_visit::noop_visit_expr(expr, self);
} }

View File

@ -43,6 +43,9 @@ pub fn expand_concat(
has_errors = true; has_errors = true;
} }
}, },
ast::ExprKind::IncludedBytes(..) => {
cx.span_err(e.span, "cannot concatenate a byte string literal")
}
ast::ExprKind::Err => { ast::ExprKind::Err => {
has_errors = true; has_errors = true;
} }

View File

@ -108,6 +108,16 @@ fn handle_array_element(
None None
} }
}, },
ast::ExprKind::IncludedBytes(..) => {
if !*has_errors {
cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
.note("byte strings are treated as arrays of bytes")
.help("try flattening the array")
.emit();
}
*has_errors = true;
None
}
_ => { _ => {
missing_literals.push(expr.span); missing_literals.push(expr.span);
None None
@ -167,6 +177,9 @@ pub fn expand_concat_bytes(
has_errors = true; has_errors = true;
} }
}, },
ast::ExprKind::IncludedBytes(ref bytes) => {
accumulator.extend_from_slice(bytes);
}
ast::ExprKind::Err => { ast::ExprKind::Err => {
has_errors = true; has_errors = true;
} }

View File

@ -10,7 +10,7 @@ use rustc_session::Session;
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;
pub(crate) struct Expander; pub(crate) struct Expander(pub bool);
impl MultiItemModifier for Expander { impl MultiItemModifier for Expander {
fn expand( fn expand(
@ -19,6 +19,7 @@ impl MultiItemModifier for Expander {
span: Span, span: Span,
meta_item: &ast::MetaItem, meta_item: &ast::MetaItem,
item: Annotatable, item: Annotatable,
_: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> { ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let sess = ecx.sess; let sess = ecx.sess;
if report_bad_target(sess, &item, span) { if report_bad_target(sess, &item, span) {
@ -58,20 +59,20 @@ impl MultiItemModifier for Expander {
report_path_args(sess, &meta); report_path_args(sess, &meta);
meta.path meta.path
}) })
.map(|path| (path, dummy_annotatable(), None)) .map(|path| (path, dummy_annotatable(), None, self.0))
.collect(); .collect();
// Do not configure or clone items unless necessary. // Do not configure or clone items unless necessary.
match &mut resolutions[..] { match &mut resolutions[..] {
[] => {} [] => {}
[(_, first_item, _), others @ ..] => { [(_, first_item, ..), others @ ..] => {
*first_item = cfg_eval( *first_item = cfg_eval(
sess, sess,
features, features,
item.clone(), item.clone(),
ecx.current_expansion.lint_node_id, ecx.current_expansion.lint_node_id,
); );
for (_, item, _) in others { for (_, item, _, _) in others {
*item = first_item.clone(); *item = first_item.clone();
} }
} }

View File

@ -1,4 +1,3 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*; use crate::deriving::generic::*;
use crate::deriving::path_std; use crate::deriving::path_std;
@ -12,16 +11,17 @@ pub fn expand_deriving_copy(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
path: path_std!(marker::Copy), path: path_std!(marker::Copy),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: true, supports_unions: true,
methods: Vec::new(), methods: Vec::new(),
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push); trait_def.expand(cx, mitem, item, push);

View File

@ -14,6 +14,7 @@ pub fn expand_deriving_clone(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
// The simple form is `fn clone(&self) -> Self { *self }`, possibly with // The simple form is `fn clone(&self) -> Self { *self }`, possibly with
// some additional `AssertParamIsClone` assertions. // some additional `AssertParamIsClone` assertions.
@ -74,7 +75,6 @@ pub fn expand_deriving_clone(
path: path_std!(clone::Clone), path: path_std!(clone::Clone),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: bounds, additional_bounds: bounds,
generics: Bounds::empty(),
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::clone, name: sym::clone,
@ -87,6 +87,7 @@ pub fn expand_deriving_clone(
combine_substructure: substructure, combine_substructure: substructure,
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand_ext(cx, mitem, item, push, is_simple) trait_def.expand_ext(cx, mitem, item, push, is_simple)

View File

@ -15,6 +15,7 @@ pub fn expand_deriving_eq(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let span = cx.with_def_site_ctxt(span); let span = cx.with_def_site_ctxt(span);
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
@ -27,7 +28,6 @@ pub fn expand_deriving_eq(
path: path_std!(cmp::Eq), path: path_std!(cmp::Eq),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::assert_receiver_is_total_eq, name: sym::assert_receiver_is_total_eq,
@ -42,6 +42,7 @@ pub fn expand_deriving_eq(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push); super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);

View File

@ -13,6 +13,7 @@ pub fn expand_deriving_ord(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = thin_vec![cx.attribute(inline)]; let attrs = thin_vec![cx.attribute(inline)];
@ -21,7 +22,6 @@ pub fn expand_deriving_ord(
path: path_std!(cmp::Ord), path: path_std!(cmp::Ord),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::cmp, name: sym::cmp,
@ -34,6 +34,7 @@ pub fn expand_deriving_ord(
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))), combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)

View File

@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
let base = true; let base = true;
@ -85,10 +86,10 @@ pub fn expand_deriving_partial_eq(
path: path_std!(cmp::PartialEq), path: path_std!(cmp::PartialEq),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods, methods,
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }

View File

@ -13,6 +13,7 @@ pub fn expand_deriving_partial_ord(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let ordering_ty = Path(path_std!(cmp::Ordering)); let ordering_ty = Path(path_std!(cmp::Ordering));
let ret_ty = let ret_ty =
@ -39,10 +40,10 @@ pub fn expand_deriving_partial_ord(
path: path_std!(cmp::PartialOrd), path: path_std!(cmp::PartialOrd),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: vec![], additional_bounds: vec![],
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![partial_cmp_def], methods: vec![partial_cmp_def],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }

View File

@ -13,6 +13,7 @@ pub fn expand_deriving_debug(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut); let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut);
@ -22,7 +23,6 @@ pub fn expand_deriving_debug(
path: path_std!(fmt::Debug), path: path_std!(fmt::Debug),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::fmt, name: sym::fmt,
@ -37,6 +37,7 @@ pub fn expand_deriving_debug(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }

View File

@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let krate = sym::rustc_serialize; let krate = sym::rustc_serialize;
let typaram = sym::__D; let typaram = sym::__D;
@ -25,7 +26,6 @@ pub fn expand_deriving_rustc_decodable(
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::decode, name: sym::decode,
@ -55,6 +55,7 @@ pub fn expand_deriving_rustc_decodable(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)

View File

@ -16,6 +16,7 @@ pub fn expand_deriving_default(
mitem: &ast::MetaItem, mitem: &ast::MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
@ -26,7 +27,6 @@ pub fn expand_deriving_default(
path: Path::new(vec![kw::Default, sym::Default]), path: Path::new(vec![kw::Default, sym::Default]),
skip_path_as_bound: has_a_default_variant(item), skip_path_as_bound: has_a_default_variant(item),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: kw::Default, name: kw::Default,
@ -47,6 +47,7 @@ pub fn expand_deriving_default(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }

View File

@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let krate = sym::rustc_serialize; let krate = sym::rustc_serialize;
let typaram = sym::__S; let typaram = sym::__S;
@ -109,7 +110,6 @@ pub fn expand_deriving_rustc_encodable(
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::encode, name: sym::encode,
@ -139,6 +139,7 @@ pub fn expand_deriving_rustc_encodable(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)

View File

@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr; use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::{Span, DUMMY_SP};
use std::cell::RefCell; use std::cell::RefCell;
use std::iter; use std::iter;
use std::ops::Not; use std::ops::Not;
@ -195,15 +195,14 @@ pub struct TraitDef<'a> {
/// other than the current trait /// other than the current trait
pub additional_bounds: Vec<Ty>, pub additional_bounds: Vec<Ty>,
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
pub generics: Bounds,
/// Can this trait be derived for unions? /// Can this trait be derived for unions?
pub supports_unions: bool, pub supports_unions: bool,
pub methods: Vec<MethodDef<'a>>, pub methods: Vec<MethodDef<'a>>,
pub associated_types: Vec<(Ident, Ty)>, pub associated_types: Vec<(Ident, Ty)>,
pub is_const: bool,
} }
pub struct MethodDef<'a> { pub struct MethodDef<'a> {
@ -581,14 +580,16 @@ impl<'a> TraitDef<'a> {
}) })
}); });
let Generics { mut params, mut where_clause, .. } = let mut where_clause = ast::WhereClause::default();
self.generics.to_generics(cx, self.span, type_ident, generics);
where_clause.span = generics.where_clause.span; where_clause.span = generics.where_clause.span;
let ctxt = self.span.ctxt(); let ctxt = self.span.ctxt();
let span = generics.span.with_ctxt(ctxt); let span = generics.span.with_ctxt(ctxt);
// Create the generic parameters // Create the generic parameters
params.extend(generics.params.iter().map(|param| match &param.kind { let params: Vec<_> = generics
.params
.iter()
.map(|param| match &param.kind {
GenericParamKind::Lifetime { .. } => param.clone(), GenericParamKind::Lifetime { .. } => param.clone(),
GenericParamKind::Type { .. } => { GenericParamKind::Type { .. } => {
// I don't think this can be moved out of the loop, since // I don't think this can be moved out of the loop, since
@ -620,7 +621,8 @@ impl<'a> TraitDef<'a> {
param_clone.kind = const_nodefault_kind; param_clone.kind = const_nodefault_kind;
param_clone param_clone
} }
})); })
.collect();
// and similarly for where clauses // and similarly for where clauses
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| { where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
@ -730,7 +732,7 @@ impl<'a> TraitDef<'a> {
unsafety: ast::Unsafe::No, unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive, polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
constness: ast::Const::No, constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No },
generics: trait_generics, generics: trait_generics,
of_trait: opt_trait_ref, of_trait: opt_trait_ref,
self_ty: self_type, self_ty: self_type,
@ -1060,18 +1062,15 @@ impl<'a> MethodDef<'a> {
trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, true); trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, true);
mk_body(cx, selflike_fields) mk_body(cx, selflike_fields)
} else { } else {
// Neither packed nor copy. Need to use ref patterns. // Packed and not copy. Need to use ref patterns.
let prefixes: Vec<_> = let prefixes: Vec<_> =
(0..selflike_args.len()).map(|i| format!("__self_{}", i)).collect(); (0..selflike_args.len()).map(|i| format!("__self_{}", i)).collect();
let addr_of = always_copy; let selflike_fields = trait_.create_struct_pattern_fields(cx, struct_def, &prefixes);
let selflike_fields =
trait_.create_struct_pattern_fields(cx, struct_def, &prefixes, addr_of);
let mut body = mk_body(cx, selflike_fields); let mut body = mk_body(cx, selflike_fields);
let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
let by_ref = ByRef::from(is_packed && !always_copy);
let patterns = let patterns =
trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref); trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, ByRef::Yes);
// Do the let-destructuring. // Do the let-destructuring.
let mut stmts: Vec<_> = iter::zip(selflike_args, patterns) let mut stmts: Vec<_> = iter::zip(selflike_args, patterns)
@ -1252,9 +1251,7 @@ impl<'a> MethodDef<'a> {
// A single arm has form (&VariantK, &VariantK, ...) => BodyK // A single arm has form (&VariantK, &VariantK, ...) => BodyK
// (see "Final wrinkle" note below for why.) // (see "Final wrinkle" note below for why.)
let addr_of = false; // because enums can't be repr(packed) let fields = trait_.create_struct_pattern_fields(cx, &variant.data, &prefixes);
let fields =
trait_.create_struct_pattern_fields(cx, &variant.data, &prefixes, addr_of);
let sp = variant.span.with_ctxt(trait_.span.ctxt()); let sp = variant.span.with_ctxt(trait_.span.ctxt());
let variant_path = cx.path(sp, vec![type_ident, variant.ident]); let variant_path = cx.path(sp, vec![type_ident, variant.ident]);
@ -1517,15 +1514,13 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
struct_def: &'a VariantData, struct_def: &'a VariantData,
prefixes: &[String], prefixes: &[String],
addr_of: bool,
) -> Vec<FieldInfo> { ) -> Vec<FieldInfo> {
self.create_fields(struct_def, |i, _struct_field, sp| { self.create_fields(struct_def, |i, _struct_field, sp| {
prefixes prefixes
.iter() .iter()
.map(|prefix| { .map(|prefix| {
let ident = self.mk_pattern_ident(prefix, i); let ident = self.mk_pattern_ident(prefix, i);
let expr = cx.expr_path(cx.path_ident(sp, ident)); cx.expr_path(cx.path_ident(sp, ident))
if addr_of { cx.expr_addr_of(sp, expr) } else { expr }
}) })
.collect() .collect()
}) })

View File

@ -13,6 +13,7 @@ pub fn expand_deriving_hash(
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
is_const: bool,
) { ) {
let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std); let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std);
@ -24,7 +25,6 @@ pub fn expand_deriving_hash(
path, path,
skip_path_as_bound: false, skip_path_as_bound: false,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::hash, name: sym::hash,
@ -39,6 +39,7 @@ pub fn expand_deriving_hash(
})), })),
}], }],
associated_types: Vec::new(), associated_types: Vec::new(),
is_const,
}; };
hash_trait_def.expand(cx, mitem, item, push); hash_trait_def.expand(cx, mitem, item, push);

View File

@ -38,9 +38,10 @@ pub mod partial_ord;
pub mod generic; pub mod generic;
pub(crate) struct BuiltinDerive( pub(crate) type BuiltinDeriveFn =
pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)), fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
);
pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn);
impl MultiItemModifier for BuiltinDerive { impl MultiItemModifier for BuiltinDerive {
fn expand( fn expand(
@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive {
span: Span, span: Span,
meta_item: &MetaItem, meta_item: &MetaItem,
item: Annotatable, item: Annotatable,
is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> { ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
// FIXME: Built-in derives often forget to give spans contexts, // FIXME: Built-in derives often forget to give spans contexts,
// so we are doing it here in a centralized way. // so we are doing it here in a centralized way.
@ -57,7 +59,12 @@ impl MultiItemModifier for BuiltinDerive {
match item { match item {
Annotatable::Stmt(stmt) => { Annotatable::Stmt(stmt) => {
if let ast::StmtKind::Item(item) = stmt.into_inner().kind { if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
(self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| { (self.0)(
ecx,
span,
meta_item,
&Annotatable::Item(item),
&mut |a| {
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
// to the function // to the function
items.push(Annotatable::Stmt(P(ast::Stmt { items.push(Annotatable::Stmt(P(ast::Stmt {
@ -65,13 +72,15 @@ impl MultiItemModifier for BuiltinDerive {
kind: ast::StmtKind::Item(a.expect_item()), kind: ast::StmtKind::Item(a.expect_item()),
span, span,
}))); })));
}); },
is_derive_const,
);
} else { } else {
unreachable!("should have already errored on non-item statement") unreachable!("should have already errored on non-item statement")
} }
} }
_ => { _ => {
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const);
} }
} }
ExpandResult::Ready(items) ExpandResult::Ready(items)

View File

@ -25,6 +25,7 @@ use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro; use rustc_expand::proc_macro::BangProcMacro;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
mod alloc_error_handler;
mod assert; mod assert;
mod cfg; mod cfg;
mod cfg_accessible; mod cfg_accessible;
@ -94,10 +95,12 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
} }
register_attr! { register_attr! {
alloc_error_handler: alloc_error_handler::expand,
bench: test::expand_bench, bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander, cfg_accessible: cfg_accessible::Expander,
cfg_eval: cfg_eval::expand, cfg_eval: cfg_eval::expand,
derive: derive::Expander, derive: derive::Expander(false),
derive_const: derive::Expander(true),
global_allocator: global_allocator::expand, global_allocator: global_allocator::expand,
test: test::expand_test, test: test::expand_test,
test_case: test::expand_test_case, test_case: test::expand_test_case,

View File

@ -216,7 +216,10 @@ pub fn expand_include_bytes(
} }
}; };
match cx.source_map().load_binary_file(&file) { match cx.source_map().load_binary_file(&file) {
Ok(bytes) => base::MacEager::expr(cx.expr_byte_str(sp, bytes)), Ok(bytes) => {
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes.into()));
base::MacEager::expr(expr)
}
Err(e) => { Err(e) => {
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp) DummyResult::any(sp)

View File

@ -112,7 +112,7 @@ pub fn expand_test_or_bench(
}; };
// Note: non-associated fn items are already handled by `expand_test_or_bench` // Note: non-associated fn items are already handled by `expand_test_or_bench`
if !matches!(item.kind, ast::ItemKind::Fn(_)) { let ast::ItemKind::Fn(fn_) = &item.kind else {
let diag = &cx.sess.parse_sess.span_diagnostic; let diag = &cx.sess.parse_sess.span_diagnostic;
let msg = "the `#[test]` attribute may only be used on a non-associated function"; let msg = "the `#[test]` attribute may only be used on a non-associated function";
let mut err = match item.kind { let mut err = match item.kind {
@ -130,7 +130,7 @@ pub fn expand_test_or_bench(
.emit(); .emit();
return vec![Annotatable::Item(item)]; return vec![Annotatable::Item(item)];
} };
// has_*_signature will report any errors in the type so compilation // has_*_signature will report any errors in the type so compilation
// will fail. We shouldn't try to expand in this case because the errors // will fail. We shouldn't try to expand in this case because the errors
@ -141,12 +141,14 @@ pub fn expand_test_or_bench(
return vec![Annotatable::Item(item)]; return vec![Annotatable::Item(item)];
} }
let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp)); let sp = cx.with_def_site_ctxt(item.span);
let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
let attr_sp = cx.with_def_site_ctxt(attr_sp);
let test_id = Ident::new(sym::test, attr_sp); let test_id = Ident::new(sym::test, attr_sp);
// creates test::$name // creates test::$name
let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]); let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
// creates test::ShouldPanic::$name // creates test::ShouldPanic::$name
let should_panic_path = |name| { let should_panic_path = |name| {
@ -192,7 +194,7 @@ pub fn expand_test_or_bench(
vec![ vec![
// super::$test_fn(b) // super::$test_fn(b)
cx.expr_call( cx.expr_call(
sp, ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])), cx.expr_path(cx.path(sp, vec![item.ident])),
vec![cx.expr_ident(sp, b)], vec![cx.expr_ident(sp, b)],
), ),
@ -216,7 +218,11 @@ pub fn expand_test_or_bench(
cx.expr_path(test_path("assert_test_result")), cx.expr_path(test_path("assert_test_result")),
vec![ vec![
// $test_fn() // $test_fn()
cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![]), // ) cx.expr_call(
ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])),
vec![],
), // )
], ],
), // } ), // }
), // ) ), // )

View File

@ -5,6 +5,7 @@ use crate::prelude::*;
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
use rustc_session::config::OomStrategy; use rustc_session::config::OomStrategy;
use rustc_span::symbol::sym;
/// Returns whether an allocator shim was created /// Returns whether an allocator shim was created
pub(crate) fn codegen( pub(crate) fn codegen(
@ -23,7 +24,7 @@ pub(crate) fn codegen(
module, module,
unwind_context, unwind_context,
kind, kind,
tcx.lang_items().oom().is_some(), tcx.alloc_error_handler_kind(()).unwrap(),
tcx.sess.opts.unstable_opts.oom, tcx.sess.opts.unstable_opts.oom,
); );
true true
@ -36,7 +37,7 @@ fn codegen_inner(
module: &mut impl Module, module: &mut impl Module,
unwind_context: &mut UnwindContext, unwind_context: &mut UnwindContext,
kind: AllocatorKind, kind: AllocatorKind,
has_alloc_error_handler: bool, alloc_error_handler_kind: AllocatorKind,
oom_strategy: OomStrategy, oom_strategy: OomStrategy,
) { ) {
let usize_ty = module.target_config().pointer_type(); let usize_ty = module.target_config().pointer_type();
@ -108,12 +109,12 @@ fn codegen_inner(
returns: vec![], returns: vec![],
}; };
let callee_name = if has_alloc_error_handler { "__rg_oom" } else { "__rdl_oom" }; let callee_name = alloc_error_handler_kind.fn_name(sym::oom);
let func_id = let func_id =
module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap(); module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();
let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap(); let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func.signature = sig; ctx.func.signature = sig;

View File

@ -38,6 +38,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
_lib_name: &str, _lib_name: &str,
_dll_imports: &[rustc_session::cstore::DllImport], _dll_imports: &[rustc_session::cstore::DllImport],
_tmpdir: &Path, _tmpdir: &Path,
_is_direct_dependency: bool,
) -> PathBuf { ) -> PathBuf {
bug!("creating dll imports is not supported"); bug!("creating dll imports is not supported");
} }

View File

@ -770,11 +770,7 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
} }
Rvalue::NullaryOp(null_op, ty) => { Rvalue::NullaryOp(null_op, ty) => {
assert!( assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all()));
lval.layout()
.ty
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
);
let layout = fx.layout_of(fx.monomorphize(ty)); let layout = fx.layout_of(fx.monomorphize(ty));
let val = match null_op { let val = match null_op {
NullOp::SizeOf => layout.size.bytes(), NullOp::SizeOf => layout.size.bytes(),

View File

@ -5,7 +5,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{
read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar, read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
}; };
use rustc_span::DUMMY_SP;
use cranelift_module::*; use cranelift_module::*;
@ -129,7 +128,7 @@ pub(crate) fn codegen_const_value<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> CValue<'tcx> { ) -> CValue<'tcx> {
let layout = fx.layout_of(ty); let layout = fx.layout_of(ty);
assert!(!layout.is_unsized(), "sized const value"); assert!(layout.is_sized(), "unsized const value");
if layout.is_zst() { if layout.is_zst() {
return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout); return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout);
@ -291,7 +290,7 @@ fn data_id_for_static(
let is_mutable = if tcx.is_mutable_static(def_id) { let is_mutable = if tcx.is_mutable_static(def_id) {
true true
} else { } else {
!ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) !ty.is_freeze(tcx, ParamEnv::reveal_all())
}; };
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();

Some files were not shown because too many files have changed in this diff Show More