Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2023-12-14 05:02:50 +00:00
commit 7d4f92a309
664 changed files with 14806 additions and 8430 deletions

View file

@ -1,8 +1,6 @@
# WARNING: this metadata is currently incomplete, do not rely on it yet.
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files-Excluded:
src/llvm-project
# Note that we're explicitly listing the individual files at the root of the
# repository rather than just having `Files: *`. This is explicitly done to
@ -39,13 +37,8 @@ Files: compiler/*
Copyright: The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT or Apache-2.0
Files: compiler/rustc_codegen_cranelift/src/cranelift_native.rs
Copyright: The Cranelift Project Developers
The Rust Project Developers (see https://thanks.rust-lang.org)
License: Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT)
Files: compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
Copyright: LLVM authors
Copyright: 2003-2019 University of Illinois at Urbana-Champaign.
The Rust Project Developers (see https://thanks.rust-lang.org)
License: Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT)
@ -85,11 +78,44 @@ Files: src/librustdoc/html/static/css/normalize.css
Copyright: Nicolas Gallagher and Jonathan Neal
License: MIT
Files: src/librustdoc/html/static/css/themes/ayu.css
Copyright: Ike Ku, Jessica Stokes, Leon Guan
Files: src/librustdoc/html/static/css/rustdoc.css
Copyright: 2016 Ike Ku, Jessica Stokes and Leon Guan
The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT OR Apache-2.0
Files: src/doc/rustc-dev-guide/mermaid.min.js
Copyright: Knut Sveidqvist
Copyright: 2014-2021 Knut Sveidqvist
License: MIT
Files: library/backtrace/*
Copyright: 2014 Alex Crichton
The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT OR Apache-2.0
Files: src/doc/embedded-book/*
Copyright: Rust on Embedded Devices Working Group
The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT OR Apache-2.0 OR CC-BY-SA-4.0
Files: src/doc/rust-by-example/*
Copyright: 2014 Jorge Aparicio
The Rust Project Developers (see https://thanks.rust-lang.org)
License: MIT OR Apache-2.0
# Reuse cannot process the LLVM source tree, and so the copyrights for the LLVM
# submodule are written out here manually. The collect-licence-metadata tool
# has a specific exception coded within it to ignore ./src/llvm-project so
# any time LLVM is updated, please revisit this section. The copyrights are
# taken from the relevant LLVM sub-folders: llvm, lld, lldb, compiler-rt and libunwind.
#
# The git hash for the CREDITS.TXT file is taken from the current git submodule
# commit for ./src/llvm-project.
#
# The copyright years were compiled by looking at all the relevant
# ./src/llvm-project/*/LICENSE.txt files
Files: src/llvm-project/*
Copyright: 2003-2019 by the contributors listed in [CREDITS.TXT](https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)
2010 Apple Inc
2003-2019 University of Illinois at Urbana-Champaign.
License: NCSA AND Apache-2.0 WITH LLVM-exception

319
LICENSES/CC-BY-3.0.txt Normal file
View file

@ -0,0 +1,319 @@
Creative Commons Legal Code
Attribution 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
1. Definitions
a. "Adaptation" means a work based upon the Work, or upon the Work and
other pre-existing works, such as a translation, adaptation,
derivative work, arrangement of music or other alterations of a
literary or artistic work, or phonogram or performance and includes
cinematographic adaptations or any other form in which the Work may be
recast, transformed, or adapted including in any form recognizably
derived from the original, except that a work that constitutes a
Collection will not be considered an Adaptation for the purpose of
this License. For the avoidance of doubt, where the Work is a musical
work, performance or phonogram, the synchronization of the Work in
timed-relation with a moving image ("synching") will be considered an
Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as
encyclopedias and anthologies, or performances, phonograms or
broadcasts, or other works or subject matter other than works listed
in Section 1(f) below, which, by reason of the selection and
arrangement of their contents, constitute intellectual creations, in
which the Work is included in its entirety in unmodified form along
with one or more other contributions, each constituting separate and
independent works in themselves, which together are assembled into a
collective whole. A work that constitutes a Collection will not be
considered an Adaptation (as defined above) for the purposes of this
License.
c. "Distribute" means to make available to the public the original and
copies of the Work or Adaptation, as appropriate, through sale or
other transfer of ownership.
d. "Licensor" means the individual, individuals, entity or entities that
offer(s) the Work under the terms of this License.
e. "Original Author" means, in the case of a literary or artistic work,
the individual, individuals, entity or entities who created the Work
or if no individual or entity can be identified, the publisher; and in
addition (i) in the case of a performance the actors, singers,
musicians, dancers, and other persons who act, sing, deliver, declaim,
play in, interpret or otherwise perform literary or artistic works or
expressions of folklore; (ii) in the case of a phonogram the producer
being the person or legal entity who first fixes the sounds of a
performance or other sounds; and, (iii) in the case of broadcasts, the
organization that transmits the broadcast.
f. "Work" means the literary and/or artistic work offered under the terms
of this License including without limitation any production in the
literary, scientific and artistic domain, whatever may be the mode or
form of its expression including digital form, such as a book,
pamphlet and other writing; a lecture, address, sermon or other work
of the same nature; a dramatic or dramatico-musical work; a
choreographic work or entertainment in dumb show; a musical
composition with or without words; a cinematographic work to which are
assimilated works expressed by a process analogous to cinematography;
a work of drawing, painting, architecture, sculpture, engraving or
lithography; a photographic work to which are assimilated works
expressed by a process analogous to photography; a work of applied
art; an illustration, map, plan, sketch or three-dimensional work
relative to geography, topography, architecture or science; a
performance; a broadcast; a phonogram; a compilation of data to the
extent it is protected as a copyrightable work; or a work performed by
a variety or circus performer to the extent it is not otherwise
considered a literary or artistic work.
g. "You" means an individual or entity exercising rights under this
License who has not previously violated the terms of this License with
respect to the Work, or who has received express permission from the
Licensor to exercise rights under this License despite a previous
violation.
h. "Publicly Perform" means to perform public recitations of the Work and
to communicate to the public those public recitations, by any means or
process, including by wire or wireless means or public digital
performances; to make available to the public Works in such a way that
members of the public may access these Works from a place and at a
place individually chosen by them; to perform the Work to the public
by any means or process and the communication to the public of the
performances of the Work, including by public digital performance; to
broadcast and rebroadcast the Work by any means including signs,
sounds or images.
i. "Reproduce" means to make copies of the Work by any means including
without limitation by sound or visual recordings and the right of
fixation and reproducing fixations of the Work, including storage of a
protected performance or phonogram in digital form or other electronic
medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
limit, or restrict any uses free from copyright or rights arising from
limitations or exceptions that are provided for in connection with the
copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more
Collections, and to Reproduce the Work as incorporated in the
Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation,
including any translation in any medium, takes reasonable steps to
clearly label, demarcate or otherwise identify that changes were made
to the original Work. For example, a translation could be marked "The
original work was translated from English to Spanish," or a
modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated
in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt:
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme cannot be waived, the Licensor
reserves the exclusive right to collect such royalties for any
exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme can be waived, the Licensor waives the
exclusive right to collect such royalties for any exercise by You
of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to
collect royalties, whether individually or, in the event that the
Licensor is a member of a collecting society that administers
voluntary licensing schemes, via that society, from any exercise
by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights in
other media and formats. Subject to Section 8(f), all rights not expressly
granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made
subject to and limited by the following restrictions:
a. You may Distribute or Publicly Perform the Work only under the terms
of this License. You must include a copy of, or the Uniform Resource
Identifier (URI) for, this License with every copy of the Work You
Distribute or Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or the ability of
the recipient of the Work to exercise the rights granted to that
recipient under the terms of the License. You may not sublicense the
Work. You must keep intact all notices that refer to this License and
to the disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or Publicly
Perform the Work, You may not impose any effective technological
measures on the Work that restrict the ability of a recipient of the
Work from You to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to the Work as
incorporated in a Collection, but this does not require the Collection
apart from the Work itself to be made subject to the terms of this
License. If You create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the Collection any credit
as required by Section 4(b), as requested. If You create an
Adaptation, upon notice from any Licensor You must, to the extent
practicable, remove from the Adaptation any credit as required by
Section 4(b), as requested.
b. If You Distribute, or Publicly Perform the Work or any Adaptations or
Collections, You must, unless a request has been made pursuant to
Section 4(a), keep intact all copyright notices for the Work and
provide, reasonable to the medium or means You are utilizing: (i) the
name of the Original Author (or pseudonym, if applicable) if supplied,
and/or if the Original Author and/or Licensor designate another party
or parties (e.g., a sponsor institute, publishing entity, journal) for
attribution ("Attribution Parties") in Licensor's copyright notice,
terms of service or by other reasonable means, the name of such party
or parties; (ii) the title of the Work if supplied; (iii) to the
extent reasonably practicable, the URI, if any, that Licensor
specifies to be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information for the Work;
and (iv) , consistent with Section 3(b), in the case of an Adaptation,
a credit identifying the use of the Work in the Adaptation (e.g.,
"French translation of the Work by Original Author," or "Screenplay
based on original Work by Original Author"). The credit required by
this Section 4 (b) may be implemented in any reasonable manner;
provided, however, that in the case of a Adaptation or Collection, at
a minimum such credit will appear, if a credit for all contributing
authors of the Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the credits for the
other contributing authors. For the avoidance of doubt, You may only
use the credit required by this Section for the purpose of attribution
in the manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your
use of the Work, without the separate, express prior written
permission of the Original Author, Licensor and/or Attribution
Parties.
c. Except as otherwise agreed in writing by the Licensor or as may be
otherwise permitted by applicable law, if You Reproduce, Distribute or
Publicly Perform the Work either by itself or as part of any
Adaptations or Collections, You must not distort, mutilate, modify or
take other derogatory action in relation to the Work which would be
prejudicial to the Original Author's honor or reputation. Licensor
agrees that in those jurisdictions (e.g. Japan), in which any exercise
of the right granted in Section 3(b) of this License (the right to
make Adaptations) would be deemed to be a distortion, mutilation,
modification or other derogatory action prejudicial to the Original
Author's honor and reputation, the Licensor will waive or not assert,
as appropriate, this Section, to the fullest extent permitted by the
applicable national law, to enable You to reasonably exercise Your
right under Section 3(b) of this License (right to make Adaptations)
but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Adaptations or Collections
from You under this License, however, will not have their licenses
terminated provided such individuals or entities remain in full
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is
perpetual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, Licensor reserves the right to release the
Work under different license terms or to stop distributing the Work at
any time; provided, however that any such election will not serve to
withdraw this License (or any other license that has been, or is
required to be, granted under the terms of this License), and this
License will continue in full force and effect unless terminated as
stated above.
8. Miscellaneous
a. Each time You Distribute or Publicly Perform the Work or a Collection,
the Licensor offers to the recipient a license to the Work on the same
terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
offers to the recipient a license to the original Work on the same
terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
d. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties with
respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that
may appear in any communication from You. This License may not be
modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this
License were drafted utilizing the terminology of the Berne Convention
for the Protection of Literary and Artistic Works (as amended on
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
and the Universal Copyright Convention (as revised on July 24, 1971).
These rights and subject matter take effect in the relevant
jurisdiction in which the License terms are sought to be enforced
according to the corresponding provisions of the implementation of
those treaty provisions in the applicable national law. If the
standard suite of rights granted under applicable copyright law
includes additional rights not granted under this License, such
additional rights are deemed to be included in the License; this
License is not intended to restrict the license of any rights under
applicable law.
Creative Commons Notice
Creative Commons is not a party to this License, and makes no warranty
whatsoever in connection with the Work. Creative Commons will not be
liable to You or any party on any legal theory for any damages
whatsoever, including without limitation any general, special,
incidental or consequential damages arising in connection to this
license. Notwithstanding the foregoing two (2) sentences, if Creative
Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the
Work is licensed under the CCPL, Creative Commons does not authorize
the use by either party of the trademark "Creative Commons" or any
related trademark or logo of Creative Commons without the prior
written consent of Creative Commons. Any permitted use will be in
compliance with Creative Commons' then-current trademark usage
guidelines, as may be published on its website or otherwise made
available upon request from time to time. For the avoidance of doubt,
this trademark restriction does not form part of this License.
Creative Commons may be contacted at https://creativecommons.org/.

427
LICENSES/CC-BY-SA-4.0.txt Normal file
View file

@ -0,0 +1,427 @@
Attribution-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-ShareAlike 4.0 International Public
License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-ShareAlike 4.0 International Public License ("Public
License"). To the extent this Public License may be interpreted as a
contract, You are granted the Licensed Rights in consideration of Your
acceptance of these terms and conditions, and the Licensor grants You
such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and
conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
l. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
m. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

121
LICENSES/CC0-1.0.txt Normal file
View file

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

29
LICENSES/NCSA.txt Normal file
View file

@ -0,0 +1,29 @@
Copyright (c) <YEAR> <OWNER ORGANIZATION NAME>. All rights reserved.
Developed by: <NAME OF DEVELOPMENT GROUP>
<NAME OF INSTITUTION>
<URL FOR DEVELOPMENT GROUP/INSTITUTION>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to
do so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the documentation
and/or other materials provided with the distribution.
* Neither the names of <NAME OF DEVELOPMENT GROUP>, <NAME OF INSTITUTION>,
nor the names of its contributors may be used to endorse or promote products
derived from this Software without specific prior written permission.
THE SOFTWARE IS 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. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

View file

@ -1222,6 +1222,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
| ExprKind::Struct(..)
| ExprKind::Tup(..)
| ExprKind::Underscore => false,
// Check for unit struct constructor.
ExprKind::Path(..) => lower_ctx.extract_unit_struct_path(lhs).is_none(),
// Check for tuple struct constructor.
ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(),
ExprKind::Paren(e) => {

View file

@ -18,7 +18,7 @@ use rustc_middle::mir::{
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
VarBindingForm,
};
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TyCtxt};
use rustc_middle::util::CallKind;
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::LocalDefId;
@ -398,7 +398,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
let hir_id = hir.parent_id(expr.hir_id);
if let Some(parent) = hir.find(hir_id) {
if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) {
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
@ -413,7 +413,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let Some(node) = hir.find(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(node) = self
.infcx
.tcx
.opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
@ -1317,7 +1320,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;
let hir = tcx.hir();
let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
let typeck_results = tcx.typeck(self.mir_def_id());
struct ExprFinder<'hir> {
@ -1509,7 +1512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let local_ty = self.body.local_decls[local].ty;
// Get the body the error happens in
let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
let body_expr = hir.body(body_id).value;
@ -1558,7 +1561,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Check that the parent of the closure is a method call,
// with receiver matching with local's type (modulo refs)
let parent = hir.parent_id(closure_expr.hir_id);
if let hir::Node::Expr(parent) = hir.get(parent) {
if let hir::Node::Expr(parent) = tcx.hir_node(parent) {
if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind {
let recv_ty = typeck_results.expr_ty(recv);
@ -1635,15 +1638,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
issued_spans: &UseSpans<'tcx>,
) {
let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
let hir = self.infcx.tcx.hir();
struct ExpressionFinder<'hir> {
struct ExpressionFinder<'tcx> {
capture_span: Span,
closure_change_spans: Vec<Span>,
closure_arg_span: Option<Span>,
in_closure: bool,
suggest_arg: String,
hir: rustc_middle::hir::map::Map<'hir>,
tcx: TyCtxt<'tcx>,
closure_local_id: Option<hir::HirId>,
closure_call_changes: Vec<(Span, String)>,
}
@ -1657,7 +1659,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn_decl: hir::FnDecl { inputs, .. },
..
}) = e.kind
&& let Some(hir::Node::Expr(body)) = self.hir.find(body.hir_id)
&& let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id)
{
self.suggest_arg = "this: &Self".to_string();
if inputs.len() > 0 {
@ -1722,8 +1724,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
..
})) = hir.find(self.mir_hir_id())
&& let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
})) = self.infcx.tcx.opt_hir_node(self.mir_hir_id())
&& let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id)
{
let mut finder = ExpressionFinder {
capture_span: *capture_kind_span,
@ -1733,7 +1735,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
suggest_arg: String::new(),
closure_local_id: None,
closure_call_changes: vec![],
hir,
tcx: self.infcx.tcx,
};
finder.visit_expr(expr);
@ -2294,7 +2296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let proper_span = proper_span.source_callsite();
if let Some(scope) = self.body.source_scopes.get(source_info.scope)
&& let ClearCrossCrate::Set(scope_data) = &scope.local_data
&& let Some(node) = self.infcx.tcx.hir().find(scope_data.lint_root)
&& let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root)
&& let Some(id) = node.body_id()
&& let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind
{

View file

@ -87,7 +87,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
&& let [hir::PathSegment { ident, args: None, .. }] = p.segments
&& let hir::def::Res::Local(hir_id) = p.res
&& let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id)
&& let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id)
{
err.span_label(pat.span, format!("binding `{ident}` declared here"));
}

View file

@ -1204,7 +1204,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
err.multipart_suggestion_verbose(
msg,
sugg.clone(),
sugg,
Applicability::MaybeIncorrect,
);
for error in errors {

View file

@ -396,7 +396,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvar_hir_id = captured_place.get_root_variable();
if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id)
&& let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
pat.kind
{
@ -661,7 +661,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if self.body.local_kind(local) != LocalKind::Arg {
return (false, None);
}
let hir_map = self.infcx.tcx.hir();
let my_def = self.body.source.def_id();
let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap());
let Some(td) =
@ -671,7 +670,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
(
true,
td.as_local().and_then(|tld| match hir_map.find_by_def_id(tld) {
td.as_local().and_then(|tld| match self.infcx.tcx.opt_hir_node_by_def_id(tld) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, items),
..
@ -682,25 +681,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if !matches!(k, hir::AssocItemKind::Fn { .. }) {
continue;
}
if hir_map.name(hi) != hir_map.name(my_hir) {
if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) {
continue;
}
f_in_trait_opt = Some(hi);
break;
}
f_in_trait_opt.and_then(|f_in_trait| match hir_map.find(f_in_trait) {
Some(Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
_,
),
..
})) => {
let hir::Ty { span, .. } = inputs[local.index() - 1];
Some(span)
f_in_trait_opt.and_then(|f_in_trait| {
match self.infcx.tcx.opt_hir_node(f_in_trait) {
Some(Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
_,
),
..
})) => {
let hir::Ty { span, .. } = inputs[local.index() - 1];
Some(span)
}
_ => None,
}
_ => None,
})
}
_ => None,
@ -741,12 +742,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
&& let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
{
let body = hir_map.body(body_id);
let body = self.infcx.tcx.hir().body(body_id);
let mut v = BindingFinder { span: pat_span, hir_id: None };
v.visit_body(body);
v.hir_id
@ -762,7 +762,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&& let Some(hir::Node::Local(hir::Local {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
..
})) = hir_map.find(hir_id)
})) = self.infcx.tcx.opt_hir_node(hir_id)
&& let Ok(name) =
self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
{
@ -942,7 +942,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let closure_id = self.mir_hir_id();
let closure_span = self.infcx.tcx.def_span(self.mir_def_id());
let fn_call_id = hir.parent_id(closure_id);
let node = hir.get(fn_call_id);
let node = self.infcx.tcx.hir_node(fn_call_id);
let def_id = hir.enclosing_body_owner(fn_call_id);
let mut look_at_return = true;
// If we can detect the expression to be an `fn` call where the closure was an argument,
@ -1001,7 +1001,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if look_at_return && hir.get_return_block(closure_id).is_some() {
// ...otherwise we are probably in the tail expression of the function, point at the
// return type.
match hir.get_by_def_id(hir.get_parent_item(fn_call_id).def_id) {
match self.infcx.tcx.hir_node_by_def_id(hir.get_parent_item(fn_call_id).def_id) {
hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. })
| hir::Node::TraitItem(hir::TraitItem {
ident,
@ -1199,12 +1199,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
hir::intravisit::walk_stmt(self, s);
}
}
let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
&& let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
{
let body = hir_map.body(body_id);
let body = self.infcx.tcx.hir().body(body_id);
let mut v = BindingFinder { span: err_label_span, hir_id: None };
v.visit_body(body);
v.hir_id
@ -1213,7 +1212,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
&& let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id)
{
let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
@ -1496,7 +1495,7 @@ fn get_mut_span_in_struct_field<'tcx>(
&& let ty::Adt(def, _) = ty.kind()
&& let field = def.all_fields().nth(field.index())?
// Use the HIR types to construct the diagnostic message.
&& let node = tcx.hir().find_by_def_id(field.did.as_local()?)?
&& let node = tcx.opt_hir_node_by_def_id(field.did.as_local()?)?
// Now we're dealing with the actual struct that we're going to suggest a change to,
// we can expect a field that is an immutable reference to a type.
&& let hir::Node::Field(field) = node

View file

@ -672,7 +672,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let mir_hir_id = self.mir_hir_id();
let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) {
let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) {
hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, .. }),
..
@ -689,7 +689,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::CoroutineSource::Closure => " of async closure",
hir::CoroutineSource::Fn => {
let parent_item =
hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
let output = &parent_item
.fn_decl()
.expect("coroutine lowered from async fn should be in fn")
@ -706,7 +706,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::CoroutineSource::Closure => " of gen closure",
hir::CoroutineSource::Fn => {
let parent_item =
hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
let output = &parent_item
.fn_decl()
.expect("coroutine lowered from gen fn should be in fn")
@ -721,7 +721,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::CoroutineSource::Closure => " of async gen closure",
hir::CoroutineSource::Fn => {
let parent_item =
hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
let output = &parent_item
.fn_decl()
.expect("coroutine lowered from async gen fn should be in fn")
@ -841,7 +841,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let type_name =
self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;
let yield_span = match tcx.hir().get(self.mir_hir_id()) {
let yield_span = match tcx.hir_node(self.mir_hir_id()) {
hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
..

View file

@ -75,11 +75,6 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"example/arbitrary_self_types_pointers_and_wrappers.rs",
&[],
),
TestCase::build_bin_and_run(
"aot.issue_91827_extern_types",
"example/issue-91827-extern-types.rs",
&[],
),
TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""),

View file

@ -1,55 +0,0 @@
// Copied from rustc ui test suite
// run-pass
//
// Test that we can handle unsized types with an extern type tail part.
// Regression test for issue #91827.
#![feature(extern_types)]
use std::ptr::addr_of;
extern "C" {
type Opaque;
}
unsafe impl Sync for Opaque {}
#[repr(C)]
pub struct List<T> {
len: usize,
data: [T; 0],
tail: Opaque,
}
#[repr(C)]
pub struct ListImpl<T, const N: usize> {
len: usize,
data: [T; N],
}
impl<T> List<T> {
const fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
}
}
impl<T, const N: usize> ListImpl<T, N> {
const fn as_list(&self) -> &List<T> {
unsafe { std::mem::transmute(self) }
}
}
pub static A: ListImpl<u128, 3> = ListImpl { len: 3, data: [5, 6, 7] };
pub static A_REF: &'static List<u128> = A.as_list();
pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
const fn tail_offset<T>(list: &List<T>) -> isize {
unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
}
fn main() {
assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
// Check that interpreter and code generation agree about the position of the tail field.
assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
}

View file

@ -816,6 +816,9 @@ impl ThinLTOKeysMap {
use std::io::Write;
let file = File::create(path)?;
let mut writer = io::BufWriter::new(file);
// The entries are loaded back into a hash map in `load_from_file()`, so
// the order in which we write them to file here does not matter.
#[allow(rustc::potential_query_instability)]
for (module, key) in &self.keys {
writeln!(writer, "{module} {key}")?;
}

View file

@ -58,6 +58,11 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
return;
}
// The entries of the map are only used to get a list of all files with
// coverage info. In the end the list of files is passed into
// `GlobalFileTable::new()` which internally do `.sort_unstable_by()`, so
// the iteration order here does not matter.
#[allow(rustc::potential_query_instability)]
let function_coverage_entries = function_coverage_map
.into_iter()
.map(|(instance, function_coverage)| (instance, function_coverage.into_finished()))

View file

@ -17,6 +17,7 @@ use crate::debuginfo::utils::FatPtrKind;
use crate::llvm;
use crate::llvm::debuginfo::{
DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind,
DebugNameTableKind,
};
use crate::value::Value;
@ -38,6 +39,7 @@ use rustc_span::FileName;
use rustc_span::{FileNameDisplayPreference, SourceFile};
use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::abi::{Align, Size};
use rustc_target::spec::DebuginfoKind;
use smallvec::smallvec;
use libc::{c_char, c_longlong, c_uint};
@ -878,6 +880,17 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
let split_name = split_name.to_str().unwrap();
let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
let dwarf_version =
tcx.sess.opts.unstable_opts.dwarf_version.unwrap_or(tcx.sess.target.default_dwarf_version);
let is_dwarf_kind =
matches!(tcx.sess.target.debuginfo_kind, DebuginfoKind::Dwarf | DebuginfoKind::DwarfDsym);
// Don't emit `.debug_pubnames` and `.debug_pubtypes` on DWARFv4 or lower.
let debug_name_table_kind = if is_dwarf_kind && dwarf_version <= 4 {
DebugNameTableKind::None
} else {
DebugNameTableKind::Default
};
unsafe {
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
debug_context.builder,
@ -907,6 +920,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
kind,
0,
tcx.sess.opts.unstable_opts.split_dwarf_inlining,
debug_name_table_kind,
);
if tcx.sess.opts.unstable_opts.profile {

View file

@ -1568,7 +1568,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
// Alignment of T, must be a constant integer value:
let alignment_ty = bx.type_i32();
let alignment = bx.const_i32(bx.align_of(values_ty).bytes() as i32);
let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);
// Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = {

View file

@ -17,7 +17,6 @@
#![feature(never_type)]
#![feature(impl_trait_in_assoc_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

View file

@ -5,7 +5,7 @@ use super::debuginfo::{
DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator,
DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DILocation, DINameSpace,
DISPFlags, DIScope, DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable,
DebugEmissionKind,
DebugEmissionKind, DebugNameTableKind,
};
use libc::{c_char, c_int, c_uint, size_t};
@ -794,6 +794,15 @@ pub mod debuginfo {
}
}
}
/// LLVMRustDebugNameTableKind
#[derive(Clone, Copy)]
#[repr(C)]
pub enum DebugNameTableKind {
Default,
Gnu,
None,
}
}
use bitflags::bitflags;
@ -1812,6 +1821,7 @@ extern "C" {
kind: DebugEmissionKind,
DWOId: u64,
SplitDebugInlining: bool,
DebugNameTableKind: DebugNameTableKind,
) -> &'a DIDescriptor;
pub fn LLVMRustDIBuilderCreateFile<'a>(

View file

@ -51,10 +51,10 @@ pub mod codegen_attrs;
pub mod common;
pub mod debuginfo;
pub mod errors;
pub mod glue;
pub mod meth;
pub mod mir;
pub mod mono_item;
pub mod size_of_val;
pub mod target_features;
pub mod traits;

View file

@ -4,8 +4,8 @@ use super::FunctionCx;
use crate::common::IntPredicate;
use crate::errors;
use crate::errors::InvalidMonomorphization;
use crate::glue;
use crate::meth;
use crate::size_of_val;
use crate::traits::*;
use crate::MemFlags;
@ -88,21 +88,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::va_end => bx.va_end(args[0].immediate()),
sym::size_of_val => {
let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val {
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llsize
} else {
bx.const_usize(bx.layout_of(tp_ty).size.bytes())
}
let meta =
if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
llsize
}
sym::min_align_of_val => {
let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val {
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llalign
} else {
bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
}
let meta =
if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
llalign
}
sym::vtable_size | sym::vtable_align => {
let vtable = args[0].immediate();

View file

@ -2,7 +2,7 @@ use super::place::PlaceRef;
use super::{FunctionCx, LocalRef};
use crate::base;
use crate::glue;
use crate::size_of_val;
use crate::traits::*;
use crate::MemFlags;
@ -466,13 +466,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
.ty;
let OperandValue::Ref(llptr, Some(llextra), _) = self else {
bug!("store_unsized called with a sized value")
bug!("store_unsized called with a sized value (or with an extern type)")
};
// Allocate an appropriate region on the stack, and copy the value into it. Since alloca
// doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
// pointer manually.
let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
let one = bx.const_usize(1);
let align_minus_1 = bx.sub(align, one);
let size_extra = bx.add(size, align_minus_1);

View file

@ -2,7 +2,7 @@ use super::operand::OperandValue;
use super::{FunctionCx, LocalRef};
use crate::common::IntPredicate;
use crate::glue;
use crate::size_of_val;
use crate::traits::*;
use rustc_middle::mir;
@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
let offset = self.layout.fields.offset(ix);
let effective_field_align = self.align.restrict_for_offset(offset);
// `simple` is called when we don't need to adjust the offset to
// the dynamic alignment of the field.
let mut simple = || {
let llval = match self.layout.abi {
_ if offset.bytes() == 0 => {
@ -141,28 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
};
// Simple cases, which don't need DST adjustment:
// * no metadata available - just log the case
// * known alignment - sized types, `[T]`, `str` or a foreign type
// * known alignment - sized types, `[T]`, `str`
// * offset 0 -- rounding up to alignment cannot change the offset
// Note that looking at `field.align` is incorrect since that is not necessarily equal
// to the dynamic alignment of the type.
match field.ty.kind() {
_ if self.llextra.is_none() => {
debug!(
"unsized field `{}`, of `{:?}` has no metadata for adjustment",
ix, self.llval
);
return simple();
}
_ if field.is_sized() => return simple(),
ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
ty::Slice(..) | ty::Str => return simple(),
_ if offset.bytes() == 0 => return simple(),
_ => {}
}
// We need to get the pointer manually now.
// We do this by casting to a `*i8`, then offsetting it by the appropriate amount.
// We do this instead of, say, simply adjusting the pointer from the result of a GEP
// because the field may have an arbitrary alignment in the LLVM representation
// anyway.
// because the field may have an arbitrary alignment in the LLVM representation.
//
// To demonstrate:
//
@ -179,7 +174,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
let unaligned_offset = bx.cx().const_usize(offset.bytes());
// Get the alignment of the field
let (_, mut unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
let (_, mut unsized_align) = size_of_val::size_and_align_of_dst(bx, field.ty, meta);
// For packed types, we need to cap alignment.
if let ty::Adt(def, _) = self.layout.ty.kind()

View file

@ -1,10 +1,11 @@
//!
//
// Code relating to drop glue.
//! Computing the size and alignment of a value.
use crate::common;
use crate::common::IntPredicate;
use crate::meth;
use crate::traits::*;
use rustc_hir::LangItem;
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty};
use rustc_target::abi::WrappingRange;
@ -14,7 +15,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
info: Option<Bx::Value>,
) -> (Bx::Value, Bx::Value) {
let layout = bx.layout_of(t);
debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
if layout.is_sized() {
let size = bx.const_usize(layout.size.bytes());
let align = bx.const_usize(layout.align.abi.bytes());
@ -51,7 +52,31 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.const_usize(unit.align.abi.bytes()),
)
}
_ => {
ty::Foreign(_) => {
// `extern` type. We cannot compute the size, so panic.
let msg_str = with_no_visible_paths!({
with_no_trimmed_paths!({
format!("attempted to compute the size or alignment of extern type `{t}`")
})
});
let msg = bx.const_str(&msg_str);
// Obtain the panic entry point.
let (fn_abi, llfn) = common::build_langcall(bx, None, LangItem::PanicNounwind);
// Generate the call.
// Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
// (But we are in good company, this code is duplicated plenty of times.)
let fn_ty = bx.fn_decl_backend_type(fn_abi);
bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None);
// This function does not return so we can now return whatever we want.
let size = bx.const_usize(layout.size.bytes());
let align = bx.const_usize(layout.align.abi.bytes());
(size, align)
}
ty::Adt(..) | ty::Tuple(..) => {
// First get the size of all statically known fields.
// Don't use size_of because it also rounds up to alignment, which we
// want to avoid, as the unsized field's alignment could be smaller.
@ -122,5 +147,6 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(size, align)
}
_ => bug!("size_and_align_of_dst: {t} not supported"),
}
}

View file

@ -33,7 +33,7 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
/// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic
/// has a `rustc_const_{un,}stable` attribute. Otherwise, return `Constness::NotConst`.
fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
let node = tcx.hir().get_by_def_id(def_id);
let node = tcx.hir_node_by_def_id(def_id);
match node {
hir::Node::Ctor(_)

View file

@ -174,12 +174,15 @@ where
};
(base_meta, offset.align_to(align))
}
None => {
// For unsized types with an extern type tail we perform no adjustments.
// NOTE: keep this in sync with `PlaceRef::project_field` in the codegen backend.
assert!(matches!(base_meta, MemPlaceMeta::None));
None if offset == Size::ZERO => {
// If the offset is 0, then rounding it up to alignment wouldn't change anything,
// so we can do this even for types where we cannot determine the alignment.
(base_meta, offset)
}
None => {
// We don't know the alignment of this field, so we cannot adjust.
throw_unsup_format!("`extern type` does not have a known offset")
}
}
} else {
// base_meta could be present; we might be accessing a sized field of an unsized

View file

@ -227,7 +227,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// Sometimes the index is beyond the number of upvars (seen
// for a coroutine).
let var_hir_id = captured_place.get_root_variable();
let node = self.ecx.tcx.hir().get(var_hir_id);
let node = self.ecx.tcx.hir_node(var_hir_id);
if let hir::Node::Pat(pat) = node {
if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
name = Some(ident.name);

View file

@ -21,7 +21,7 @@ pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized {
/// `read_discriminant` can be hooked for better error messages.
#[inline(always)]
fn read_discriminant(&mut self, v: &Self::V) -> InterpResult<'tcx, VariantIdx> {
Ok(self.ecx().read_discriminant(&v.to_op(self.ecx())?)?)
self.ecx().read_discriminant(&v.to_op(self.ecx())?)
}
/// This function provides the chance to reorder the order in which fields are visited for

View file

@ -119,8 +119,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
match self_ty.kind() {
Param(param_ty) => {
debug!(?param_ty);
let caller_hir_id = tcx.local_def_id_to_hir_id(caller);
if let Some(generics) = tcx.hir().get(caller_hir_id).generics() {
if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() {
let constraint = with_no_trimmed_paths!(format!(
"~const {}",
trait_ref.print_only_trait_path()

View file

@ -81,6 +81,7 @@
/// E::A,
/// }
/// ```
#[cfg(bootstrap)]
#[macro_export]
macro_rules! impl_tag {
(
@ -140,5 +141,148 @@ macro_rules! impl_tag {
};
}
/// Implements [`Tag`] for a given type.
///
/// You can use `impl_tag` on structs and enums.
/// You need to specify the type and all its possible values,
/// which can only be paths with optional fields.
///
/// [`Tag`]: crate::tagged_ptr::Tag
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(macro_metavar_expr)]
/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag};
///
/// #[derive(Copy, Clone, PartialEq, Debug)]
/// enum SomeTag {
/// A,
/// B,
/// X { v: bool },
/// Y(bool, bool),
/// }
///
/// impl_tag! {
/// // The type for which the `Tag` will be implemented
/// impl Tag for SomeTag;
/// // You need to specify all possible tag values:
/// SomeTag::A, // 0
/// SomeTag::B, // 1
/// // For variants with fields, you need to specify the fields:
/// SomeTag::X { v: true }, // 2
/// SomeTag::X { v: false }, // 3
/// // For tuple variants use named syntax:
/// SomeTag::Y { 0: true, 1: true }, // 4
/// SomeTag::Y { 0: false, 1: true }, // 5
/// SomeTag::Y { 0: true, 1: false }, // 6
/// SomeTag::Y { 0: false, 1: false }, // 7
/// }
///
/// // Tag values are assigned in order:
/// assert_eq!(SomeTag::A.into_usize(), 0);
/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3);
/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5);
///
/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B);
/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true });
/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false));
/// ```
///
/// Structs are supported:
///
/// ```
/// #![feature(macro_metavar_expr)]
/// # use rustc_data_structures::impl_tag;
/// #[derive(Copy, Clone)]
/// struct Flags { a: bool, b: bool }
///
/// impl_tag! {
/// impl Tag for Flags;
/// Flags { a: true, b: true },
/// Flags { a: false, b: true },
/// Flags { a: true, b: false },
/// Flags { a: false, b: false },
/// }
/// ```
///
/// Not specifying all values results in a compile error:
///
/// ```compile_fail,E0004
/// #![feature(macro_metavar_expr)]
/// # use rustc_data_structures::impl_tag;
/// #[derive(Copy, Clone)]
/// enum E {
/// A,
/// B,
/// }
///
/// impl_tag! {
/// impl Tag for E;
/// E::A,
/// }
/// ```
#[cfg(not(bootstrap))]
#[macro_export]
macro_rules! impl_tag {
(
impl Tag for $Self:ty;
$(
$($path:ident)::* $( { $( $fields:tt )* })?,
)*
) => {
// Safety:
// `bits_for_tags` is called on the same `${index()}`-es as
// `into_usize` returns, thus `BITS` constant is correct.
unsafe impl $crate::tagged_ptr::Tag for $Self {
const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[
$(
${index()},
$( ${ignore($path)} )*
)*
]);
#[inline]
fn into_usize(self) -> usize {
// This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc)
// (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>)
#[forbid(unreachable_patterns)]
match self {
// `match` is doing heavy lifting here, by requiring exhaustiveness
$(
$($path)::* $( { $( $fields )* } )? => ${index()},
)*
}
}
#[inline]
unsafe fn from_usize(tag: usize) -> Self {
match tag {
$(
${index()} => $($path)::* $( { $( $fields )* } )?,
)*
// Safety:
// `into_usize` only returns `${index()}` of the same
// repetition as we are filtering above, thus if this is
// reached, the safety contract of this function was
// already breached.
_ => unsafe {
debug_assert!(
false,
"invalid tag: {tag}\
(this is a bug in the caller of `from_usize`)"
);
std::hint::unreachable_unchecked()
},
}
}
}
};
}
#[cfg(test)]
mod tests;

View file

@ -587,10 +587,8 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
let mut print_formatted = if pager_name == "less" {
cmd.arg("-r");
true
} else if ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name) {
true
} else {
false
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
};
if color == ColorConfig::Never {

View file

@ -41,6 +41,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::{iter, mem};
#[cfg(bootstrap)]
macro_rules! ast_fragments {
(
$($Kind:ident($AstTy:ty) {
@ -165,6 +166,131 @@ macro_rules! ast_fragments {
}
}
#[cfg(not(bootstrap))]
macro_rules! ast_fragments {
(
$($Kind:ident($AstTy:ty) {
$kind_name:expr;
$(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)?
$(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)?
fn $make_ast:ident;
})*
) => {
/// A fragment of AST that can be produced by a single macro expansion.
/// Can also serve as an input and intermediate result for macro expansion operations.
pub enum AstFragment {
OptExpr(Option<P<ast::Expr>>),
MethodReceiverExpr(P<ast::Expr>),
$($Kind($AstTy),)*
}
/// "Discriminant" of an AST fragment.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum AstFragmentKind {
OptExpr,
MethodReceiverExpr,
$($Kind,)*
}
impl AstFragmentKind {
pub fn name(self) -> &'static str {
match self {
AstFragmentKind::OptExpr => "expression",
AstFragmentKind::MethodReceiverExpr => "expression",
$(AstFragmentKind::$Kind => $kind_name,)*
}
}
fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
match self {
AstFragmentKind::OptExpr =>
result.make_expr().map(Some).map(AstFragment::OptExpr),
AstFragmentKind::MethodReceiverExpr =>
result.make_expr().map(AstFragment::MethodReceiverExpr),
$(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
}
}
}
impl AstFragment {
pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
if placeholders.is_empty() {
return;
}
match self {
$($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
${ignore($flat_map_ast_elt)}
placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
})),)?)*
_ => panic!("unexpected AST fragment kind")
}
}
pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
match self {
AstFragment::OptExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
}
pub fn make_method_receiver_expr(self) -> P<ast::Expr> {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
}
$(pub fn $make_ast(self) -> $AstTy {
match self {
AstFragment::$Kind(ast) => ast,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
})*
fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy {
T::fragment_to_output(self)
}
pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
match self {
AstFragment::OptExpr(opt_expr) => {
visit_clobber(opt_expr, |opt_expr| {
if let Some(expr) = opt_expr {
vis.filter_map_expr(expr)
} else {
None
}
});
}
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) =>
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
}
}
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
match self {
AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr),
AstFragment::OptExpr(None) => {}
AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] {
visitor.$visit_ast_elt(ast_elt, $($args)*);
})?)*
}
}
}
impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
$(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>)
-> Option<$AstTy> {
Some(self.make(AstFragmentKind::$Kind).$make_ast())
})*
}
}
}
ast_fragments! {
Expr(P<ast::Expr>) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; }
Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; }

View file

@ -10,9 +10,8 @@ use rustc_span::Span;
/// A meta-variable expression, for expansions based on properties of meta-variables.
#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
pub(crate) enum MetaVarExpr {
/// The number of repetitions of an identifier, optionally limited to a number
/// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
Count(Ident, Option<usize>),
/// The number of repetitions of an identifier.
Count(Ident, usize),
/// Ignore a meta-variable for repetition without expansion.
Ignore(Ident),
@ -43,7 +42,10 @@ impl MetaVarExpr {
let mut iter = args.trees();
let rslt = match ident.as_str() {
"count" => parse_count(&mut iter, sess, ident.span)?,
"ignore" => MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?),
"ignore" => {
eat_dollar(&mut iter, sess, ident.span)?;
MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?)
}
"index" => MetaVarExpr::Index(parse_depth(&mut iter, sess, ident.span)?),
"length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?),
_ => {
@ -92,6 +94,7 @@ fn parse_count<'sess>(
sess: &'sess ParseSess,
span: Span,
) -> PResult<'sess, MetaVarExpr> {
eat_dollar(iter, sess, span)?;
let ident = parse_ident(iter, sess, span)?;
let depth = if try_eat_comma(iter) {
if iter.look_ahead(0).is_none() {
@ -100,9 +103,9 @@ fn parse_count<'sess>(
"`count` followed by a comma must have an associated index indicating its depth",
));
}
Some(parse_depth(iter, sess, span)?)
parse_depth(iter, sess, span)?
} else {
None
0
};
Ok(MetaVarExpr::Count(ident, depth))
}
@ -166,3 +169,20 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
}
false
}
/// Expects that the next item is a dollar sign.
fn eat_dollar<'sess>(
iter: &mut RefTokenTreeCursor<'_>,
sess: &'sess ParseSess,
span: Span,
) -> PResult<'sess, ()> {
if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0)
{
let _ = iter.next();
return Ok(());
}
Err(sess.span_diagnostic.struct_span_err(
span,
"meta-variables within meta-variable expressions must be referenced using a dollar sign",
))
}

View file

@ -440,7 +440,7 @@ fn lockstep_iter_size(
/// declared inside a single repetition and the index `1` implies two nested repetitions.
fn count_repetitions<'a>(
cx: &ExtCtxt<'a>,
depth_opt: Option<usize>,
depth_user: usize,
mut matched: &NamedMatch,
repeats: &[(usize, usize)],
sp: &DelimSpan,
@ -449,37 +449,45 @@ fn count_repetitions<'a>(
// (or at the top-level of `matched` if no depth is given).
fn count<'a>(
cx: &ExtCtxt<'a>,
declared_lhs_depth: usize,
depth_opt: Option<usize>,
depth_curr: usize,
depth_max: usize,
matched: &NamedMatch,
sp: &DelimSpan,
) -> PResult<'a, usize> {
match matched {
MatchedTokenTree(_) | MatchedNonterminal(_) => {
if declared_lhs_depth == 0 {
return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
}
match depth_opt {
None => Ok(1),
Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
}
}
MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1),
MatchedSeq(named_matches) => {
let new_declared_lhs_depth = declared_lhs_depth + 1;
match depth_opt {
None => named_matches
if depth_curr == depth_max {
Ok(named_matches.len())
} else {
named_matches
.iter()
.map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp))
.sum(),
Some(0) => Ok(named_matches.len()),
Some(depth) => named_matches
.iter()
.map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp))
.sum(),
.map(|elem| count(cx, depth_curr + 1, depth_max, elem, sp))
.sum()
}
}
}
}
/// Maximum depth
fn depth(counter: usize, matched: &NamedMatch) -> usize {
match matched {
MatchedTokenTree(_) | MatchedNonterminal(_) => counter,
MatchedSeq(named_matches) => {
let rslt = counter + 1;
if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt }
}
}
}
let depth_max = depth(0, matched)
.checked_sub(1)
.and_then(|el| el.checked_sub(repeats.len()))
.unwrap_or_default();
if depth_user > depth_max {
return Err(out_of_bounds_err(cx, depth_max + 1, sp.entire(), "count"));
}
// `repeats` records all of the nested levels at which we are currently
// matching meta-variables. The meta-var-expr `count($x)` only counts
// matches that occur in this "subtree" of the `NamedMatch` where we
@ -491,7 +499,12 @@ fn count_repetitions<'a>(
matched = &ads[idx];
}
}
count(cx, 0, depth_opt, matched, sp)
if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched {
return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
}
count(cx, depth_user, depth_max, matched, sp)
}
/// Returns a `NamedMatch` item declared on the LHS given an arbitrary [Ident]
@ -523,7 +536,7 @@ fn out_of_bounds_err<'a>(
)
} else {
format!(
"depth parameter on meta-variable expression `{ty}` \
"depth parameter of meta-variable expression `{ty}` \
must be less than {max}"
)
};
@ -545,9 +558,9 @@ fn transcribe_metavar_expr<'a>(
span
};
match *expr {
MetaVarExpr::Count(original_ident, depth_opt) => {
MetaVarExpr::Count(original_ident, depth) => {
let matched = matched_from_ident(cx, original_ident, interp)?;
let count = count_repetitions(cx, depth_opt, matched, repeats, sp)?;
let count = count_repetitions(cx, depth, matched, repeats, sp)?;
let tt = TokenTree::token_alone(
TokenKind::lit(token::Integer, sym::integer(count), None),
visited_span(),

View file

@ -24,7 +24,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
..
}),
..
}) = tcx.hir().get_by_def_id(parent_id)
}) = tcx.hir_node_by_def_id(parent_id)
&& self_ty.hir_id == impl_self_ty.hir_id
{
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {

View file

@ -2715,7 +2715,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let hir = tcx.hir();
let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
hir.get(fn_hir_id)
tcx.hir_node(fn_hir_id)
else {
return None;
};

View file

@ -479,7 +479,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
match assoc_item.kind {
ty::AssocKind::Fn => {
let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
@ -504,7 +504,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
// Skip opaques from RPIT in traits with no default body.
@ -1173,7 +1173,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
ty::VariantDiscr::Explicit(discr_def_id) => {
// In the case the discriminant is both a duplicate and overflowed, let the user know
if let hir::Node::AnonConst(expr) =
tcx.hir().get_by_def_id(discr_def_id.expect_local())
tcx.hir_node_by_def_id(discr_def_id.expect_local())
&& let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
&& let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
&& *lit_value != dis.val

View file

@ -2181,7 +2181,7 @@ pub(super) fn check_type_bounds<'tcx>(
let impl_ty_span = if impl_ty.is_impl_trait_in_trait() {
tcx.def_span(impl_ty_def_id)
} else {
match tcx.hir().get_by_def_id(impl_ty_def_id) {
match tcx.hir_node_by_def_id(impl_ty_def_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(_, Some(ty)),
..

View file

@ -278,7 +278,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
}
let (span, impl_return_span, pre, post) =
match tcx.hir().get_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
match tcx.hir_node_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
hir::FnRetTy::DefaultReturn(span) => (tcx.def_span(impl_m_def_id), span, "-> ", " "),
hir::FnRetTy::Return(ty) => (ty.span, ty.span, "", ""),
};

View file

@ -43,7 +43,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
generics.params.is_empty().not().then_some(generics.span)
}
@ -58,7 +58,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
Some(generics.where_clause_span)
}
@ -80,7 +80,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
Some(fn_sig.decl.output.span())
}
@ -199,7 +199,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {

View file

@ -130,7 +130,7 @@ fn get_owner_return_paths(
) -> Option<(LocalDefId, ReturnsVisitor<'_>)> {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let parent_id = tcx.hir().get_parent_item(hir_id).def_id;
tcx.hir().find_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
let body = tcx.hir().body(body_id);
let mut visitor = ReturnsVisitor::default();
visitor.visit_body(body);
@ -141,7 +141,7 @@ fn get_owner_return_paths(
/// Forbid defining intrinsics in Rust code,
/// as they must always be defined by the compiler.
// FIXME: Move this to a more appropriate place.
pub fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
}

View file

@ -793,7 +793,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
/// When this is done, suggest using `Self` instead.
fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
let (trait_name, trait_def_id) =
match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
_ => return,
@ -1019,7 +1019,7 @@ fn check_type_defn<'tcx>(
for field in &variant.fields {
let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field();
tcx.hir_node_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(
hir_ty.span,
None,
@ -1057,7 +1057,7 @@ fn check_type_defn<'tcx>(
let last = idx == variant.fields.len() - 1;
let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } =
tcx.hir().get_by_def_id(field_id).expect_field();
tcx.hir_node_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(
hir_ty.span,
None,
@ -1882,7 +1882,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// Match the existing behavior.
if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
let pred = self.normalize(span, None, pred);
let hir_node = tcx.hir().find_by_def_id(self.body_def_id);
let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id);
// only use the span of the predicate clause (#90869)

View file

@ -221,7 +221,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
// Check if parent is const or static
let parent_id = tcx.hir().parent_id(hir_ty.hir_id);
let parent_node = tcx.hir().get(parent_id);
let parent_node = tcx.hir_node(parent_id);
is_const_or_static = matches!(
parent_node,
@ -354,7 +354,7 @@ impl<'tcx> ItemCtxt<'tcx> {
}
pub fn node(&self) -> hir::Node<'tcx> {
self.tcx.hir().get(self.hir_id())
self.tcx.hir_node(self.hir_id())
}
}
@ -835,8 +835,7 @@ fn convert_variant(
fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
use rustc_hir::*;
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let Node::Item(item) = tcx.hir().get(hir_id) else {
let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
bug!();
};
@ -1105,7 +1104,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
let icx = ItemCtxt::new(tcx, def_id);
let output = match tcx.hir().get(hir_id) {
let output = match tcx.hir_node(hir_id) {
TraitItem(hir::TraitItem {
kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
generics,
@ -1551,7 +1550,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
}
fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
match tcx.hir().get_by_def_id(def_id) {
match tcx.hir_node_by_def_id(def_id) {
Node::Expr(&rustc_hir::Expr {
kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
..
@ -1561,7 +1560,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK
}
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
match tcx.hir().get_by_def_id(def_id) {
match tcx.hir_node_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
}

View file

@ -16,7 +16,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(hir_id);
let node = tcx.hir_node(hir_id);
let parent_def_id = match node {
Node::ImplItem(_)
| Node::TraitItem(_)

View file

@ -34,17 +34,14 @@ fn associated_type_bounds<'tcx>(
let trait_def_id = tcx.local_parent(assoc_item_def_id);
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
let bounds_from_parent = trait_predicates
.predicates
.iter()
.copied()
.filter(|(pred, _)| match pred.kind().skip_binder() {
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
match pred.kind().skip_binder() {
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
_ => false,
})
.map(|(clause, span)| (clause, span));
}
});
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
debug!(
@ -86,7 +83,7 @@ pub(super) fn explicit_item_bounds(
// RPITIT's bounds are the same as opaque type bounds, but with
// a projection self type.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
let opaque_ty = item.expect_opaque_ty();
return ty::EarlyBinder::bind(opaque_type_bounds(
tcx,
@ -105,8 +102,7 @@ pub(super) fn explicit_item_bounds(
None => {}
}
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let bounds = match tcx.hir().get(hir_id) {
let bounds = match tcx.hir_node_by_def_id(def_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(bounds, _),
span,

View file

@ -135,7 +135,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(hir_id);
let node = tcx.hir_node(hir_id);
let mut is_trait = None;
let mut is_default_impl_trait = None;
@ -337,7 +337,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// and the duplicated parameter, to ensure that they do not get out of sync.
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
let opaque_ty_id = tcx.hir().parent_id(hir_id);
let opaque_ty_node = tcx.hir().get(opaque_ty_id);
let opaque_ty_node = tcx.hir_node(opaque_ty_id);
let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
bug!("unexpected {opaque_ty_node:?}")
};
@ -413,7 +413,7 @@ fn const_evaluatable_predicates_of(
}
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(hir_id);
let node = tcx.hir_node(hir_id);
let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
if let hir::Node::Item(item) = node
@ -633,7 +633,7 @@ pub(super) fn implied_predicates_with_filter(
let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id);
let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
let Node::Item(item) = tcx.hir_node(trait_hir_id) else {
bug!("trait_node_id {} is not an item", trait_hir_id);
};
@ -713,7 +713,7 @@ pub(super) fn type_param_predicates(
let mut extend = None;
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
let ast_generics = match tcx.hir().get(item_hir_id) {
let ast_generics = match tcx.hir_node(item_hir_id) {
Node::TraitItem(item) => item.generics,
Node::ImplItem(item) => item.generics,

View file

@ -748,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy { .. }, ..
}) = self.tcx.hir().get(parent_id)
}) = self.tcx.hir_node(parent_id)
{
let mut err = self.tcx.sess.struct_span_err(
lifetime.ident.span,
@ -1004,7 +1004,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault {
debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(param_def_id) else {
let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(param_def_id) else {
bug!("expected GenericParam for object_lifetime_default");
};
match param.source {
@ -1305,7 +1305,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
def = ResolvedArg::Error(guar);
} else if let Some(body_id) = outermost_body {
let fn_id = self.tcx.hir().body_owner(body_id);
match self.tcx.hir().get(fn_id) {
match self.tcx.hir_node(fn_id) {
Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn(..), .. })
| Node::TraitItem(hir::TraitItem {
owner_id,
@ -2122,7 +2122,7 @@ pub fn deny_non_region_late_bound(
let mut first = true;
for (var, arg) in bound_vars {
let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else {
let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else {
bug!();
};

View file

@ -20,10 +20,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
use rustc_middle::ty::Ty;
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
let Node::AnonConst(_) = tcx.hir_node(hir_id) else { panic!() };
let parent_node_id = tcx.hir().parent_id(hir_id);
let parent_node = tcx.hir().get(parent_node_id);
let parent_node = tcx.hir_node(parent_node_id);
let (generics, arg_idx) = match parent_node {
// Easy case: arrays repeat expressions.
@ -61,7 +61,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
}
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) =>
if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
return Ty::new_error_with_message(
@ -354,7 +354,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
let icx = ItemCtxt::new(tcx, def_id);
let output = match tcx.hir().get(hir_id) {
let output = match tcx.hir_node(hir_id) {
Node::TraitItem(item) => match item.kind {
TraitItemKind::Fn(..) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@ -517,8 +517,7 @@ pub(super) fn type_of_opaque(
if let Some(def_id) = def_id.as_local() {
use rustc_hir::*;
let hir_id = tcx.local_def_id_to_hir_id(def_id);
Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) {
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { .. },

View file

@ -50,8 +50,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
if scope == hir::CRATE_HIR_ID {
tcx.hir().walk_toplevel_module(&mut locator);
} else {
trace!("scope={:#?}", tcx.hir().get(scope));
match tcx.hir().get(scope) {
trace!("scope={:#?}", tcx.hir_node(scope));
match tcx.hir_node(scope) {
// We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
// This allows our visitor to process the defining item itself, causing
// it to pick up any 'sibling' defining uses.
@ -95,7 +95,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
span: tcx.def_span(def_id),
name: tcx.item_name(parent_def_id.to_def_id()),
what: match tcx.hir().get(scope) {
what: match tcx.hir_node(scope) {
_ if scope == hir::CRATE_HIR_ID => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
@ -282,7 +282,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
debug!(?scope);
let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
match tcx.hir().get(scope) {
match tcx.hir_node(scope) {
Node::Item(it) => intravisit::walk_item(&mut locator, it),
Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it),
Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),

View file

@ -122,7 +122,7 @@ fn diagnostic_hir_wf_check<'tcx>(
// We will walk 'into' this type to try to find
// a more precise span for our predicate.
let tys = match loc {
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
WellFormedLoc::Ty(_) => match tcx.hir_node(hir_id) {
hir::Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Type(ty) => vec![ty],
hir::ImplItemKind::Const(ty, _) => vec![ty],

View file

@ -41,7 +41,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
}
}
match tcx.hir().get(id) {
match tcx.hir_node(id) {
Node::Item(item) => match item.kind {
hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
let crate_map = tcx.inferred_outlives_crate(());

View file

@ -137,10 +137,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
// is from the 'of_trait' field of the enclosing impl
let parent = self.tcx.hir().get_parent(self.path_segment.hir_id);
let parent_item = self
.tcx
.hir()
.get_by_def_id(self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id);
let parent_item = self.tcx.hir_node_by_def_id(
self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id,
);
// Get the HIR id of the trait ref
let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
@ -774,7 +773,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
);
if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
&& let Some(parent_node) = self.tcx.opt_hir_node(parent_node)
&& let hir::Node::Expr(expr) = parent_node
{
match &expr.kind {

View file

@ -238,8 +238,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
// Next, make sure that we have no type expectation.
let Some(ret) = hir
.find_by_def_id(self.body_id)
let Some(ret) = self
.tcx
.opt_hir_node_by_def_id(self.body_id)
.and_then(|owner| owner.fn_decl())
.map(|decl| decl.output.span())
else {
@ -317,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir_id: hir::HirId,
sp: Span,
) -> Option<(Span, String)> {
let node = self.tcx.hir().get(hir_id);
let node = self.tcx.hir_node(hir_id);
if let hir::Node::Block(block) = node {
// check that the body's parent is an fn
let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));

View file

@ -295,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) {
let hir = self.tcx.hir();
let parent_hir_id = hir.parent_id(hir_id);
let parent_node = hir.get(parent_hir_id);
let parent_node = self.tcx.hir_node(parent_hir_id);
if let (
hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, body, .. }),
@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
..
}) = hir.get(async_closure)
}) = self.tcx.hir_node(async_closure)
{
fn_decl_span
} else {
@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
callee_expr: &'tcx hir::Expr<'tcx>,
) -> bool {
let hir_id = self.tcx.hir().parent_id(call_expr.hir_id);
let parent_node = self.tcx.hir().get(hir_id);
let parent_node = self.tcx.hir_node(hir_id);
if let (
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }),
hir::ExprKind::Tup(exp),

View file

@ -8,7 +8,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir_analysis::check::{check_function_signature, fn_maybe_err};
use rustc_hir_analysis::check::{check_function_signature, forbid_intrinsic_abi};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::RegionVariableOrigin;
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
@ -53,7 +53,7 @@ pub(super) fn check_fn<'a, 'tcx>(
let span = body.value.span;
fn_maybe_err(tcx, span, fn_sig.abi);
forbid_intrinsic_abi(tcx, span, fn_sig.abi);
if let Some(kind) = body.coroutine_kind
&& can_be_coroutine.is_some()

View file

@ -483,8 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
body: &hir::Body<'_>,
expected_sig: ExpectedSig<'tcx>,
) -> ClosureSignatures<'tcx> {
let hir = self.tcx.hir();
let expr_map_node = hir.get_by_def_id(expr_def_id);
let expr_map_node = self.tcx.hir_node_by_def_id(expr_def_id);
let expected_args: Vec<_> = expected_sig
.sig
.skip_binder()

View file

@ -1694,14 +1694,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let ret_msg = "return a value for the case when the loop has zero elements to iterate on";
let ret_ty_msg =
"otherwise consider changing the return type to account for that possibility";
if let Some(node) = hir.find(item.into())
if let Some(node) = tcx.opt_hir_node(item.into())
&& let Some(body_id) = node.body_id()
&& let Some(sig) = node.fn_sig()
&& let hir::ExprKind::Block(block, _) = hir.body(body_id).value.kind
&& !ty.is_never()
{
let indentation = if let None = block.expr
&& let [.., last] = &block.stmts[..]
&& let [.., last] = &block.stmts
{
tcx.sess.source_map().indentation_before(last.span).unwrap_or_else(String::new)
} else if let Some(expr) = block.expr {
@ -1710,7 +1710,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
String::new()
};
if let None = block.expr
&& let [.., last] = &block.stmts[..]
&& let [.., last] = &block.stmts
{
err.span_suggestion_verbose(
last.span.shrink_to_hi(),
@ -1750,7 +1750,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
}
if let None = block.expr
&& let [.., last] = &block.stmts[..]
&& let [.., last] = &block.stmts
{
sugg.push((last.span.shrink_to_hi(), format!("\n{indentation}None")));
} else if let Some(expr) = block.expr {
@ -1776,7 +1776,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
let parent_id = fcx.tcx.hir().parent_id(id);
let parent = fcx.tcx.hir().get(parent_id);
let parent = fcx.tcx.hir_node(parent_id);
if let Some(expr) = expression
&& let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { body, .. }),
@ -1835,7 +1835,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
let parent_id = fcx.tcx.hir().get_parent_item(id);
let parent_item = fcx.tcx.hir().get_by_def_id(parent_id.def_id);
let parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) =
(expression, blk_id, fcx.get_node_fn_decl(parent_item))

View file

@ -289,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::def::Res::Local(local_hir_id) = p.res else {
return false;
};
let hir::Node::Pat(pat) = hir.get(local_hir_id) else {
let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else {
return false;
};
let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) {
@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
| hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
| hir::Node::Expr(&ref p),
) = self.tcx.hir().find(parent_id)
) = self.tcx.opt_hir_node(parent_id)
else {
break;
};
@ -570,7 +570,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut direct = false;
loop {
// Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
let parent = match self.tcx.hir().find(parent_id) {
let parent = match self.tcx.opt_hir_node(parent_id) {
Some(hir::Node::Expr(&ref parent)) => {
parent_id = self.tcx.hir().parent_id(parent.hir_id);
parent
@ -672,7 +672,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error: Option<TypeError<'tcx>>,
) {
let parent = self.tcx.hir().parent_id(expr.hir_id);
match (self.tcx.hir().find(parent), error) {
match (self.tcx.opt_hir_node(parent), error) {
(Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _)
if init.hir_id == expr.hir_id =>
{
@ -717,7 +717,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) => {
if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) {
if let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) {
primary_span = pat.span;
secondary_span = pat.span;
match self.tcx.hir().find_parent(pat.hir_id) {
@ -790,7 +790,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
};
let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })) =
self.tcx.hir().find(parent)
self.tcx.opt_hir_node(parent)
else {
return;
};
@ -862,7 +862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
mutability,
),
),
match &args[..] {
match &args {
[] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()),
[first, ..] => (base.span.between(first.span), ", ".to_string()),
},
@ -1014,8 +1014,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
)) = expr.kind
{
let bind = self.tcx.hir().find(*bind_hir_id);
let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id));
let bind = self.tcx.opt_hir_node(*bind_hir_id);
let parent = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*bind_hir_id));
if let Some(hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Binding(_, _hir_id, _, _),
..

View file

@ -883,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: hir::ImplItemKind::Fn(..),
span: encl_fn_span,
..
})) = self.tcx.hir().find_by_def_id(encl_item_id.def_id)
})) = self.tcx.opt_hir_node_by_def_id(encl_item_id.def_id)
{
// We are inside a function body, so reporting "return statement
// outside of function body" needs an explanation.
@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
then: impl FnOnce(&hir::Expr<'_>),
) {
let mut parent = self.tcx.hir().parent_id(original_expr_id);
while let Some(node) = self.tcx.hir().find(parent) {
while let Some(node) = self.tcx.opt_hir_node(parent) {
match node {
hir::Node::Expr(hir::Expr {
kind:

View file

@ -24,9 +24,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
self.fulfillment_cx.borrow_mut().pending_obligations()
);
let fallback_occured = self.fallback_types() | self.fallback_effects();
let fallback_occurred = self.fallback_types() | self.fallback_effects();
if !fallback_occured {
if !fallback_occurred {
return;
}
@ -57,24 +57,25 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
}
fn fallback_types(&self) -> bool {
// Check if we have any unsolved variables. If not, no need for fallback.
let unsolved_variables = self.unsolved_variables();
// Check if we have any unresolved variables. If not, no need for fallback.
let unresolved_variables = self.unresolved_variables();
if unsolved_variables.is_empty() {
if unresolved_variables.is_empty() {
return false;
}
let diverging_fallback = self.calculate_diverging_fallback(&unsolved_variables);
let diverging_fallback = self.calculate_diverging_fallback(&unresolved_variables);
// We do fallback in two passes, to try to generate
// better error messages.
// The first time, we do *not* replace opaque types.
for ty in unsolved_variables {
let mut fallback_occurred = false;
for ty in unresolved_variables {
debug!("unsolved_variable = {:?}", ty);
self.fallback_if_possible(ty, &diverging_fallback);
fallback_occurred |= self.fallback_if_possible(ty, &diverging_fallback);
}
true
fallback_occurred
}
fn fallback_effects(&self) -> bool {
@ -84,9 +85,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
return false;
}
// not setting `fallback_has_occured` here because that field is only used for type fallback
// diagnostics.
// not setting the `fallback_has_occured` field here because
// that field is only used for type fallback diagnostics.
for effect in unsolved_effects {
let expected = self.tcx.consts.true_;
let cause = self.misc(rustc_span::DUMMY_SP);
@ -122,7 +122,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
&self,
ty: Ty<'tcx>,
diverging_fallback: &UnordMap<Ty<'tcx>, Ty<'tcx>>,
) {
) -> bool {
// Careful: we do NOT shallow-resolve `ty`. We know that `ty`
// is an unsolved variable, and we determine its fallback
// based solely on how it was created, not what other type
@ -147,7 +147,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
_ => match diverging_fallback.get(&ty) {
Some(&fallback_ty) => fallback_ty,
None => return,
None => return false,
},
};
debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback);
@ -159,6 +159,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
.unwrap_or(rustc_span::DUMMY_SP);
self.demand_eqtype(span, ty, fallback);
self.fallback_has_occurred.set(true);
true
}
/// The "diverging fallback" system is rather complicated. This is
@ -230,9 +231,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
/// any variable that has an edge into `D`.
fn calculate_diverging_fallback(
&self,
unsolved_variables: &[Ty<'tcx>],
unresolved_variables: &[Ty<'tcx>],
) -> UnordMap<Ty<'tcx>, Ty<'tcx>> {
debug!("calculate_diverging_fallback({:?})", unsolved_variables);
debug!("calculate_diverging_fallback({:?})", unresolved_variables);
// Construct a coercion graph where an edge `A -> B` indicates
// a type variable is that is coerced
@ -240,7 +241,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
// Extract the unsolved type inference variable vids; note that some
// unsolved variables are integer/float variables and are excluded.
let unsolved_vids = unsolved_variables.iter().filter_map(|ty| ty.ty_vid());
let unsolved_vids = unresolved_variables.iter().filter_map(|ty| ty.ty_vid());
// Compute the diverging root vids D -- that is, the root vid of
// those type variables that (a) are the target of a coercion from

View file

@ -994,7 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
// `while` before reaching it, as block tail returns are not available in them.
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
let parent = self.tcx.hir().get(blk_id);
let parent = self.tcx.hir_node(blk_id);
self.get_node_fn_decl(parent)
.map(|(fn_id, fn_decl, _, is_main)| (fn_id, fn_decl, is_main))
})

View file

@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
let hir = self.tcx.hir();
let (expr, qpath) = match hir.get(hir_id) {
let (expr, qpath) = match self.tcx.hir_node(hir_id) {
hir::Node::Expr(expr) => {
if self.closure_span_overlaps_error(error, expr.span) {
return false;
@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
.unwrap_or(arg.span);
if let hir::Node::Expr(arg_expr) = self.tcx.hir().get(arg.hir_id) {
if let hir::Node::Expr(arg_expr) = self.tcx.hir_node(arg.hir_id) {
// This is more specific than pointing at the entire argument.
self.blame_specific_expr_if_possible(error, arg_expr)
}

View file

@ -1734,7 +1734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id).def_id);
let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id);
match node {
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
@ -1750,7 +1750,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident))
}
@ -2084,7 +2084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let node = self
.tcx
.opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
.and_then(|hir_id| self.tcx.hir().find(hir_id));
.and_then(|hir_id| self.tcx.opt_hir_node(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),

View file

@ -677,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// can suggest Box::pin.
let parent = self.tcx.hir().parent_id(expr.hir_id);
let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) =
self.tcx.hir().find(parent)
self.tcx.opt_hir_node(parent)
else {
return false;
};
@ -824,7 +824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty), ..
}) = self.tcx.hir().get(item_id.hir_id())
}) = self.tcx.hir_node(item_id.hir_id())
&& let [
hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args),
] = op_ty.bounds
@ -902,7 +902,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty::Param(expected_ty_as_param) = expected.kind() else { return };
let fn_node = self.tcx.hir().find(fn_id);
let fn_node = self.tcx.opt_hir_node(fn_id);
let Some(hir::Node::Item(hir::Item {
kind:
@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let ty = self.normalize(expr.span, ty);
if self.can_coerce(found, ty) {
if let Some(node) = self.tcx.hir().find(fn_id)
if let Some(node) = self.tcx.opt_hir_node(fn_id)
&& let Some(owner_node) = node.as_owner()
&& let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
{
@ -1545,12 +1545,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
fn is_loop(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
let node = self.tcx.hir_node(id);
matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))
}
fn is_local_statement(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
let node = self.tcx.hir_node(id);
matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. }))
}
@ -1677,11 +1677,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
hir::Path { segments: [_], res: crate::Res::Local(binding), .. },
)) => {
let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.hir().find(*binding)
let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.opt_hir_node(*binding)
else {
return expr;
};
let Some(parent) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id)) else {
let Some(parent) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) else {
return expr;
};
@ -1697,7 +1697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
..
}) => {
let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) =
self.tcx.hir().find(self.tcx.hir().parent_id(*pat_hir_id))
self.tcx.opt_hir_node(self.tcx.hir().parent_id(*pat_hir_id))
else {
return expr;
};
@ -1730,8 +1730,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
call_expr_path
&& let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) =
self.tcx.hir().find(*binding)
&& let Some(closure) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id))
self.tcx.opt_hir_node(*binding)
&& let Some(closure) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id))
&& let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure
&& let Expr {
kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
@ -1985,7 +1985,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(hir::Node::Block(&hir::Block {
span: block_span, expr: Some(e), ..
})) = self.tcx.hir().find(parent)
})) = self.tcx.opt_hir_node(parent)
{
if e.hir_id == id {
if let Some(span) = expr.span.find_ancestor_inside(block_span) {
@ -2211,7 +2211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let local_parent = self.tcx.hir().parent_id(local_id);
let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) =
self.tcx.hir().find(local_parent)
self.tcx.opt_hir_node(local_parent)
else {
return None;
};
@ -2221,13 +2221,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir_id: expr_hir_id,
kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
..
})) = self.tcx.hir().find(param_parent)
})) = self.tcx.opt_hir_node(param_parent)
else {
return None;
};
let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
let hir = self.tcx.hir().find(expr_parent);
let hir = self.tcx.opt_hir_node(expr_parent);
let closure_params_len = closure_fn_decl.inputs.len();
let (
Some(Node::Expr(hir::Expr {
@ -2667,7 +2667,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::If(_, _, Some(else_expr)),
..
})) = self.tcx.hir().find(parent_id)
})) = self.tcx.opt_hir_node(parent_id)
{
return else_expr.hir_id == expr.hir_id;
}
@ -3057,7 +3057,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
};
let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(hir::Node::ExprField(_)) = self.tcx.hir().find(parent) {
if let Some(hir::Node::ExprField(_)) = self.tcx.opt_hir_node(parent) {
// Ignore `Foo { field: a..Default::default() }`
return;
}
@ -3136,7 +3136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::def::Res::Local(hir_id) = path.res else {
return;
};
let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else {
let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
return;
};
let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =

View file

@ -127,7 +127,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
if let Some(def_id) = def_id.as_local() {
primary_body_of(tcx.hir().get_by_def_id(def_id)).is_some()
primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some()
} else {
false
}
@ -166,7 +166,7 @@ fn typeck_with_fallback<'tcx>(
}
let id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(id);
let node = tcx.hir_node(id);
let span = tcx.hir().span(id);
// Figure out what primary body this item has.
@ -201,7 +201,7 @@ fn typeck_with_fallback<'tcx>(
span,
}))
} else if let Node::AnonConst(_) = node {
match tcx.hir().get(tcx.hir().parent_id(id)) {
match tcx.hir_node(tcx.hir().parent_id(id)) {
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
if anon_const.hir_id == id =>
{
@ -283,8 +283,6 @@ fn typeck_with_fallback<'tcx>(
fcx.check_asms();
fcx.infcx.skip_region_resolution();
let typeck_results = fcx.resolve_type_vars_in_body(body);
// Consistency check our TypeckResults instance can hold all ItemLocalIds

View file

@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
&& let hir::def::Res::Local(hir_id) = path.res
&& let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id)
&& let Some(hir::Node::Pat(b)) = self.tcx.opt_hir_node(hir_id)
&& let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
&& let Some(node) = self.tcx.hir().find_parent(p.hir_id)
&& let Some(decl) = node.fn_decl()
@ -262,7 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
rcvr_expr: &hir::Expr<'tcx>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
let mut file = None;
let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
let mut err = struct_span_err!(
self.tcx.sess,
rcvr_expr.span,
@ -280,6 +281,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"a writer is needed before this format string",
);
};
if let Some(file) = file {
err.note(format!("the full type name has been written to '{}'", file.display()));
}
err
}
@ -299,11 +303,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mode = no_match_data.mode;
let tcx = self.tcx;
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
let ((mut ty_str, ty_file), short_ty_str) =
let mut ty_file = None;
let (mut ty_str, short_ty_str) =
if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string()))
(predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
} else {
(tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string()))
(
tcx.short_ty_string(rcvr_ty, &mut ty_file),
with_forced_trimmed_paths!(rcvr_ty.to_string()),
)
};
let is_method = mode == Mode::MethodCall;
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
@ -605,16 +613,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let (ty::Param(_), ty::PredicateKind::Clause(ty::ClauseKind::Trait(p))) =
(self_ty.kind(), parent_pred.kind().skip_binder())
{
let hir = self.tcx.hir();
let node = match p.trait_ref.self_ty().kind() {
ty::Param(_) => {
// Account for `fn` items like in `issue-35677.rs` to
// suggest restricting its type params.
Some(hir.get_by_def_id(self.body_id))
}
ty::Adt(def, _) => {
def.did().as_local().map(|def_id| hir.get_by_def_id(def_id))
Some(self.tcx.hir_node_by_def_id(self.body_id))
}
ty::Adt(def, _) => def
.did()
.as_local()
.map(|def_id| self.tcx.hir_node_by_def_id(def_id)),
_ => None,
};
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node
@ -1952,7 +1960,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
visitor.visit_body(body);
let parent = self.tcx.hir().parent_id(seg1.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
&& let Some(expr) = visitor.result
&& let Some(self_ty) = self.node_ty_opt(expr.hir_id)
{
@ -2869,11 +2877,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let id = item
.def_id
.as_local()
.map(|def_id| self.tcx.local_def_id_to_hir_id(def_id));
.map(|def_id| self.tcx.hir_node_by_def_id(def_id));
if let Some(hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(fn_sig, method),
..
})) = id.map(|id| self.tcx.hir().get(id))
})) = id
{
let self_first_arg = match method {
hir::TraitFn::Required([ident, ..]) => {
@ -2963,7 +2971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: FooBar`,
// instead we suggest `T: Foo + Bar` in that case.
match hir.get(id) {
match self.tcx.hir_node(id) {
Node::GenericParam(param) => {
enum Introducer {
Plus,
@ -3183,7 +3191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
&& let hir::ExprKind::MethodCall(
hir::PathSegment { ident: method_name, .. },
self_expr,

View file

@ -720,7 +720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let PatKind::Binding(_, _, binding, ..) = inner.kind
{
let binding_parent_id = tcx.hir().parent_id(pat.hir_id);
let binding_parent = tcx.hir().get(binding_parent_id);
let binding_parent = tcx.hir_node(binding_parent_id);
debug!(?inner, ?pat, ?binding_parent);
let mutability = match mutbl {
@ -941,7 +941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Const(_, _, body_id),
..
})) => match self.tcx.hir().get(body_id.hir_id) {
})) => match self.tcx.hir_node(body_id.hir_id) {
hir::Node::Expr(expr) => {
if hir::is_range_literal(expr) {
let span = self.tcx.hir().span(body_id.hir_id);

View file

@ -69,12 +69,13 @@ pub fn resolve_rvalue_scopes<'a, 'tcx>(
def_id: DefId,
) -> RvalueScopes {
let tcx = &fcx.tcx;
let hir_map = tcx.hir();
let mut rvalue_scopes = RvalueScopes::new();
debug!("start resolving rvalue scopes, def_id={def_id:?}");
debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
let Some(Node::Expr(expr)) = hir_map.find(hir_id) else { bug!("hir node does not exist") };
let Some(Node::Expr(expr)) = tcx.opt_hir_node(hir_id) else {
bug!("hir node does not exist")
};
record_rvalue_scope(&mut rvalue_scopes, expr, candidate);
}
rvalue_scopes

View file

@ -315,11 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let final_tupled_upvars_type = Ty::new_tup(self.tcx, &final_upvar_tys);
self.demand_suptype(span, args.tupled_upvars_ty(), final_tupled_upvars_type);
let fake_reads = delegate
.fake_reads
.into_iter()
.map(|(place, cause, hir_id)| (place, cause, hir_id))
.collect();
let fake_reads = delegate.fake_reads;
self.typeck_results.borrow_mut().closure_fake_reads.insert(closure_def_id, fake_reads);
if self.tcx.sess.opts.unstable_opts.profile_closures {
@ -853,7 +850,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Looks like a macro fragment. Try to find the real block.
if let Some(hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::Block(block, ..), ..
})) = self.tcx.hir().find(body_id.hir_id) {
})) = self.tcx.opt_hir_node(body_id.hir_id) {
// If the body is a block (with `{..}`), we use the span of that block.
// E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
// Since we know it's a block, we know we can insert the `let _ = ..` without
@ -1673,7 +1670,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
fn drop_location_span(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> Span {
let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap();
let owner_node = tcx.hir().get(owner_id);
let owner_node = tcx.hir_node(owner_id);
let owner_span = match owner_node {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Fn(_, _, owner_id) => tcx.hir().span(owner_id.hir_id),

View file

@ -8,12 +8,16 @@ use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::TypeSuperFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::solve;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use std::mem;
@ -695,24 +699,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
}
}
fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T
fn resolve<T>(&mut self, value: T, span: &dyn Locatable) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
let mut resolver = Resolver::new(self.fcx, span, self.body);
let x = x.fold_with(&mut resolver);
if cfg!(debug_assertions) && x.has_infer() {
span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
}
let value = self.fcx.resolve_vars_if_possible(value);
let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body));
assert!(!value.has_infer());
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
// to mark the `TypeckResults` as tainted in that case, so that downstream
// users of the typeck results don't produce extra errors, or worse, ICEs.
if let Some(e) = resolver.replaced_with_error {
self.typeck_results.tainted_by_errors = Some(e);
if let Err(guar) = value.error_reported() {
self.typeck_results.tainted_by_errors = Some(guar);
}
x
value
}
}
@ -732,15 +734,13 @@ impl Locatable for hir::HirId {
}
}
/// The Resolver. This is the type folding engine that detects
/// unresolved types and so forth.
struct Resolver<'cx, 'tcx> {
fcx: &'cx FnCtxt<'cx, 'tcx>,
span: &'cx dyn Locatable,
body: &'tcx hir::Body<'tcx>,
/// Set to `Some` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
replaced_with_error: Option<ErrorGuaranteed>,
/// Whether we should normalize using the new solver, disabled
/// both when using the old solver and when resolving predicates.
should_normalize: bool,
}
impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
@ -749,7 +749,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
span: &'cx dyn Locatable,
body: &'tcx hir::Body<'tcx>,
) -> Resolver<'cx, 'tcx> {
Resolver { fcx, span, body, replaced_with_error: None }
Resolver { fcx, span, body, should_normalize: fcx.next_trait_solver() }
}
fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
@ -768,6 +768,42 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
.emit(),
}
}
fn handle_term<T>(
&mut self,
value: T,
outer_exclusive_binder: impl FnOnce(T) -> ty::DebruijnIndex,
new_err: impl Fn(TyCtxt<'tcx>, ErrorGuaranteed) -> T,
) -> T
where
T: Into<ty::GenericArg<'tcx>> + TypeSuperFoldable<TyCtxt<'tcx>> + Copy,
{
let tcx = self.fcx.tcx;
// We must deeply normalize in the new solver, since later lints
// expect that types that show up in the typeck are fully
// normalized.
let value = if self.should_normalize {
let body_id = tcx.hir().body_owner_def_id(self.body.id());
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
let at = self.fcx.at(&cause, self.fcx.param_env);
let universes = vec![None; outer_exclusive_binder(value).as_usize()];
solve::deeply_normalize_with_skipped_universes(at, value, universes).unwrap_or_else(
|errors| {
let guar = self.fcx.err_ctxt().report_fulfillment_errors(errors);
new_err(tcx, guar)
},
)
} else {
value
};
if value.has_non_region_infer() {
let guar = self.report_error(value);
new_err(tcx, guar)
} else {
tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
}
}
}
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
@ -775,57 +811,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
self.fcx.tcx
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
let tcx = self.fcx.tcx;
match self.fcx.fully_resolve(t) {
Ok(t) if self.fcx.next_trait_solver() => {
// We must normalize erasing regions here, since later lints
// expect that types that show up in the typeck are fully
// normalized.
if let Ok(t) = tcx.try_normalize_erasing_regions(self.fcx.param_env, t) {
t
} else {
tcx.fold_regions(t, |_, _| tcx.lifetimes.re_erased)
}
}
Ok(t) => {
// Do not anonymize late-bound regions
// (e.g. keep `for<'a>` named `for<'a>`).
// This allows NLL to generate error messages that
// refer to the higher-ranked lifetime names written by the user.
tcx.fold_regions(t, |_, _| tcx.lifetimes.re_erased)
}
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
let e = self.report_error(t);
self.replaced_with_error = Some(e);
Ty::new_error(self.fcx.tcx, e)
}
}
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
debug_assert!(!r.is_bound(), "Should not be resolving bound region.");
self.fcx.tcx.lifetimes.re_erased
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.handle_term(ty, Ty::outer_exclusive_binder, Ty::new_error)
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match self.fcx.fully_resolve(ct) {
Ok(ct) => self.fcx.tcx.erase_regions(ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
let e = self.report_error(ct);
self.replaced_with_error = Some(e);
ty::Const::new_error(self.fcx.tcx, e, ct.ty())
}
}
self.handle_term(ct, ty::Const::outer_exclusive_binder, |tcx, guar| {
ty::Const::new_error(tcx, guar, ct.ty())
})
}
fn fold_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
// Do not normalize predicates in the new solver. The new solver is
// supposed to handle unnormalized predicates and incorrectly normalizing
// them can be unsound, e.g. for `WellFormed` predicates.
let prev = mem::replace(&mut self.should_normalize, false);
let predicate = predicate.super_fold_with(self);
self.should_normalize = prev;
predicate
}
}
///////////////////////////////////////////////////////////////////////////
// During type check, we store promises with the result of trait
// lookup rather than the actual results (because the results are not
// necessarily available immediately). These routines unwind the
// promises. It is expected that we will have already reported any
// errors that may be encountered, so if the promises store an error,
// a dummy result is returned.

View file

@ -232,7 +232,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
/// Return all DepNode labels that should be asserted for this item.
/// index=0 is the "name" used for error messages
fn auto_labels(&mut self, item_id: LocalDefId, attr: &Attribute) -> (&'static str, Labels) {
let node = self.tcx.hir().get_by_def_id(item_id);
let node = self.tcx.hir_node_by_def_id(item_id);
let (name, labels) = match node {
HirNode::Item(item) => {
match item.kind {

View file

@ -363,9 +363,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
return false;
};
let hir_id = self.tcx.local_def_id_to_hir_id(anon_reg.def_id);
let node = self.tcx.hir().get(hir_id);
let node = self.tcx.hir_node_by_def_id(anon_reg.def_id);
let is_impl = matches!(&node, hir::Node::ImplItem(_));
let generics = match node {
hir::Node::Item(&hir::Item {

View file

@ -166,10 +166,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
.into_iter()
.map(|(k, v)| (k, v.hidden_type.ty))
.collect()
self.take_opaque_types().into_iter().map(|(k, v)| (k, v.hidden_type.ty)).collect()
}
/// Given the (canonicalized) result to a canonical query,

View file

@ -891,7 +891,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
// don't suggest wrapping either blocks in `if .. {} else {}`
let is_empty_arm = |id| {
let hir::Node::Block(blk) = self.tcx.hir().get(id) else {
let hir::Node::Block(blk) = self.tcx.hir_node(id) else {
return false;
};
if blk.expr.is_some() || !blk.stmts.is_empty() {
@ -1743,7 +1743,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
if let Some((expected, found, exp_p, found_p)) = expected_found {
if let Some((expected, found, path)) = expected_found {
let (expected_label, found_label, exp_found) = match exp_found {
Mismatch::Variable(ef) => (
ef.expected.prefix_string(self.tcx),
@ -1869,40 +1869,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
TypeError::Sorts(values) => {
let extra = expected == found;
let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
let mut s = match (extra, ty.kind()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!(
" (opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
if let Some(path) = path {
s.push_str(&format!(
"\nthe full type name has been written to '{}'",
path.display(),
));
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!(
" (opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
s
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
if !(values.expected.is_simple_text(self.tcx)
&& values.found.is_simple_text(self.tcx))
@ -1933,9 +1924,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected,
&found_label,
found,
&sort_string(values.expected, exp_p),
&sort_string(values.found, found_p),
&sort_string(values.expected),
&sort_string(values.found),
);
if let Some(path) = path {
diag.note(format!(
"the full type name has been written to '{}'",
path.display(),
));
}
}
}
}
@ -2007,7 +2004,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
self.suggest_for_all_lifetime_closure(
span,
self.tcx.hir().get_by_def_id(def_id),
self.tcx.hir_node_by_def_id(def_id),
&exp_found,
diag,
);
@ -2101,7 +2098,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
| BlockTailExpression(.., source)) = code
&& let hir::MatchSource::TryDesugar(_) = source
&& let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
&& let Some((expected_ty, found_ty, _)) = self.values_str(trace.values)
{
suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
found: found_ty.content(),
@ -2121,7 +2118,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let TypeError::FixedArraySize(sz) = terr else {
return None;
};
let tykind = match hir.find_by_def_id(trace.cause.body_id) {
let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
let body = hir.body(*body_id);
struct LetVisitor<'v> {
@ -2219,8 +2216,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn values_str(
&self,
values: ValuePairs<'tcx>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
match values {
infer::Regions(exp_found) => self.expected_found_str(exp_found),
infer::Terms(exp_found) => self.expected_found_str_term(exp_found),
@ -2233,7 +2229,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found: exp_found.found.print_trait_sugared(),
};
match self.expected_found_str(pretty_exp_found) {
Some((expected, found, _, _)) if expected == found => {
Some((expected, found, _)) if expected == found => {
self.expected_found_str(exp_found)
}
ret => ret,
@ -2245,7 +2241,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return None;
}
let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
Some((exp, fnd, None, None))
Some((exp, fnd, None))
}
}
}
@ -2253,8 +2249,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn expected_found_str_term(
&self,
exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
@ -2269,25 +2264,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let len = self.tcx.sess().diagnostic_width() + 40;
let exp_s = exp.content();
let fnd_s = fnd.content();
let mut exp_p = None;
let mut fnd_p = None;
let mut path = None;
if exp_s.len() > len {
let (exp_s, exp_path) = self.tcx.short_ty_string(expected);
let exp_s = self.tcx.short_ty_string(expected, &mut path);
exp = DiagnosticStyledString::highlighted(exp_s);
exp_p = exp_path;
}
if fnd_s.len() > len {
let (fnd_s, fnd_path) = self.tcx.short_ty_string(found);
let fnd_s = self.tcx.short_ty_string(found, &mut path);
fnd = DiagnosticStyledString::highlighted(fnd_s);
fnd_p = fnd_path;
}
(exp, fnd, exp_p, fnd_p)
(exp, fnd, path)
}
_ => (
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
),
})
}
@ -2296,8 +2287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
&self,
exp_found: ty::error::ExpectedFound<T>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
@ -2307,7 +2297,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
))
}
@ -2452,7 +2441,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if !suggs.is_empty() {
err.multipart_suggestion_verbose(
format!("{msg}"),
msg,
suggs,
Applicability::MaybeIncorrect, // Issue #41966
);
@ -2591,8 +2580,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let infer::Subtype(ref sup_trace) = sup_origin
&& let infer::Subtype(ref sub_trace) = sub_origin
&& let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values)
&& let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values)
&& let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values)
&& let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values)
&& sub_expected == sup_expected
&& sub_found == sup_found
{
@ -2997,7 +2986,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// Given a [`hir::HirId`] for a block, get the span of its last expression
/// or statement, peeling off any inner blocks.
pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span {
match self.tcx.hir().get(hir_id) {
match self.tcx.hir_node(hir_id) {
hir::Node::Block(blk) => self.find_block_span(blk),
// The parser was in a weird state if either of these happen, but
// it's better not to panic.

View file

@ -26,8 +26,7 @@ pub fn find_anon_type<'tcx>(
br: &ty::BoundRegionKind,
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
let anon_reg = tcx.is_suitable_region(region)?;
let hir_id = tcx.local_def_id_to_hir_id(anon_reg.def_id);
let fn_sig = tcx.hir().get(hir_id).fn_sig()?;
let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?;
fn_sig
.decl

View file

@ -460,7 +460,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
if let Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), ..
}) = tcx.hir().find_by_def_id(impl_did)?
}) = tcx.opt_hir_node_by_def_id(impl_did)?
&& trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
// type in the `UnifyReceiver` context, but for now, use

View file

@ -50,11 +50,10 @@ pub fn find_param_with_region<'tcx>(
let hir = &tcx.hir();
let def_id = id.as_local()?;
let hir_id = tcx.local_def_id_to_hir_id(def_id);
// FIXME: use def_kind
// Don't perform this on closures
match hir.get(hir_id) {
match tcx.hir_node_by_def_id(def_id) {
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
return None;
}

View file

@ -22,7 +22,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
span: trace.cause.span,
requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)),
expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
}
.add_to_diagnostic(err),
infer::Reborrow(span) => {

View file

@ -655,7 +655,7 @@ fn foo(&self) -> Self::T { String::new() }
// When `body_owner` is an `impl` or `trait` item, look in its associated types for
// `expected` and point at it.
let parent_id = tcx.hir().get_parent_item(hir_id);
let item = tcx.hir().find_by_def_id(parent_id.def_id);
let item = tcx.opt_hir_node_by_def_id(parent_id.def_id);
debug!("expected_projection parent item {:?}", item);

View file

@ -42,7 +42,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
]
.into_iter()
.find_map(|(id, ty)| {
let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None };
let hir::Node::Block(blk) = self.tcx.hir_node(id?) else { return None };
self.could_remove_semicolon(blk, ty)
});
match remove_semicolon {
@ -62,7 +62,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let mut ret = None;
for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] {
if let Some(id) = id
&& let hir::Node::Block(blk) = self.tcx.hir().get(id)
&& let hir::Node::Block(blk) = self.tcx.hir_node(id)
&& let Some(diag) = self.consider_returning_binding_diag(blk, ty)
{
ret = Some(diag);

View file

@ -295,7 +295,7 @@ where
ty::Covariant | ty::Contravariant => (),
}
let origin = *inner.type_variables().var_origin(vid);
let origin = inner.type_variables().var_origin(vid);
let new_var_id =
inner.type_variables().new_var(self.for_universe, origin);
let u = Ty::new_var(self.tcx(), new_var_id);

View file

@ -98,6 +98,8 @@ pub(crate) type UnificationTable<'a, 'tcx, T> = ut::UnificationTable<
/// call to `start_snapshot` and `rollback_to`.
#[derive(Clone)]
pub struct InferCtxtInner<'tcx> {
undo_log: InferCtxtUndoLogs<'tcx>,
/// Cache for projections.
///
/// This cache is snapshotted along with the infcx.
@ -162,8 +164,6 @@ pub struct InferCtxtInner<'tcx> {
/// that all type inference variables have been bound and so forth.
region_obligations: Vec<RegionObligation<'tcx>>,
undo_log: InferCtxtUndoLogs<'tcx>,
/// Caches for opaque type inference.
opaque_type_storage: OpaqueTypeStorage<'tcx>,
}
@ -171,9 +171,10 @@ pub struct InferCtxtInner<'tcx> {
impl<'tcx> InferCtxtInner<'tcx> {
fn new() -> InferCtxtInner<'tcx> {
InferCtxtInner {
undo_log: InferCtxtUndoLogs::default(),
projection_cache: Default::default(),
type_variable_storage: type_variable::TypeVariableStorage::new(),
undo_log: InferCtxtUndoLogs::default(),
const_unification_storage: ut::UnificationTableStorage::new(),
int_unification_storage: ut::UnificationTableStorage::new(),
float_unification_storage: ut::UnificationTableStorage::new(),
@ -783,7 +784,7 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn type_var_origin(&self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin> {
match *ty.kind() {
ty::Infer(ty::TyVar(vid)) => {
Some(*self.inner.borrow_mut().type_variables().var_origin(vid))
Some(self.inner.borrow_mut().type_variables().var_origin(vid))
}
_ => None,
}
@ -793,11 +794,11 @@ impl<'tcx> InferCtxt<'tcx> {
freshen::TypeFreshener::new(self)
}
pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
pub fn unresolved_variables(&self) -> Vec<Ty<'tcx>> {
let mut inner = self.inner.borrow_mut();
let mut vars: Vec<Ty<'_>> = inner
.type_variables()
.unsolved_variables()
.unresolved_variables()
.into_iter()
.map(|t| Ty::new_var(self.tcx, t))
.collect();
@ -1306,12 +1307,7 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin {
let mut inner = self.inner.borrow_mut();
let inner = &mut *inner;
inner
.region_constraint_storage
.as_mut()
.expect("regions already resolved")
.with_log(&mut inner.undo_log)
.var_origin(vid)
inner.unwrap_region_constraints().var_origin(vid)
}
/// Clone the list of variable regions. This is used only during NLL processing

View file

@ -683,8 +683,8 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi
let res = hir_id == scope;
trace!(
"may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
tcx.hir().find(hir_id),
tcx.hir().get(opaque_hir_id),
tcx.opt_hir_node(hir_id),
tcx.hir_node(opaque_hir_id),
res
);
res

View file

@ -3,7 +3,7 @@ use self::env::OutlivesEnvironment;
use super::region_constraints::RegionConstraintData;
use super::{InferCtxt, RegionResolutionError};
use crate::infer::free_regions::RegionRelations;
use crate::infer::lexical_region_resolve::{self, LexicalRegionResolutions};
use crate::infer::lexical_region_resolve;
use rustc_middle::traits::query::OutlivesBound;
use rustc_middle::ty;
@ -37,32 +37,6 @@ pub fn explicit_outlives_bounds<'tcx>(
}
impl<'tcx> InferCtxt<'tcx> {
pub fn skip_region_resolution(&self) {
let (var_infos, _) = {
let mut inner = self.inner.borrow_mut();
let inner = &mut *inner;
// Note: `inner.region_obligations` may not be empty, because we
// didn't necessarily call `process_registered_region_obligations`.
// This is okay, because that doesn't introduce new vars.
inner
.region_constraint_storage
.take()
.expect("regions already resolved")
.with_log(&mut inner.undo_log)
.into_infos_and_data()
};
let lexical_region_resolutions = LexicalRegionResolutions {
values: rustc_index::IndexVec::from_elem_n(
crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased),
var_infos.len(),
),
};
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
assert!(old_value.is_none());
}
/// Process the region constraints and return any errors that
/// result. After this, no more unification operations should be
/// done -- or the compiler will panic -- but it is legal to use

View file

@ -134,7 +134,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for UnresolvedTypeOrConstFinder<'a, 'tc
if let TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeParameterDefinition(_, _),
span,
} = *ty_vars.var_origin(ty_vid)
} = ty_vars.var_origin(ty_vid)
{
Some(span)
} else {

View file

@ -1,4 +1,5 @@
use rustc_hir::def_id::DefId;
use rustc_index::IndexVec;
use rustc_middle::ty::{self, Ty, TyVid};
use rustc_span::symbol::Symbol;
use rustc_span::Span;
@ -11,14 +12,13 @@ use std::cmp;
use std::marker::PhantomData;
use std::ops::Range;
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
use rustc_data_structures::undo_log::Rollback;
/// Represents a single undo-able action that affects a type inference variable.
#[derive(Clone)]
pub(crate) enum UndoLog<'tcx> {
EqRelation(sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>),
SubRelation(sv::UndoLog<ut::Delegate<ty::TyVid>>),
Values(sv::UndoLog<Delegate>),
}
/// Convert from a specific kind of undo to the more general UndoLog
@ -35,34 +35,19 @@ impl<'tcx> From<sv::UndoLog<ut::Delegate<ty::TyVid>>> for UndoLog<'tcx> {
}
}
/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<sv::UndoLog<Delegate>> for UndoLog<'tcx> {
fn from(l: sv::UndoLog<Delegate>) -> Self {
UndoLog::Values(l)
}
}
/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<Instantiate> for UndoLog<'tcx> {
fn from(l: Instantiate) -> Self {
UndoLog::Values(sv::UndoLog::Other(l))
}
}
impl<'tcx> Rollback<UndoLog<'tcx>> for TypeVariableStorage<'tcx> {
fn reverse(&mut self, undo: UndoLog<'tcx>) {
match undo {
UndoLog::EqRelation(undo) => self.eq_relations.reverse(undo),
UndoLog::SubRelation(undo) => self.sub_relations.reverse(undo),
UndoLog::Values(undo) => self.values.reverse(undo),
}
}
}
#[derive(Clone)]
pub struct TypeVariableStorage<'tcx> {
values: sv::SnapshotVecStorage<Delegate>,
/// The origins of each type variable.
values: IndexVec<TyVid, TypeVariableData>,
/// Two variables are unified in `eq_relations` when we have a
/// constraint `?X == ?Y`. This table also stores, for each key,
/// the known value.
@ -168,15 +153,10 @@ impl<'tcx> TypeVariableValue<'tcx> {
}
}
#[derive(Clone)]
pub(crate) struct Instantiate;
pub(crate) struct Delegate;
impl<'tcx> TypeVariableStorage<'tcx> {
pub fn new() -> TypeVariableStorage<'tcx> {
TypeVariableStorage {
values: sv::SnapshotVecStorage::new(),
values: Default::default(),
eq_relations: ut::UnificationTableStorage::new(),
sub_relations: ut::UnificationTableStorage::new(),
}
@ -194,6 +174,11 @@ impl<'tcx> TypeVariableStorage<'tcx> {
pub(crate) fn eq_relations_ref(&self) -> &ut::UnificationTableStorage<TyVidEqKey<'tcx>> {
&self.eq_relations
}
pub(super) fn finalize_rollback(&mut self) {
debug_assert!(self.values.len() >= self.eq_relations.len());
self.values.truncate(self.eq_relations.len());
}
}
impl<'tcx> TypeVariableTable<'_, 'tcx> {
@ -201,8 +186,8 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
///
/// Note that this function does not return care whether
/// `vid` has been unified with something else or not.
pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin {
&self.storage.values.get(vid.as_usize()).origin
pub fn var_origin(&self, vid: ty::TyVid) -> TypeVariableOrigin {
self.storage.values[vid].origin
}
/// Records that `a == b`, depending on `dir`.
@ -237,11 +222,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
self.eq_relations().probe_value(vid)
);
self.eq_relations().union_value(vid, TypeVariableValue::Known { value: ty });
// Hack: we only need this so that `types_escaping_snapshot`
// can see what has been unified; see the Delegate impl for
// more details.
self.undo_log.push(Instantiate);
}
/// Creates a new type variable.
@ -262,14 +242,14 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe });
let sub_key = self.sub_relations().new_key(());
assert_eq!(eq_key.vid, sub_key);
debug_assert_eq!(eq_key.vid, sub_key);
let index = self.values().push(TypeVariableData { origin });
assert_eq!(eq_key.vid.as_u32(), index as u32);
let index = self.storage.values.push(TypeVariableData { origin });
debug_assert_eq!(eq_key.vid, index);
debug!("new_var(index={:?}, universe={:?}, origin={:?})", eq_key.vid, universe, origin);
eq_key.vid
index
}
/// Returns the number of type variables created thus far.
@ -329,13 +309,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
}
}
#[inline]
fn values(
&mut self,
) -> sv::SnapshotVec<Delegate, &mut Vec<TypeVariableData>, &mut InferCtxtUndoLogs<'tcx>> {
self.storage.values.with_log(self.undo_log)
}
#[inline]
fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> {
self.storage.eq_relations.with_log(self.undo_log)
@ -354,16 +327,14 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
let range = TyVid::from_usize(value_count)..TyVid::from_usize(self.num_vars());
(
range.start..range.end,
(range.start.as_usize()..range.end.as_usize())
.map(|index| self.storage.values.get(index).origin)
.collect(),
(range.start..range.end).map(|index| self.var_origin(index)).collect(),
)
}
/// Returns indices of all variables that are not yet
/// instantiated.
pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> {
(0..self.storage.values.len())
pub fn unresolved_variables(&mut self) -> Vec<ty::TyVid> {
(0..self.num_vars())
.filter_map(|i| {
let vid = ty::TyVid::from_usize(i);
match self.probe(vid) {
@ -375,26 +346,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
}
}
impl sv::SnapshotVecDelegate for Delegate {
type Value = TypeVariableData;
type Undo = Instantiate;
fn reverse(_values: &mut Vec<TypeVariableData>, _action: Instantiate) {
// We don't actually have to *do* anything to reverse an
// instantiation; the value for a variable is stored in the
// `eq_relations` and hence its rollback code will handle
// it. In fact, we could *almost* just remove the
// `SnapshotVec` entirely, except that we would have to
// reproduce *some* of its logic, since we want to know which
// type variables have been instantiated since the snapshot
// was started, so we can implement `types_escaping_snapshot`.
//
// (If we extended the `UnificationTable` to let us see which
// values have been unified and so forth, that might also
// suffice.)
}
}
///////////////////////////////////////////////////////////////////////////
/// These structs (a newtyped TyVid) are used as the unification key

View file

@ -32,7 +32,7 @@ pub(crate) enum UndoLog<'tcx> {
}
macro_rules! impl_from {
($($ctor: ident ($ty: ty),)*) => {
($($ctor:ident ($ty:ty),)*) => {
$(
impl<'tcx> From<$ty> for UndoLog<'tcx> {
fn from(x: $ty) -> Self {
@ -50,8 +50,6 @@ impl_from! {
TypeVariables(sv::UndoLog<ut::Delegate<type_variable::TyVidEqKey<'tcx>>>),
TypeVariables(sv::UndoLog<ut::Delegate<ty::TyVid>>),
TypeVariables(sv::UndoLog<type_variable::Delegate>),
TypeVariables(type_variable::Instantiate),
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
@ -140,6 +138,8 @@ impl<'tcx> InferCtxtInner<'tcx> {
self.reverse(undo);
}
self.type_variable_storage.finalize_rollback();
if self.undo_log.num_open_snapshots == 1 {
// After the root snapshot the undo log should be empty.
assert!(snapshot.undo_len == 0);

View file

@ -706,9 +706,13 @@ pub trait LintContext {
},
BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().copied().collect();
let is_from_cargo = std::env::var_os("CARGO").is_some();
let mut is_feature_cfg = name == sym::feature;
if is_feature_cfg && is_from_cargo {
db.help("consider defining some features in `Cargo.toml`");
// Suggest the most probable if we found one
if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
} else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
if let Some(ExpectedValues::Some(best_match_values)) =
sess.parse_sess.check_config.expecteds.get(&best_match) {
let mut possibilities = best_match_values.iter()
@ -741,8 +745,8 @@ pub trait LintContext {
} else {
db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect);
}
} else if name == sym::feature && std::env::var_os("CARGO").is_some() {
db.help("consider defining some features in `Cargo.toml`");
is_feature_cfg |= best_match == sym::feature;
} else if !possibilities.is_empty() {
let mut possibilities = possibilities.iter()
.map(Symbol::as_str)
@ -756,6 +760,23 @@ pub trait LintContext {
// once.
db.help_once(format!("expected names are: `{possibilities}`"));
}
let inst = if let Some((value, _value_span)) = value {
let pre = if is_from_cargo { "\\" } else { "" };
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
} else {
format!("cfg({name})")
};
if is_from_cargo {
if !is_feature_cfg {
db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
}
db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
} else {
db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
}
},
BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => {
let Some(ExpectedValues::Some(values)) = &sess.parse_sess.check_config.expecteds.get(&name) else {
@ -767,6 +788,7 @@ pub trait LintContext {
.copied()
.flatten()
.collect();
let is_from_cargo = std::env::var_os("CARGO").is_some();
// Show the full list if all possible values for a given name, but don't do it
// for names as the possibilities could be very long
@ -787,6 +809,8 @@ pub trait LintContext {
db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
}
} else if name == sym::feature && is_from_cargo {
db.help(format!("consider defining `{name}` as feature in `Cargo.toml`"));
} else if let &[first_possibility] = &possibilities[..] {
db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect);
}
@ -796,6 +820,27 @@ pub trait LintContext {
db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect);
}
}
let inst = if let Some((value, _value_span)) = value {
let pre = if is_from_cargo { "\\" } else { "" };
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
} else {
format!("cfg({name})")
};
if is_from_cargo {
if name == sym::feature {
if let Some((value, _value_span)) = value {
db.help(format!("consider adding `{value}` as a feature in `Cargo.toml`"));
}
} else {
db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
}
db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
} else {
db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
}
},
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(new_span, suggestion) => {
db.multipart_suggestion(

View file

@ -34,7 +34,7 @@ declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
impl LateLintPass<'_> for DefaultHashTypes {
fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return };
if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
if matches!(cx.tcx.hir_node(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
// don't lint imports, only actual usages
return;
}

View file

@ -202,7 +202,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
) -> bool {
// Look past casts to support cases like `0..256 as u8`
let (expr, lit_span) = if let Node::Expr(par_expr) =
cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id))
cx.tcx.hir_node(cx.tcx.hir().parent_id(expr.hir_id))
&& let ExprKind::Cast(_, _) = par_expr.kind
{
(par_expr, expr.span)
@ -213,7 +213,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
let par_id = cx.tcx.hir().parent_id(expr.hir_id);
let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
let Node::ExprField(field) = cx.tcx.hir_node(par_id) else { return false };
let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false };
if !is_range_literal(struct_expr) {
return false;
@ -498,7 +498,7 @@ fn lint_uint_literal<'tcx>(
};
if lit_val < min || lit_val > max {
let parent_id = cx.tcx.hir().parent_id(e.hir_id);
if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) {
if let Node::Expr(par_e) = cx.tcx.hir_node(parent_id) {
match par_e.kind {
hir::ExprKind::Cast(..) => {
if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {

View file

@ -345,12 +345,34 @@ pub struct FutureIncompatibleInfo {
}
/// The reason for future incompatibility
///
/// Future-incompatible lints come in roughly two categories:
///
/// 1. There was a mistake in the compiler (such as a soundness issue), and
/// we're trying to fix it, but it may be a breaking change.
/// 2. A change across an Edition boundary, typically used for the
/// introduction of new language features that can't otherwise be
/// introduced in a backwards-compatible way.
///
/// See <https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html> and
/// <https://rustc-dev-guide.rust-lang.org/diagnostics.html#future-incompatible-lints>
/// for more information.
#[derive(Copy, Clone, Debug)]
pub enum FutureIncompatibilityReason {
/// This will be an error in a future release for all editions
///
/// This will *not* show up in cargo's future breakage report.
/// The warning will hence only be seen in local crates, not in dependencies.
///
/// Choose this variant when you are first introducing a "future
/// incompatible" warning that is intended to eventually be fixed in the
/// future. This allows crate developers an opportunity to fix the warning
/// before blasting all dependents with a warning they can't fix
/// (dependents have to wait for a new release of the affected crate to be
/// published).
///
/// After a lint has been in this state for a while, consider graduating
/// it to [`FutureIncompatibilityReason::FutureReleaseErrorReportInDeps`].
FutureReleaseErrorDontReportInDeps,
/// This will be an error in a future release, and
/// Cargo should create a report even for dependencies
@ -358,17 +380,62 @@ pub enum FutureIncompatibilityReason {
/// This is the *only* reason that will make future incompatibility warnings show up in cargo's
/// reports. All other future incompatibility warnings are not visible when they occur in a
/// dependency.
///
/// Choose this variant after the lint has been sitting in the
/// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`]
/// state for a while, and you feel like it is ready to graduate to
/// warning everyone. It is a good signal that it is ready if you can
/// determine that all or most affected crates on crates.io have been
/// updated.
///
/// After some period of time, lints with this variant can be turned into
/// hard errors (and the lint removed). Preferably when there is some
/// confidence that the number of impacted projects is very small (few
/// should have a broken dependency in their dependency tree).
FutureReleaseErrorReportInDeps,
/// Code that changes meaning in some way in a
/// future release.
///
/// Choose this variant when the semantics of existing code is changing,
/// (as opposed to
/// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`],
/// which is for when code is going to be rejected in the future).
FutureReleaseSemanticsChange,
/// Previously accepted code that will become an
/// error in the provided edition
///
/// Choose this variant for code that you want to start rejecting across
/// an edition boundary. This will automatically include the lint in the
/// `rust-20xx-compatibility` lint group, which is used by `cargo fix
/// --edition` to do migrations. The lint *should* be auto-fixable with
/// [`Applicability::MachineApplicable`].
///
/// The lint can either be `Allow` or `Warn` by default. If it is `Allow`,
/// users usually won't see this warning unless they are doing an edition
/// migration manually or there is a problem during the migration (cargo's
/// automatic migrations will force the level to `Warn`). If it is `Warn`
/// by default, users on all editions will see this warning (only do this
/// if you think it is important for everyone to be aware of the change,
/// and to encourage people to update their code on all editions).
///
/// See also [`FutureIncompatibilityReason::EditionSemanticsChange`] if
/// you have code that is changing semantics across the edition (as
/// opposed to being rejected).
EditionError(Edition),
/// Code that changes meaning in some way in
/// the provided edition
///
/// This is the same as [`FutureIncompatibilityReason::EditionError`],
/// except for situations where the semantics change across an edition. It
/// slightly changes the text of the diagnostic, but is otherwise the
/// same.
EditionSemanticsChange(Edition),
/// A custom reason.
///
/// Choose this variant if the built-in text of the diagnostic of the
/// other variants doesn't match your situation. This is behaviorally
/// equivalent to
/// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`].
Custom(&'static str),
}

View file

@ -37,7 +37,9 @@
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#if LLVM_VERSION_GE(18, 0)
#include "llvm/TargetParser/Host.h"
#endif
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Support/TimeProfiler.h"

View file

@ -697,6 +697,25 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
}
}
enum class LLVMRustDebugNameTableKind {
Default,
GNU,
None,
};
static DICompileUnit::DebugNameTableKind fromRust(LLVMRustDebugNameTableKind Kind) {
switch (Kind) {
case LLVMRustDebugNameTableKind::Default:
return DICompileUnit::DebugNameTableKind::Default;
case LLVMRustDebugNameTableKind::GNU:
return DICompileUnit::DebugNameTableKind::GNU;
case LLVMRustDebugNameTableKind::None:
return DICompileUnit::DebugNameTableKind::None;
default:
report_fatal_error("bad DebugNameTableKind.");
}
}
enum class LLVMRustChecksumKind {
None,
MD5,
@ -765,13 +784,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
const char *Flags, unsigned RuntimeVer,
const char *SplitName, size_t SplitNameLen,
LLVMRustDebugEmissionKind Kind,
uint64_t DWOId, bool SplitDebugInlining) {
uint64_t DWOId, bool SplitDebugInlining,
LLVMRustDebugNameTableKind TableKind) {
auto *File = unwrapDI<DIFile>(FileRef);
return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
isOptimized, Flags, RuntimeVer,
StringRef(SplitName, SplitNameLen),
fromRust(Kind), DWOId, SplitDebugInlining));
fromRust(Kind), DWOId, SplitDebugInlining,
false, fromRust(TableKind)));
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(

View file

@ -1144,7 +1144,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
let origin = tcx.opaque_type_origin(def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
false
@ -1161,7 +1161,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
}
}
DefKind::TyParam => {
let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() };
let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(def_id) else { bug!() };
let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() };
default.is_some()
}
@ -1372,7 +1372,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// anonymous constants will not work on them and panic. It's not clear whether it
// can cause any observable issues or not.
let anon_const_without_hir = def_kind == DefKind::AnonConst
&& tcx.hir().find(tcx.local_def_id_to_hir_id(local_id)).is_none();
&& tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
if should_encode_generics(def_kind) && !anon_const_without_hir {
let g = tcx.generics_of(def_id);
record!(self.tables.generics_of[def_id] <- g);

View file

@ -92,10 +92,6 @@ macro_rules! arena_types {
[] name_set: rustc_data_structures::unord::UnordSet<rustc_span::symbol::Symbol>,
[] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::symbol::Symbol>,
// Interned types
[] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyKind<'tcx>>,
[] consts: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::ConstData<'tcx>>,
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena
// (during lowering) and the `librustc_middle` arena (for decoding MIR)

View file

@ -57,6 +57,10 @@ fn is_body_owner(node: Node<'_>, hir_id: HirId) -> bool {
}
}
// FIXME: the structure was necessary in the past but now it
// only serves as "namespace" for HIR-related methods, and can be
// removed if all the methods are reasonably renamed and moved to tcx
// (https://github.com/rust-lang/rust/pull/118256#issuecomment-1826442834).
#[derive(Copy, Clone)]
pub struct Map<'hir> {
pub(super) tcx: TyCtxt<'hir>,
@ -128,6 +132,40 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
}
}
impl<'tcx> TyCtxt<'tcx> {
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
if id.local_id == ItemLocalId::from_u32(0) {
let owner = self.hir_owner(id.owner)?;
Some(owner.node.into())
} else {
let owner = self.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
Some(node.node)
}
}
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
self.opt_hir_node(self.opt_local_def_id_to_hir_id(id)?)
}
/// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
#[track_caller]
pub fn hir_node(self, id: HirId) -> Node<'tcx> {
self.opt_hir_node(id).unwrap_or_else(|| bug!("couldn't find HIR node for hir id {id:?}"))
}
/// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
#[inline]
#[track_caller]
pub fn hir_node_by_def_id(self, id: LocalDefId) -> Node<'tcx> {
self.opt_hir_node_by_def_id(id)
.unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}"))
}
}
impl<'hir> Map<'hir> {
#[inline]
pub fn krate(self) -> &'hir Crate<'hir> {
@ -191,46 +229,15 @@ impl<'hir> Map<'hir> {
}
pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
self.get(self.parent_id(hir_id))
self.tcx.hir_node(self.parent_id(hir_id))
}
pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
self.find(self.opt_parent_id(hir_id)?)
}
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(self, id: HirId) -> Option<Node<'hir>> {
if id.local_id == ItemLocalId::from_u32(0) {
let owner = self.tcx.hir_owner(id.owner)?;
Some(owner.node.into())
} else {
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
Some(node.node)
}
}
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn find_by_def_id(self, id: LocalDefId) -> Option<Node<'hir>> {
self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)
}
/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
#[track_caller]
pub fn get(self, id: HirId) -> Node<'hir> {
self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id))
}
/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
#[inline]
#[track_caller]
pub fn get_by_def_id(self, id: LocalDefId) -> Node<'hir> {
self.find_by_def_id(id).unwrap_or_else(|| bug!("couldn't find {:?} in the HIR map", id))
self.tcx.opt_hir_node(self.opt_parent_id(hir_id)?)
}
pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?))
id.as_local().and_then(|id| self.tcx.opt_hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?))
}
pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
@ -264,7 +271,7 @@ impl<'hir> Map<'hir> {
#[track_caller]
pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
if let Some(node) = self.find(hir_id) {
if let Some(node) = self.tcx.opt_hir_node(hir_id) {
node.fn_decl()
} else {
bug!("no node for hir_id `{}`", hir_id)
@ -273,7 +280,7 @@ impl<'hir> Map<'hir> {
#[track_caller]
pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
if let Some(node) = self.find(hir_id) {
if let Some(node) = self.tcx.opt_hir_node(hir_id) {
node.fn_sig()
} else {
bug!("no node for hir_id `{}`", hir_id)
@ -296,19 +303,22 @@ impl<'hir> Map<'hir> {
/// item (possibly associated), a closure, or a `hir::AnonConst`.
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
let parent = self.parent_id(hir_id);
assert!(self.find(parent).is_some_and(|n| is_body_owner(n, hir_id)), "{hir_id:?}");
assert!(
self.tcx.opt_hir_node(parent).is_some_and(|n| is_body_owner(n, hir_id)),
"{hir_id:?}"
);
parent
}
pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId {
let parent = self.parent_id(hir_id);
associated_body(self.get(parent)).unwrap().0
associated_body(self.tcx.hir_node(parent)).unwrap().0
}
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`.
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> {
let node = self.find_by_def_id(id)?;
let node = self.tcx.opt_hir_node_by_def_id(id)?;
let (_, body_id) = associated_body(node)?;
Some(body_id)
}
@ -548,7 +558,7 @@ impl<'hir> Map<'hir> {
/// until the crate root is reached. Prefer this over your own loop using `parent_id`.
#[inline]
pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.tcx.opt_hir_node(id)?)))
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
@ -600,7 +610,7 @@ impl<'hir> Map<'hir> {
pub fn get_return_block(self, id: HirId) -> Option<HirId> {
let mut iter = self.parent_iter(id).peekable();
let mut ignore_tail = false;
if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.find(id) {
if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.tcx.opt_hir_node(id) {
// When dealing with `return` statements, we don't care about climbing only tail
// expressions.
ignore_tail = true;
@ -708,7 +718,7 @@ impl<'hir> Map<'hir> {
let mut scope = id;
loop {
scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID);
if scope == CRATE_HIR_ID || !matches!(self.get(scope), Node::Block(_)) {
if scope == CRATE_HIR_ID || !matches!(self.tcx.hir_node(scope), Node::Block(_)) {
return scope;
}
}
@ -764,7 +774,7 @@ impl<'hir> Map<'hir> {
}
pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
match self.find(id) {
match self.tcx.opt_hir_node(id) {
Some(Node::Variant(variant)) => variant,
_ => bug!("expected variant, found {}", self.node_to_string(id)),
}
@ -783,7 +793,7 @@ impl<'hir> Map<'hir> {
}
pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
match self.find(id) {
match self.tcx.opt_hir_node(id) {
Some(Node::Expr(expr)) => expr,
_ => bug!("expected expr, found {}", self.node_to_string(id)),
}
@ -791,7 +801,7 @@ impl<'hir> Map<'hir> {
#[inline]
fn opt_ident(self, id: HirId) -> Option<Ident> {
match self.find(id)? {
match self.tcx.opt_hir_node(id)? {
Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
// A `Ctor` doesn't have an identifier itself, but its parent
// struct/variant does. Compare with `hir::Map::opt_span`.
@ -860,7 +870,7 @@ impl<'hir> Map<'hir> {
}
}
let span = match self.find(hir_id)? {
let span = match self.tcx.opt_hir_node(hir_id)? {
// Function-like.
Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
| Node::TraitItem(TraitItem {
@ -950,7 +960,7 @@ impl<'hir> Map<'hir> {
/// Like `hir.span()`, but includes the body of items
/// (instead of just the item header)
pub fn span_with_body(self, hir_id: HirId) -> Span {
match self.get(hir_id) {
match self.tcx.hir_node(hir_id) {
Node::Param(param) => param.span,
Node::Item(item) => item.span,
Node::ForeignItem(foreign_item) => foreign_item.span,
@ -1045,7 +1055,7 @@ impl<'hir> Map<'hir> {
impl<'hir> intravisit::Map<'hir> for Map<'hir> {
fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
(*self).find(hir_id)
self.tcx.opt_hir_node(hir_id)
}
fn body(&self, id: BodyId) -> &'hir Body<'hir> {
@ -1159,7 +1169,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
match map.find(id) {
match map.tcx.opt_hir_node(id) {
Some(Node::Item(item)) => {
let item_str = match item.kind {
ItemKind::ExternCrate(..) => "extern crate",

View file

@ -195,7 +195,7 @@ pub fn provide(providers: &mut Providers) {
| Node::ForeignItem(&ForeignItem {
kind: ForeignItemKind::Fn(_, idents, _),
..
}) = hir.get(hir_id)
}) = tcx.hir_node(hir_id)
{
idents
} else {

View file

@ -180,7 +180,7 @@ impl Scope {
};
let span = tcx.hir().span(hir_id);
if let ScopeData::Remainder(first_statement_index) = self.data {
if let Node::Block(blk) = tcx.hir().get(hir_id) {
if let Node::Block(blk) = tcx.hir_node(hir_id) {
// Want span for scope starting after the
// indexed statement and ending at end of
// `blk`; reuse span of `blk` and shift `lo`

View file

@ -219,7 +219,7 @@ fn late_report_deprecation(
}
let method_span = method_span.unwrap_or(span);
tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| {
if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
if let hir::Node::Expr(_) = tcx.hir_node(hir_id) {
let kind = tcx.def_descr(def_id);
deprecation_suggestion(diag, kind, suggestion, method_span);
}

View file

@ -30,7 +30,7 @@ impl<'tcx> IntoKind for Const<'tcx> {
type Kind = ConstKind<'tcx>;
fn kind(self) -> ConstKind<'tcx> {
self.kind().clone()
self.kind()
}
}
@ -41,7 +41,8 @@ impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
}
/// Typed constant value.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable)]
pub struct ConstData<'tcx> {
pub ty: Ty<'tcx>,
pub kind: ConstKind<'tcx>,
@ -166,7 +167,7 @@ impl<'tcx> Const<'tcx> {
/// becomes `Unevaluated`.
#[instrument(skip(tcx), level = "debug")]
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
let body_id = match tcx.hir().get_by_def_id(def) {
let body_id = match tcx.hir_node_by_def_id(def) {
hir::Node::AnonConst(ac) => ac.body,
_ => span_bug!(
tcx.def_span(def.to_def_id()),
@ -442,7 +443,7 @@ impl<'tcx> Const<'tcx> {
}
pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Const<'_>> {
let default_def_id = match tcx.hir().get_by_def_id(def_id) {
let default_def_id = match tcx.hir_node_by_def_id(def_id) {
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { default: Some(ac), .. },
..

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