Auto merge of #111925 - Manishearth:rollup-z6z6l2v, r=Manishearth
Rollup of 5 pull requests Successful merges: - #111741 (Use `ObligationCtxt` in custom type ops) - #111840 (Expose more information in `get_body_with_borrowck_facts`) - #111876 (Roll compiler_builtins to 0.1.92) - #111912 (Use `Option::is_some_and` and `Result::is_ok_and` in the compiler ) - #111915 (libtest: Improve error when missing `-Zunstable-options`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7664dfe433
115 changed files with 417 additions and 378 deletions
|
@ -726,9 +726,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.91"
|
version = "0.1.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "571298a3cce7e2afbd3d61abb91a18667d5ab25993ec577a88ee8ac45f00cc3a"
|
checksum = "64518f1ae689f74db058bbfb3238dfe6eb53f59f4ae712f1ff4348628522e190"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
|
|
|
@ -2391,10 +2391,10 @@ pub struct FnDecl {
|
||||||
|
|
||||||
impl FnDecl {
|
impl FnDecl {
|
||||||
pub fn has_self(&self) -> bool {
|
pub fn has_self(&self) -> bool {
|
||||||
self.inputs.get(0).map_or(false, Param::is_self)
|
self.inputs.get(0).is_some_and(Param::is_self)
|
||||||
}
|
}
|
||||||
pub fn c_variadic(&self) -> bool {
|
pub fn c_variadic(&self) -> bool {
|
||||||
self.inputs.last().map_or(false, |arg| matches!(arg.ty.kind, TyKind::CVarArgs))
|
self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ impl Attribute {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_have_doc_links(&self) -> bool {
|
pub fn may_have_doc_links(&self) -> bool {
|
||||||
self.doc_str().map_or(false, |s| comments::may_have_doc_links(s.as_str()))
|
self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_proc_macro_attr(&self) -> bool {
|
pub fn is_proc_macro_attr(&self) -> bool {
|
||||||
|
@ -441,12 +441,12 @@ impl NestedMetaItem {
|
||||||
|
|
||||||
/// Returns `true` if this list item is a MetaItem with a name of `name`.
|
/// Returns `true` if this list item is a MetaItem with a name of `name`.
|
||||||
pub fn has_name(&self, name: Symbol) -> bool {
|
pub fn has_name(&self, name: Symbol) -> bool {
|
||||||
self.meta_item().map_or(false, |meta_item| meta_item.has_name(name))
|
self.meta_item().is_some_and(|meta_item| meta_item.has_name(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `self` is a `MetaItem` and the meta item is a word.
|
/// Returns `true` if `self` is a `MetaItem` and the meta item is a word.
|
||||||
pub fn is_word(&self) -> bool {
|
pub fn is_word(&self) -> bool {
|
||||||
self.meta_item().map_or(false, |meta_item| meta_item.is_word())
|
self.meta_item().is_some_and(|meta_item| meta_item.is_word())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a list of inner meta items from a list `MetaItem` type.
|
/// Gets a list of inner meta items from a list `MetaItem` type.
|
||||||
|
|
|
@ -607,7 +607,7 @@ impl Token {
|
||||||
/// Returns `true` if the token is an identifier whose name is the given
|
/// Returns `true` if the token is an identifier whose name is the given
|
||||||
/// string slice.
|
/// string slice.
|
||||||
pub fn is_ident_named(&self, name: Symbol) -> bool {
|
pub fn is_ident_named(&self, name: Symbol) -> bool {
|
||||||
self.ident().map_or(false, |(ident, _)| ident.name == name)
|
self.ident().is_some_and(|(ident, _)| ident.name == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the token is an interpolated path.
|
/// Returns `true` if the token is an interpolated path.
|
||||||
|
|
|
@ -392,8 +392,7 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
|
||||||
// Small bases are lexed as if they were base 10, e.g, the string
|
// Small bases are lexed as if they were base 10, e.g, the string
|
||||||
// might be `0b10201`. This will cause the conversion above to fail,
|
// might be `0b10201`. This will cause the conversion above to fail,
|
||||||
// but these kinds of errors are already reported by the lexer.
|
// but these kinds of errors are already reported by the lexer.
|
||||||
let from_lexer =
|
let from_lexer = base < 10 && s.chars().any(|c| c.to_digit(10).is_some_and(|d| d >= base));
|
||||||
base < 10 && s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
|
|
||||||
if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) }
|
if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ impl<'a> AstValidator<'a> {
|
||||||
let source_map = self.session.source_map();
|
let source_map = self.session.source_map();
|
||||||
let end = source_map.end_point(sp);
|
let end = source_map.end_point(sp);
|
||||||
|
|
||||||
if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
|
if source_map.span_to_snippet(end).is_ok_and(|s| s == ";") {
|
||||||
end
|
end
|
||||||
} else {
|
} else {
|
||||||
sp.shrink_to_hi()
|
sp.shrink_to_hi()
|
||||||
|
|
|
@ -317,8 +317,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
match i.kind {
|
match i.kind {
|
||||||
ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => {
|
ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => {
|
||||||
let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
|
let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
|
||||||
let links_to_llvm =
|
let links_to_llvm = link_name.is_some_and(|val| val.as_str().starts_with("llvm."));
|
||||||
link_name.map_or(false, |val| val.as_str().starts_with("llvm."));
|
|
||||||
if links_to_llvm {
|
if links_to_llvm {
|
||||||
gate_feature_post!(
|
gate_feature_post!(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct BorrowSet<'tcx> {
|
||||||
/// Map from local to all the borrows on that local.
|
/// Map from local to all the borrows on that local.
|
||||||
pub local_map: FxIndexMap<mir::Local, FxIndexSet<BorrowIndex>>,
|
pub local_map: FxIndexMap<mir::Local, FxIndexSet<BorrowIndex>>,
|
||||||
|
|
||||||
pub(crate) locals_state_at_exit: LocalsStateAtExit,
|
pub locals_state_at_exit: LocalsStateAtExit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
|
impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
|
||||||
|
@ -153,7 +153,7 @@ impl<'tcx> BorrowSet<'tcx> {
|
||||||
self.activation_map.get(&location).map_or(&[], |activations| &activations[..])
|
self.activation_map.get(&location).map_or(&[], |activations| &activations[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.location_map.len()
|
self.location_map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,95 @@
|
||||||
//! This file provides API for compiler consumers.
|
//! This file provides API for compiler consumers.
|
||||||
|
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
|
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
|
||||||
use rustc_middle::mir::Body;
|
use rustc_middle::mir::{Body, Promoted};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::borrow_set::BorrowSet;
|
||||||
|
|
||||||
pub use super::{
|
pub use super::{
|
||||||
|
constraints::OutlivesConstraint,
|
||||||
|
dataflow::{calculate_borrows_out_of_scope_at_location, BorrowIndex, Borrows},
|
||||||
facts::{AllFacts as PoloniusInput, RustcFacts},
|
facts::{AllFacts as PoloniusInput, RustcFacts},
|
||||||
location::{LocationTable, RichLocation},
|
location::{LocationTable, RichLocation},
|
||||||
nll::PoloniusOutput,
|
nll::PoloniusOutput,
|
||||||
BodyWithBorrowckFacts,
|
place_ext::PlaceExt,
|
||||||
|
places_conflict::{places_conflict, PlaceConflictBias},
|
||||||
|
region_infer::RegionInferenceContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This function computes Polonius facts for the given body. It makes a copy of
|
/// Options determining the output behavior of [`get_body_with_borrowck_facts`].
|
||||||
/// the body because it needs to regenerate the region identifiers. This function
|
///
|
||||||
/// should never be invoked during a typical compilation session due to performance
|
/// If executing under `-Z polonius` the choice here has no effect, and everything as if
|
||||||
/// issues with Polonius.
|
/// [`PoloniusOutputFacts`](ConsumerOptions::PoloniusOutputFacts) had been selected
|
||||||
|
/// will be retrieved.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum ConsumerOptions {
|
||||||
|
/// Retrieve the [`Body`] along with the [`BorrowSet`](super::borrow_set::BorrowSet)
|
||||||
|
/// and [`RegionInferenceContext`]. If you would like the body only, use
|
||||||
|
/// [`TyCtxt::mir_promoted`].
|
||||||
|
///
|
||||||
|
/// These can be used in conjunction with [`calculate_borrows_out_of_scope_at_location`].
|
||||||
|
RegionInferenceContext,
|
||||||
|
/// The recommended option. Retrieves the maximal amount of information
|
||||||
|
/// without significant slowdowns.
|
||||||
|
///
|
||||||
|
/// Implies [`RegionInferenceContext`](ConsumerOptions::RegionInferenceContext),
|
||||||
|
/// and additionally retrieve the [`LocationTable`] and [`PoloniusInput`] that
|
||||||
|
/// would be given to Polonius. Critically, this does not run Polonius, which
|
||||||
|
/// one may want to avoid due to performance issues on large bodies.
|
||||||
|
PoloniusInputFacts,
|
||||||
|
/// Implies [`PoloniusInputFacts`](ConsumerOptions::PoloniusInputFacts),
|
||||||
|
/// and additionally runs Polonius to calculate the [`PoloniusOutput`].
|
||||||
|
PoloniusOutputFacts,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConsumerOptions {
|
||||||
|
/// Should the Polonius input facts be computed?
|
||||||
|
pub(crate) fn polonius_input(&self) -> bool {
|
||||||
|
matches!(self, Self::PoloniusInputFacts | Self::PoloniusOutputFacts)
|
||||||
|
}
|
||||||
|
/// Should we run Polonius and collect the output facts?
|
||||||
|
pub(crate) fn polonius_output(&self) -> bool {
|
||||||
|
matches!(self, Self::PoloniusOutputFacts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `Body` with information computed by the borrow checker. This struct is
|
||||||
|
/// intended to be consumed by compiler consumers.
|
||||||
|
///
|
||||||
|
/// We need to include the MIR body here because the region identifiers must
|
||||||
|
/// match the ones in the Polonius facts.
|
||||||
|
pub struct BodyWithBorrowckFacts<'tcx> {
|
||||||
|
/// A mir body that contains region identifiers.
|
||||||
|
pub body: Body<'tcx>,
|
||||||
|
/// The mir bodies of promoteds.
|
||||||
|
pub promoted: IndexVec<Promoted, Body<'tcx>>,
|
||||||
|
/// The set of borrows occurring in `body` with data about them.
|
||||||
|
pub borrow_set: Rc<BorrowSet<'tcx>>,
|
||||||
|
/// Context generated during borrowck, intended to be passed to
|
||||||
|
/// [`calculate_borrows_out_of_scope_at_location`].
|
||||||
|
pub region_inference_context: Rc<RegionInferenceContext<'tcx>>,
|
||||||
|
/// The table that maps Polonius points to locations in the table.
|
||||||
|
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
|
||||||
|
/// or [`ConsumerOptions::PoloniusOutputFacts`].
|
||||||
|
pub location_table: Option<LocationTable>,
|
||||||
|
/// Polonius input facts.
|
||||||
|
/// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
|
||||||
|
/// or [`ConsumerOptions::PoloniusOutputFacts`].
|
||||||
|
pub input_facts: Option<Box<PoloniusInput>>,
|
||||||
|
/// Polonius output facts. Populated when using
|
||||||
|
/// [`ConsumerOptions::PoloniusOutputFacts`].
|
||||||
|
pub output_facts: Option<Rc<PoloniusOutput>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
|
||||||
|
/// determine which facts are returned. This function makes a copy of the body because
|
||||||
|
/// it needs to regenerate the region identifiers. It should never be invoked during a
|
||||||
|
/// typical compilation session due to the unnecessary overhead of returning
|
||||||
|
/// [`BodyWithBorrowckFacts`].
|
||||||
///
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
/// * This function will panic if the required body was already stolen. This
|
/// * This function will panic if the required body was already stolen. This
|
||||||
|
@ -28,10 +101,14 @@ pub use super::{
|
||||||
/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
|
/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
|
||||||
///
|
///
|
||||||
/// * Polonius is highly unstable, so expect regular changes in its signature or other details.
|
/// * Polonius is highly unstable, so expect regular changes in its signature or other details.
|
||||||
pub fn get_body_with_borrowck_facts(tcx: TyCtxt<'_>, def: LocalDefId) -> BodyWithBorrowckFacts<'_> {
|
pub fn get_body_with_borrowck_facts(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
def: LocalDefId,
|
||||||
|
options: ConsumerOptions,
|
||||||
|
) -> BodyWithBorrowckFacts<'_> {
|
||||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
|
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
|
||||||
let input_body: &Body<'_> = &input_body.borrow();
|
let input_body: &Body<'_> = &input_body.borrow();
|
||||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||||
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()
|
*super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,27 +228,32 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
|
||||||
|
body: &Body<'tcx>,
|
||||||
|
regioncx: &RegionInferenceContext<'tcx>,
|
||||||
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
|
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
|
||||||
|
let mut prec = OutOfScopePrecomputer::new(body, regioncx);
|
||||||
|
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
|
||||||
|
let borrow_region = borrow_data.region;
|
||||||
|
let location = borrow_data.reserve_location;
|
||||||
|
|
||||||
|
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
prec.borrows_out_of_scope_at_location
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
||||||
pub(crate) fn new(
|
pub fn new(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
nonlexical_regioncx: &'a RegionInferenceContext<'tcx>,
|
nonlexical_regioncx: &'a RegionInferenceContext<'tcx>,
|
||||||
borrow_set: &'a BorrowSet<'tcx>,
|
borrow_set: &'a BorrowSet<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut prec = OutOfScopePrecomputer::new(body, nonlexical_regioncx);
|
let borrows_out_of_scope_at_location =
|
||||||
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
|
calculate_borrows_out_of_scope_at_location(body, nonlexical_regioncx, borrow_set);
|
||||||
let borrow_region = borrow_data.region;
|
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
|
||||||
let location = borrow_data.reserve_location;
|
|
||||||
|
|
||||||
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
Borrows {
|
|
||||||
tcx,
|
|
||||||
body,
|
|
||||||
borrow_set,
|
|
||||||
borrows_out_of_scope_at_location: prec.borrows_out_of_scope_at_location,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn location(&self, idx: BorrowIndex) -> &Location {
|
pub fn location(&self, idx: BorrowIndex) -> &Location {
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl<'tcx> ToUniverseInfo<'tcx>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp<F, G>> {
|
impl<'tcx, F> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp<F>> {
|
||||||
fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
||||||
// We can't rerun custom type ops.
|
// We can't rerun custom type ops.
|
||||||
UniverseInfo::other()
|
UniverseInfo::other()
|
||||||
|
|
|
@ -118,7 +118,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
let path_span = path_span.unwrap();
|
let path_span = path_span.unwrap();
|
||||||
// path_span is only present in the case of closure capture
|
// path_span is only present in the case of closure capture
|
||||||
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
|
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
|
||||||
if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) {
|
if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) {
|
||||||
let path_label = "used here by closure";
|
let path_label = "used here by closure";
|
||||||
let capture_kind_label = message;
|
let capture_kind_label = message;
|
||||||
err.span_label(
|
err.span_label(
|
||||||
|
@ -224,12 +224,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
if info.tail_result_is_ignored {
|
if info.tail_result_is_ignored {
|
||||||
// #85581: If the first mutable borrow's scope contains
|
// #85581: If the first mutable borrow's scope contains
|
||||||
// the second borrow, this suggestion isn't helpful.
|
// the second borrow, this suggestion isn't helpful.
|
||||||
if !multiple_borrow_span
|
if !multiple_borrow_span.is_some_and(|(old, new)| {
|
||||||
.map(|(old, new)| {
|
old.to(info.span.shrink_to_hi()).contains(new)
|
||||||
old.to(info.span.shrink_to_hi()).contains(new)
|
}) {
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
info.span.shrink_to_hi(),
|
info.span.shrink_to_hi(),
|
||||||
"consider adding semicolon after the expression so its \
|
"consider adding semicolon after the expression so its \
|
||||||
|
|
|
@ -1156,7 +1156,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
ty::Adt(def, ..) => Some(def.did()),
|
ty::Adt(def, ..) => Some(def.did()),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
|
let is_option_or_result = parent_self_ty.is_some_and(|def_id| {
|
||||||
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
|
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
|
||||||
});
|
});
|
||||||
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
||||||
|
|
|
@ -289,8 +289,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
.body
|
.body
|
||||||
.local_decls
|
.local_decls
|
||||||
.get(local)
|
.get(local)
|
||||||
.map(|l| mut_borrow_of_mutable_ref(l, self.local_names[local]))
|
.is_some_and(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) =>
|
||||||
.unwrap_or(false) =>
|
|
||||||
{
|
{
|
||||||
let decl = &self.body.local_decls[local];
|
let decl = &self.body.local_decls[local];
|
||||||
err.span_label(span, format!("cannot {act}"));
|
err.span_label(span, format!("cannot {act}"));
|
||||||
|
@ -443,7 +442,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(span)
|
.span_to_snippet(span)
|
||||||
.map_or(false, |snippet| snippet.starts_with("&mut ")) =>
|
.is_ok_and(|snippet| snippet.starts_with("&mut ")) =>
|
||||||
{
|
{
|
||||||
err.span_label(span, format!("cannot {act}"));
|
err.span_label(span, format!("cannot {act}"));
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
|
|
@ -125,8 +125,7 @@ impl OutlivesSuggestionBuilder {
|
||||||
|(r, _)| {
|
|(r, _)| {
|
||||||
self.constraints_to_add
|
self.constraints_to_add
|
||||||
.get(r)
|
.get(r)
|
||||||
.map(|r_outlived| r_outlived.as_slice().contains(fr))
|
.is_some_and(|r_outlived| r_outlived.as_slice().contains(fr))
|
||||||
.unwrap_or(false)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ use crate::session_diagnostics::VarNeedNotMut;
|
||||||
use self::diagnostics::{AccessKind, RegionName};
|
use self::diagnostics::{AccessKind, RegionName};
|
||||||
use self::location::LocationTable;
|
use self::location::LocationTable;
|
||||||
use self::prefixes::PrefixSet;
|
use self::prefixes::PrefixSet;
|
||||||
use facts::AllFacts;
|
use consumers::{BodyWithBorrowckFacts, ConsumerOptions};
|
||||||
|
|
||||||
use self::path_utils::*;
|
use self::path_utils::*;
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
||||||
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
|
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
|
||||||
let input_body: &Body<'_> = &input_body.borrow();
|
let input_body: &Body<'_> = &input_body.borrow();
|
||||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||||
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0;
|
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
|
||||||
debug!("mir_borrowck done");
|
debug!("mir_borrowck done");
|
||||||
|
|
||||||
tcx.arena.alloc(opt_closure_req)
|
tcx.arena.alloc(opt_closure_req)
|
||||||
|
@ -151,15 +151,15 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
||||||
|
|
||||||
/// Perform the actual borrow checking.
|
/// Perform the actual borrow checking.
|
||||||
///
|
///
|
||||||
/// If `return_body_with_facts` is true, then return the body with non-erased
|
/// Use `consumer_options: None` for the default behavior of returning
|
||||||
/// region ids on which the borrow checking was performed together with Polonius
|
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
|
||||||
/// facts.
|
/// to the given [`ConsumerOptions`].
|
||||||
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
|
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
|
||||||
fn do_mir_borrowck<'tcx>(
|
fn do_mir_borrowck<'tcx>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
input_body: &Body<'tcx>,
|
input_body: &Body<'tcx>,
|
||||||
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||||
return_body_with_facts: bool,
|
consumer_options: Option<ConsumerOptions>,
|
||||||
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
|
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
|
||||||
let def = input_body.source.def_id().expect_local();
|
let def = input_body.source.def_id().expect_local();
|
||||||
debug!(?def);
|
debug!(?def);
|
||||||
|
@ -240,8 +240,6 @@ fn do_mir_borrowck<'tcx>(
|
||||||
let borrow_set =
|
let borrow_set =
|
||||||
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
|
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
|
||||||
|
|
||||||
let use_polonius = return_body_with_facts || infcx.tcx.sess.opts.unstable_opts.polonius;
|
|
||||||
|
|
||||||
// Compute non-lexical lifetimes.
|
// Compute non-lexical lifetimes.
|
||||||
let nll::NllOutput {
|
let nll::NllOutput {
|
||||||
regioncx,
|
regioncx,
|
||||||
|
@ -261,7 +259,7 @@ fn do_mir_borrowck<'tcx>(
|
||||||
&mdpe.move_data,
|
&mdpe.move_data,
|
||||||
&borrow_set,
|
&borrow_set,
|
||||||
&upvars,
|
&upvars,
|
||||||
use_polonius,
|
consumer_options,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Dump MIR results into a file, if that is enabled. This let us
|
// Dump MIR results into a file, if that is enabled. This let us
|
||||||
|
@ -441,13 +439,16 @@ fn do_mir_borrowck<'tcx>(
|
||||||
tainted_by_errors,
|
tainted_by_errors,
|
||||||
};
|
};
|
||||||
|
|
||||||
let body_with_facts = if return_body_with_facts {
|
let body_with_facts = if consumer_options.is_some() {
|
||||||
let output_facts = mbcx.polonius_output.expect("Polonius output was not computed");
|
let output_facts = mbcx.polonius_output;
|
||||||
Some(Box::new(BodyWithBorrowckFacts {
|
Some(Box::new(BodyWithBorrowckFacts {
|
||||||
body: body_owned,
|
body: body_owned,
|
||||||
input_facts: *polonius_input.expect("Polonius input facts were not generated"),
|
promoted,
|
||||||
|
borrow_set,
|
||||||
|
region_inference_context: regioncx,
|
||||||
|
location_table: polonius_input.as_ref().map(|_| location_table_owned),
|
||||||
|
input_facts: polonius_input,
|
||||||
output_facts,
|
output_facts,
|
||||||
location_table: location_table_owned,
|
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -458,22 +459,6 @@ fn do_mir_borrowck<'tcx>(
|
||||||
(result, body_with_facts)
|
(result, body_with_facts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `Body` with information computed by the borrow checker. This struct is
|
|
||||||
/// intended to be consumed by compiler consumers.
|
|
||||||
///
|
|
||||||
/// We need to include the MIR body here because the region identifiers must
|
|
||||||
/// match the ones in the Polonius facts.
|
|
||||||
pub struct BodyWithBorrowckFacts<'tcx> {
|
|
||||||
/// A mir body that contains region identifiers.
|
|
||||||
pub body: Body<'tcx>,
|
|
||||||
/// Polonius input facts.
|
|
||||||
pub input_facts: AllFacts,
|
|
||||||
/// Polonius output facts.
|
|
||||||
pub output_facts: Rc<self::nll::PoloniusOutput>,
|
|
||||||
/// The table that maps Polonius points to locations in the table.
|
|
||||||
pub location_table: LocationTable,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BorrowckInferCtxt<'cx, 'tcx> {
|
pub struct BorrowckInferCtxt<'cx, 'tcx> {
|
||||||
pub(crate) infcx: &'cx InferCtxt<'tcx>,
|
pub(crate) infcx: &'cx InferCtxt<'tcx>,
|
||||||
pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
|
pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
|
||||||
|
|
|
@ -27,6 +27,7 @@ use rustc_mir_dataflow::ResultsCursor;
|
||||||
use crate::{
|
use crate::{
|
||||||
borrow_set::BorrowSet,
|
borrow_set::BorrowSet,
|
||||||
constraint_generation,
|
constraint_generation,
|
||||||
|
consumers::ConsumerOptions,
|
||||||
diagnostics::RegionErrors,
|
diagnostics::RegionErrors,
|
||||||
facts::{AllFacts, AllFactsExt, RustcFacts},
|
facts::{AllFacts, AllFactsExt, RustcFacts},
|
||||||
invalidation,
|
invalidation,
|
||||||
|
@ -165,10 +166,14 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
borrow_set: &BorrowSet<'tcx>,
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
upvars: &[Upvar<'tcx>],
|
upvars: &[Upvar<'tcx>],
|
||||||
use_polonius: bool,
|
consumer_options: Option<ConsumerOptions>,
|
||||||
) -> NllOutput<'tcx> {
|
) -> NllOutput<'tcx> {
|
||||||
|
let polonius_input = consumer_options.map(|c| c.polonius_input()).unwrap_or_default()
|
||||||
|
|| infcx.tcx.sess.opts.unstable_opts.polonius;
|
||||||
|
let polonius_output = consumer_options.map(|c| c.polonius_output()).unwrap_or_default()
|
||||||
|
|| infcx.tcx.sess.opts.unstable_opts.polonius;
|
||||||
let mut all_facts =
|
let mut all_facts =
|
||||||
(use_polonius || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default());
|
(polonius_input || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default());
|
||||||
|
|
||||||
let universal_regions = Rc::new(universal_regions);
|
let universal_regions = Rc::new(universal_regions);
|
||||||
|
|
||||||
|
@ -189,7 +194,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
move_data,
|
move_data,
|
||||||
elements,
|
elements,
|
||||||
upvars,
|
upvars,
|
||||||
use_polonius,
|
polonius_input,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(all_facts) = &mut all_facts {
|
if let Some(all_facts) = &mut all_facts {
|
||||||
|
@ -284,7 +289,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
all_facts.write_to_dir(dir_path, location_table).unwrap();
|
all_facts.write_to_dir(dir_path, location_table).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if use_polonius {
|
if polonius_output {
|
||||||
let algorithm =
|
let algorithm =
|
||||||
env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid"));
|
env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid"));
|
||||||
let algorithm = Algorithm::from_str(&algorithm).unwrap();
|
let algorithm = Algorithm::from_str(&algorithm).unwrap();
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_middle::mir::{Body, Mutability, Place};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
|
||||||
/// Extension methods for the `Place` type.
|
/// Extension methods for the `Place` type.
|
||||||
pub(crate) trait PlaceExt<'tcx> {
|
pub trait PlaceExt<'tcx> {
|
||||||
/// Returns `true` if we can safely ignore borrows of this place.
|
/// Returns `true` if we can safely ignore borrows of this place.
|
||||||
/// This is true whenever there is no action that the user can do
|
/// This is true whenever there is no action that the user can do
|
||||||
/// to the place `self` that would invalidate the borrow. This is true
|
/// to the place `self` that would invalidate the borrow. This is true
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::iter;
|
||||||
/// being run in the calling context, the conservative choice is to assume the compared indices
|
/// being run in the calling context, the conservative choice is to assume the compared indices
|
||||||
/// are disjoint (and therefore, do not overlap).
|
/// are disjoint (and therefore, do not overlap).
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub(crate) enum PlaceConflictBias {
|
pub enum PlaceConflictBias {
|
||||||
Overlap,
|
Overlap,
|
||||||
NoOverlap,
|
NoOverlap,
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ pub(crate) enum PlaceConflictBias {
|
||||||
/// Helper function for checking if places conflict with a mutable borrow and deep access depth.
|
/// Helper function for checking if places conflict with a mutable borrow and deep access depth.
|
||||||
/// This is used to check for places conflicting outside of the borrow checking code (such as in
|
/// This is used to check for places conflicting outside of the borrow checking code (such as in
|
||||||
/// dataflow).
|
/// dataflow).
|
||||||
pub(crate) fn places_conflict<'tcx>(
|
pub fn places_conflict<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
borrow_place: Place<'tcx>,
|
borrow_place: Place<'tcx>,
|
||||||
|
|
|
@ -585,6 +585,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
self.universal_regions.to_region_vid(r)
|
self.universal_regions.to_region_vid(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all the outlives constraints.
|
||||||
|
pub fn outlives_constraints(&self) -> impl Iterator<Item = OutlivesConstraint<'tcx>> + '_ {
|
||||||
|
self.constraints.outlives().iter().copied()
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
|
/// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
|
||||||
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
||||||
self.universal_regions.annotate(tcx, err)
|
self.universal_regions.annotate(tcx, err)
|
||||||
|
@ -712,7 +717,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
#[instrument(skip(self, _body), level = "debug")]
|
#[instrument(skip(self, _body), level = "debug")]
|
||||||
fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
|
fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
|
||||||
debug!("constraints={:#?}", {
|
debug!("constraints={:#?}", {
|
||||||
let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
|
let mut constraints: Vec<_> = self.outlives_constraints().collect();
|
||||||
constraints.sort_by_key(|c| (c.sup, c.sub));
|
constraints.sort_by_key(|c| (c.sup, c.sub));
|
||||||
constraints
|
constraints
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -159,7 +159,7 @@ impl<N: Idx> LivenessValues<N> {
|
||||||
/// Returns `true` if the region `r` contains the given element.
|
/// Returns `true` if the region `r` contains the given element.
|
||||||
pub(crate) fn contains(&self, row: N, location: Location) -> bool {
|
pub(crate) fn contains(&self, row: N, location: Location) -> bool {
|
||||||
let index = self.elements.point_from_location(location);
|
let index = self.elements.point_from_location(location);
|
||||||
self.points.row(row).map_or(false, |r| r.contains(index))
|
self.points.row(row).is_some_and(|r| r.contains(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator of all the elements contained by the region `r`
|
/// Returns an iterator of all the elements contained by the region `r`
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_infer::infer::{canonical::Canonical, InferOk};
|
use rustc_infer::infer::canonical::Canonical;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
|
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
|
||||||
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
||||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
use rustc_trait_selection::traits::ObligationCause;
|
||||||
|
|
||||||
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
|
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
|
||||||
|
|
||||||
|
@ -219,20 +219,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
let cause = ObligationCause::dummy_with_span(span);
|
let cause = ObligationCause::dummy_with_span(span);
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
let op = |infcx: &'_ _| {
|
|
||||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
|
||||||
let user_ty = ocx.normalize(&cause, param_env, user_ty);
|
|
||||||
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
|
|
||||||
if !ocx.select_all_or_error().is_empty() {
|
|
||||||
return Err(NoSolution);
|
|
||||||
}
|
|
||||||
Ok(InferOk { value: (), obligations: vec![] })
|
|
||||||
};
|
|
||||||
|
|
||||||
self.fully_perform_op(
|
self.fully_perform_op(
|
||||||
Locations::All(span),
|
Locations::All(span),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
type_op::custom::CustomTypeOp::new(op, || "ascribe_user_type_skip_wf".to_string()),
|
type_op::custom::CustomTypeOp::new(
|
||||||
|
|ocx| {
|
||||||
|
let user_ty = ocx.normalize(&cause, param_env, user_ty);
|
||||||
|
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
"ascribe_user_type_skip_wf",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
|
|
|
@ -20,7 +20,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
||||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{
|
use rustc_infer::infer::{
|
||||||
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
InferCtxt, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
||||||
};
|
};
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
||||||
|
@ -211,16 +211,16 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
Locations::All(body.span),
|
Locations::All(body.span),
|
||||||
ConstraintCategory::OpaqueType,
|
ConstraintCategory::OpaqueType,
|
||||||
CustomTypeOp::new(
|
CustomTypeOp::new(
|
||||||
|infcx| {
|
|ocx| {
|
||||||
infcx.register_member_constraints(
|
ocx.infcx.register_member_constraints(
|
||||||
param_env,
|
param_env,
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
decl.hidden_type.ty,
|
decl.hidden_type.ty,
|
||||||
decl.hidden_type.span,
|
decl.hidden_type.span,
|
||||||
);
|
);
|
||||||
Ok(InferOk { value: (), obligations: vec![] })
|
Ok(())
|
||||||
},
|
},
|
||||||
|| "opaque_type_map".to_string(),
|
"opaque_type_map",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -2695,8 +2695,9 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
|
||||||
type ErrorInfo = InstantiateOpaqueType<'tcx>;
|
type ErrorInfo = InstantiateOpaqueType<'tcx>;
|
||||||
|
|
||||||
fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
||||||
let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
|
let (mut output, region_constraints) = scrape_region_constraints(infcx, |ocx| {
|
||||||
Ok(InferOk { value: (), obligations: self.obligations.clone() })
|
ocx.register_obligations(self.obligations.clone());
|
||||||
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
self.region_constraints = Some(region_constraints);
|
self.region_constraints = Some(region_constraints);
|
||||||
output.error_info = Some(self);
|
output.error_info = Some(self);
|
||||||
|
|
|
@ -185,17 +185,25 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||||
self.type_checker
|
match self.type_checker.fully_perform_op(
|
||||||
.fully_perform_op(
|
self.locations,
|
||||||
self.locations,
|
self.category,
|
||||||
self.category,
|
InstantiateOpaqueType {
|
||||||
InstantiateOpaqueType {
|
obligations,
|
||||||
obligations,
|
// These fields are filled in during execution of the operation
|
||||||
// These fields are filled in during execution of the operation
|
base_universe: None,
|
||||||
base_universe: None,
|
region_constraints: None,
|
||||||
region_constraints: None,
|
},
|
||||||
},
|
) {
|
||||||
)
|
Ok(()) => {}
|
||||||
.unwrap();
|
Err(_) => {
|
||||||
|
// It's a bit redundant to delay a bug here, but I'd rather
|
||||||
|
// delay more bugs than accidentally not delay a bug at all.
|
||||||
|
self.type_checker.tcx().sess.delay_span_bug(
|
||||||
|
self.locations.span(self.type_checker.body),
|
||||||
|
"errors selecting obligation during MIR typeck",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ impl<'ast> visit::Visitor<'ast> for CfgFinder {
|
||||||
self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
|
self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
|
||||||
|| attr
|
|| attr
|
||||||
.ident()
|
.ident()
|
||||||
.map_or(false, |ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
|
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -432,11 +432,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
let is_cold = if fn_sig.abi() == Abi::RustCold {
|
let is_cold = if fn_sig.abi() == Abi::RustCold {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
instance
|
instance.is_some_and(|inst| {
|
||||||
.map(|inst| {
|
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
|
||||||
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
|
})
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
};
|
};
|
||||||
if is_cold {
|
if is_cold {
|
||||||
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
||||||
|
@ -470,7 +468,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pass the caller location for `#[track_caller]`.
|
// Pass the caller location for `#[track_caller]`.
|
||||||
if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) {
|
if instance.is_some_and(|inst| inst.def.requires_caller_location(fx.tcx)) {
|
||||||
let caller_location = fx.get_caller_location(source_info);
|
let caller_location = fx.get_caller_location(source_info);
|
||||||
args.push(CallArgument { value: caller_location, is_owned: false });
|
args.push(CallArgument { value: caller_location, is_owned: false });
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,11 +630,11 @@ fn codegen_stmt<'tcx>(
|
||||||
let to_ty = fx.monomorphize(to_ty);
|
let to_ty = fx.monomorphize(to_ty);
|
||||||
|
|
||||||
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
ty.builtin_deref(true)
|
ty.builtin_deref(true).is_some_and(
|
||||||
.map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| {
|
|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| {
|
||||||
has_ptr_meta(fx.tcx, pointee_ty)
|
has_ptr_meta(fx.tcx, pointee_ty)
|
||||||
})
|
},
|
||||||
.unwrap_or(false)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_fat_ptr(fx, from_ty) {
|
if is_fat_ptr(fx, from_ty) {
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl CoverageMapGenerator {
|
||||||
counter_regions.sort_unstable_by_key(|(_counter, region)| *region);
|
counter_regions.sort_unstable_by_key(|(_counter, region)| *region);
|
||||||
for (counter, region) in counter_regions {
|
for (counter, region) in counter_regions {
|
||||||
let CodeRegion { file_name, start_line, start_col, end_line, end_col } = *region;
|
let CodeRegion { file_name, start_line, start_col, end_line, end_col } = *region;
|
||||||
let same_file = current_file_name.map_or(false, |p| p == file_name);
|
let same_file = current_file_name.is_some_and(|p| p == file_name);
|
||||||
if !same_file {
|
if !same_file {
|
||||||
if current_file_name.is_some() {
|
if current_file_name.is_some() {
|
||||||
current_file_id += 1;
|
current_file_id += 1;
|
||||||
|
|
|
@ -125,8 +125,7 @@ impl CodegenCx<'_, '_> {
|
||||||
|
|
||||||
// Thread-local variables generally don't support copy relocations.
|
// Thread-local variables generally don't support copy relocations.
|
||||||
let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
|
let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
|
||||||
.map(|v| llvm::LLVMIsThreadLocal(v) == llvm::True)
|
.is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
|
||||||
.unwrap_or(false);
|
|
||||||
if is_thread_local_var {
|
if is_thread_local_var {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1031,7 +1031,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let needs_location =
|
let needs_location =
|
||||||
instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx()));
|
instance.is_some_and(|i| i.def.requires_caller_location(self.cx.tcx()));
|
||||||
if needs_location {
|
if needs_location {
|
||||||
let mir_args = if let Some(num_untupled) = num_untupled {
|
let mir_args = if let Some(num_untupled) = num_untupled {
|
||||||
first_args.len() + num_untupled
|
first_args.len() + num_untupled
|
||||||
|
|
|
@ -944,7 +944,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
|
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
|
||||||
};
|
};
|
||||||
let feature_gate_declared = gate_declared(gate);
|
let feature_gate_declared = gate_declared(gate);
|
||||||
let implied_gate_declared = implied_by.map(gate_declared).unwrap_or(false);
|
let implied_gate_declared = implied_by.is_some_and(gate_declared);
|
||||||
if !feature_gate_declared && !implied_gate_declared {
|
if !feature_gate_declared && !implied_gate_declared {
|
||||||
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
|
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
|
||||||
return;
|
return;
|
||||||
|
@ -971,7 +971,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
// have no `rustc_const_stable` attributes to be const-unstable as well. This
|
// have no `rustc_const_stable` attributes to be const-unstable as well. This
|
||||||
// should be fixed later.
|
// should be fixed later.
|
||||||
let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none()
|
let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none()
|
||||||
&& tcx.lookup_stability(callee).map_or(false, |s| s.is_unstable());
|
&& tcx.lookup_stability(callee).is_some_and(|s| s.is_unstable());
|
||||||
if callee_is_unstable_unmarked {
|
if callee_is_unstable_unmarked {
|
||||||
trace!("callee_is_unstable_unmarked");
|
trace!("callee_is_unstable_unmarked");
|
||||||
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
|
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
|
||||||
|
|
|
@ -139,5 +139,5 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.lookup_const_stability(parent.owner).map_or(false, |stab| stab.is_const_stable())
|
tcx.lookup_const_stability(parent.owner).is_some_and(|stab| stab.is_const_stable())
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,7 +366,7 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
&& self
|
&& self
|
||||||
.error_cache
|
.error_cache
|
||||||
.get(&obligation_tree_id)
|
.get(&obligation_tree_id)
|
||||||
.map_or(false, |errors| errors.contains(v.key()));
|
.is_some_and(|errors| errors.contains(v.key()));
|
||||||
|
|
||||||
if already_failed {
|
if already_failed {
|
||||||
Err(())
|
Err(())
|
||||||
|
|
|
@ -1315,7 +1315,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
|
||||||
}
|
}
|
||||||
|
|
||||||
// If backtraces are enabled, also print the query stack
|
// If backtraces are enabled, also print the query stack
|
||||||
let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0");
|
let backtrace = env::var_os("RUST_BACKTRACE").is_some_and(|x| &x != "0");
|
||||||
|
|
||||||
let num_frames = if backtrace { None } else { Some(2) };
|
let num_frames = if backtrace { None } else { Some(2) };
|
||||||
|
|
||||||
|
|
|
@ -285,15 +285,11 @@ pub trait Emitter: Translate {
|
||||||
format!(
|
format!(
|
||||||
"help: {}{}: `{}`",
|
"help: {}{}: `{}`",
|
||||||
&msg,
|
&msg,
|
||||||
if self
|
if self.source_map().is_some_and(|sm| is_case_difference(
|
||||||
.source_map()
|
sm,
|
||||||
.map(|sm| is_case_difference(
|
substitution,
|
||||||
sm,
|
sugg.substitutions[0].parts[0].span,
|
||||||
substitution,
|
)) {
|
||||||
sugg.substitutions[0].parts[0].span,
|
|
||||||
))
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
" (notice the capitalization)"
|
" (notice the capitalization)"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
|
|
@ -1437,7 +1437,7 @@ impl HandlerInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn treat_err_as_bug(&self) -> bool {
|
fn treat_err_as_bug(&self) -> bool {
|
||||||
self.flags.treat_err_as_bug.map_or(false, |c| {
|
self.flags.treat_err_as_bug.is_some_and(|c| {
|
||||||
self.err_count() + self.lint_err_count + self.delayed_bug_count() >= c.get()
|
self.err_count() + self.lint_err_count + self.delayed_bug_count() >= c.get()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1603,7 +1603,7 @@ impl HandlerInner {
|
||||||
// This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before
|
// This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before
|
||||||
// incrementing `err_count` by one, so we need to +1 the comparing.
|
// incrementing `err_count` by one, so we need to +1 the comparing.
|
||||||
// FIXME: Would be nice to increment err_count in a more coherent way.
|
// FIXME: Would be nice to increment err_count in a more coherent way.
|
||||||
if self.flags.treat_err_as_bug.map_or(false, |c| {
|
if self.flags.treat_err_as_bug.is_some_and(|c| {
|
||||||
self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get()
|
self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get()
|
||||||
}) {
|
}) {
|
||||||
// FIXME: don't abort here if report_delayed_bugs is off
|
// FIXME: don't abort here if report_delayed_bugs is off
|
||||||
|
|
|
@ -780,7 +780,7 @@ impl SyntaxExtension {
|
||||||
let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe);
|
let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe);
|
||||||
let local_inner_macros = attr::find_by_name(attrs, sym::macro_export)
|
let local_inner_macros = attr::find_by_name(attrs, sym::macro_export)
|
||||||
.and_then(|macro_export| macro_export.meta_item_list())
|
.and_then(|macro_export| macro_export.meta_item_list())
|
||||||
.map_or(false, |l| attr::list_contains_name(&l, sym::local_inner_macros));
|
.is_some_and(|l| attr::list_contains_name(&l, sym::local_inner_macros));
|
||||||
let collapse_debuginfo = attr::contains_name(attrs, sym::collapse_debuginfo);
|
let collapse_debuginfo = attr::contains_name(attrs, sym::collapse_debuginfo);
|
||||||
tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
|
tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
|
||||||
|
|
||||||
|
@ -1449,7 +1449,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
|
||||||
&& version
|
&& version
|
||||||
.next()
|
.next()
|
||||||
.and_then(|c| c.parse::<u32>().ok())
|
.and_then(|c| c.parse::<u32>().ok())
|
||||||
.map_or(false, |v| v < 6)
|
.is_some_and(|v| v < 6)
|
||||||
};
|
};
|
||||||
|
|
||||||
if crate_matches {
|
if crate_matches {
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
cfg_pos = Some(pos); // a cfg attr found, no need to search anymore
|
cfg_pos = Some(pos); // a cfg attr found, no need to search anymore
|
||||||
break;
|
break;
|
||||||
} else if attr_pos.is_none()
|
} else if attr_pos.is_none()
|
||||||
&& !name.map_or(false, rustc_feature::is_builtin_attr_name)
|
&& !name.is_some_and(rustc_feature::is_builtin_attr_name)
|
||||||
{
|
{
|
||||||
attr_pos = Some(pos); // a non-cfg attr found, still may find a cfg attr
|
attr_pos = Some(pos); // a non-cfg attr found, still may find a cfg attr
|
||||||
}
|
}
|
||||||
|
@ -1647,7 +1647,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
|
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
|
||||||
span = Some(current_span);
|
span = Some(current_span);
|
||||||
|
|
||||||
if attrs.peek().map_or(false, |next_attr| next_attr.doc_str().is_some()) {
|
if attrs.peek().is_some_and(|next_attr| next_attr.doc_str().is_some()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1950,6 +1950,6 @@ impl<'feat> ExpansionConfig<'feat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proc_macro_hygiene(&self) -> bool {
|
fn proc_macro_hygiene(&self) -> bool {
|
||||||
self.features.map_or(false, |features| features.proc_macro_hygiene)
|
self.features.is_some_and(|features| features.proc_macro_hygiene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -861,11 +861,11 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool {
|
||||||
/// Whether this builtin attribute is only used in the local crate.
|
/// Whether this builtin attribute is only used in the local crate.
|
||||||
/// If so, it is not encoded in the crate metadata.
|
/// If so, it is not encoded in the crate metadata.
|
||||||
pub fn is_builtin_only_local(name: Symbol) -> bool {
|
pub fn is_builtin_only_local(name: Symbol) -> bool {
|
||||||
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
|
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.only_local)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_valid_for_get_attr(name: Symbol) -> bool {
|
pub fn is_valid_for_get_attr(name: Symbol) -> bool {
|
||||||
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| match attr.duplicates {
|
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates {
|
||||||
WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
|
WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
|
||||||
| FutureWarnPreceding => true,
|
| FutureWarnPreceding => true,
|
||||||
DuplicatesOk | WarnFollowingWordOnly => false,
|
DuplicatesOk | WarnFollowingWordOnly => false,
|
||||||
|
|
|
@ -84,14 +84,13 @@ impl UnstableFeatures {
|
||||||
pub fn from_environment(krate: Option<&str>) -> Self {
|
pub fn from_environment(krate: Option<&str>) -> Self {
|
||||||
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
|
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
|
||||||
let disable_unstable_features =
|
let disable_unstable_features =
|
||||||
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").map(|s| s != "0").unwrap_or(false);
|
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
|
||||||
// Returns whether `krate` should be counted as unstable
|
// Returns whether `krate` should be counted as unstable
|
||||||
let is_unstable_crate = |var: &str| {
|
let is_unstable_crate =
|
||||||
krate.map_or(false, |name| var.split(',').any(|new_krate| new_krate == name))
|
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
|
||||||
};
|
|
||||||
// `true` if we should enable unstable features for bootstrapping.
|
// `true` if we should enable unstable features for bootstrapping.
|
||||||
let bootstrap = std::env::var("RUSTC_BOOTSTRAP")
|
let bootstrap =
|
||||||
.map_or(false, |var| var == "1" || is_unstable_crate(&var));
|
std::env::var("RUSTC_BOOTSTRAP").is_ok_and(|var| var == "1" || is_unstable_crate(&var));
|
||||||
match (disable_unstable_features, bootstrap) {
|
match (disable_unstable_features, bootstrap) {
|
||||||
(_, true) => UnstableFeatures::Cheat,
|
(_, true) => UnstableFeatures::Cheat,
|
||||||
(true, _) => UnstableFeatures::Disallow,
|
(true, _) => UnstableFeatures::Disallow,
|
||||||
|
|
|
@ -787,7 +787,7 @@ pub struct WhereBoundPredicate<'hir> {
|
||||||
impl<'hir> WhereBoundPredicate<'hir> {
|
impl<'hir> WhereBoundPredicate<'hir> {
|
||||||
/// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
|
/// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
|
||||||
pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
|
pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
|
||||||
self.bounded_ty.as_generic_param().map_or(false, |(def_id, _)| def_id == param_def_id)
|
self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2625,7 +2625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&& tcx.all_impls(*trait_def_id)
|
&& tcx.all_impls(*trait_def_id)
|
||||||
.any(|impl_def_id| {
|
.any(|impl_def_id| {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||||
trait_ref.map_or(false, |trait_ref| {
|
trait_ref.is_some_and(|trait_ref| {
|
||||||
let impl_ = trait_ref.subst(
|
let impl_ = trait_ref.subst(
|
||||||
tcx,
|
tcx,
|
||||||
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
|
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
|
||||||
|
@ -3654,7 +3654,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
..
|
..
|
||||||
}) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
|
}) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
|
||||||
{
|
{
|
||||||
if !of_trait_ref.trait_def_id().map_or(false, |def_id| def_id.is_local()) {
|
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let of_trait_span = of_trait_ref.path.span;
|
let of_trait_span = of_trait_ref.path.span;
|
||||||
|
@ -3693,7 +3693,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_prev_source(self_ty.span)
|
.span_to_prev_source(self_ty.span)
|
||||||
.ok()
|
.ok()
|
||||||
.map_or(false, |s| s.trim_end().ends_with('<'));
|
.is_some_and(|s| s.trim_end().ends_with('<'));
|
||||||
|
|
||||||
let is_global = poly_trait_ref.trait_ref.path.is_global();
|
let is_global = poly_trait_ref.trait_ref.path.is_global();
|
||||||
|
|
||||||
|
|
|
@ -800,16 +800,15 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
|
|
||||||
let is_implemented = leaf_def
|
let is_implemented = leaf_def
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |node_item| node_item.item.defaultness(tcx).has_value());
|
.is_some_and(|node_item| node_item.item.defaultness(tcx).has_value());
|
||||||
|
|
||||||
if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
|
if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
|
||||||
missing_items.push(tcx.associated_item(trait_item_id));
|
missing_items.push(tcx.associated_item(trait_item_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// true if this item is specifically implemented in this impl
|
// true if this item is specifically implemented in this impl
|
||||||
let is_implemented_here = leaf_def
|
let is_implemented_here =
|
||||||
.as_ref()
|
leaf_def.as_ref().is_some_and(|node_item| !node_item.defining_node.is_from_trait());
|
||||||
.map_or(false, |node_item| !node_item.defining_node.is_from_trait());
|
|
||||||
|
|
||||||
if !is_implemented_here {
|
if !is_implemented_here {
|
||||||
let full_impl_span =
|
let full_impl_span =
|
||||||
|
@ -1082,8 +1081,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
let layout = tcx.layout_of(param_env.and(ty));
|
let layout = tcx.layout_of(param_env.and(ty));
|
||||||
// We are currently checking the type this field came from, so it must be local
|
// We are currently checking the type this field came from, so it must be local
|
||||||
let span = tcx.hir().span_if_local(field.did).unwrap();
|
let span = tcx.hir().span_if_local(field.did).unwrap();
|
||||||
let zst = layout.map_or(false, |layout| layout.is_zst());
|
let zst = layout.is_ok_and(|layout| layout.is_zst());
|
||||||
let align1 = layout.map_or(false, |layout| layout.align.abi.bytes() == 1);
|
let align1 = layout.is_ok_and(|layout| layout.align.abi.bytes() == 1);
|
||||||
if !zst {
|
if !zst {
|
||||||
return (span, zst, align1, None);
|
return (span, zst, align1, None);
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||||
hir::ItemKind::Impl(impl_) => {
|
hir::ItemKind::Impl(impl_) => {
|
||||||
let is_auto = tcx
|
let is_auto = tcx
|
||||||
.impl_trait_ref(def_id)
|
.impl_trait_ref(def_id)
|
||||||
.map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id));
|
.is_some_and(|trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id));
|
||||||
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
|
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
|
||||||
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
|
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
|
||||||
let mut err =
|
let mut err =
|
||||||
|
|
|
@ -819,7 +819,7 @@ fn convert_variant(
|
||||||
recovered,
|
recovered,
|
||||||
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
||||||
|| variant_did
|
|| variant_did
|
||||||
.map_or(false, |variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
|
.is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,7 +1025,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
|
||||||
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
|
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
|
||||||
}
|
}
|
||||||
Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
|
Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
|
||||||
ty_opt.map_or(false, is_suggestable_infer_ty)
|
ty_opt.is_some_and(is_suggestable_infer_ty)
|
||||||
|| segments.iter().any(|segment| are_suggestable_generic_args(segment.args().args))
|
|| segments.iter().any(|segment| are_suggestable_generic_args(segment.args().args))
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -395,7 +395,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
) -> String {
|
) -> String {
|
||||||
let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(hir::Node::fn_sig);
|
let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(hir::Node::fn_sig);
|
||||||
let is_used_in_input = |def_id| {
|
let is_used_in_input = |def_id| {
|
||||||
fn_sig.map_or(false, |fn_sig| {
|
fn_sig.is_some_and(|fn_sig| {
|
||||||
fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
|
fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
|
||||||
hir::TyKind::Path(hir::QPath::Resolved(
|
hir::TyKind::Path(hir::QPath::Resolved(
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -465,7 +465,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(self.expr_span)
|
.span_to_snippet(self.expr_span)
|
||||||
.map_or(false, |snip| snip.starts_with('('));
|
.is_ok_and(|snip| snip.starts_with('('));
|
||||||
|
|
||||||
// Very crude check to see whether the expression must be wrapped
|
// Very crude check to see whether the expression must be wrapped
|
||||||
// in parentheses for the suggestion to work (issue #89497).
|
// in parentheses for the suggestion to work (issue #89497).
|
||||||
|
|
|
@ -1814,7 +1814,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
.span_to_snippet(return_sp)
|
.span_to_snippet(return_sp)
|
||||||
.unwrap_or_else(|_| "dyn Trait".to_string());
|
.unwrap_or_else(|_| "dyn Trait".to_string());
|
||||||
let mut snippet_iter = snippet.split_whitespace();
|
let mut snippet_iter = snippet.split_whitespace();
|
||||||
let has_impl = snippet_iter.next().map_or(false, |s| s == "impl");
|
let has_impl = snippet_iter.next().is_some_and(|s| s == "impl");
|
||||||
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
|
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
|
||||||
let mut is_object_safe = false;
|
let mut is_object_safe = false;
|
||||||
if let hir::FnRetTy::Return(ty) = fn_output
|
if let hir::FnRetTy::Return(ty) = fn_output
|
||||||
|
@ -1834,7 +1834,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
bound
|
bound
|
||||||
.trait_ref()
|
.trait_ref()
|
||||||
.and_then(|t| t.trait_def_id())
|
.and_then(|t| t.trait_def_id())
|
||||||
.map_or(false, |def_id| {
|
.is_some_and(|def_id| {
|
||||||
fcx.tcx.check_is_object_safe(def_id)
|
fcx.tcx.check_is_object_safe(def_id)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1748,8 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|err: &mut Diagnostic,
|
|err: &mut Diagnostic,
|
||||||
found_to_exp_is_fallible: bool,
|
found_to_exp_is_fallible: bool,
|
||||||
exp_to_found_is_fallible: bool| {
|
exp_to_found_is_fallible: bool| {
|
||||||
let exp_is_lhs =
|
let exp_is_lhs = expected_ty_expr.is_some_and(|e| self.tcx.hir().is_lhs(e.hir_id));
|
||||||
expected_ty_expr.map(|e| self.tcx.hir().is_lhs(e.hir_id)).unwrap_or(false);
|
|
||||||
|
|
||||||
if exp_is_lhs {
|
if exp_is_lhs {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -497,7 +497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.borrow()
|
.borrow()
|
||||||
.adjustments()
|
.adjustments()
|
||||||
.get(base.hir_id)
|
.get(base.hir_id)
|
||||||
.map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
|
.is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
|
||||||
});
|
});
|
||||||
if !is_named {
|
if !is_named {
|
||||||
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span });
|
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span });
|
||||||
|
|
|
@ -1017,8 +1017,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.typeck_results
|
.typeck_results
|
||||||
.borrow()
|
.borrow()
|
||||||
.expr_ty_adjusted_opt(rcvr)
|
.expr_ty_adjusted_opt(rcvr)
|
||||||
.and_then(|ty| expected.map(|expected_ty| expected_ty.peel_refs() == ty.peel_refs()))
|
.zip(expected)
|
||||||
.unwrap_or(false);
|
.is_some_and(|(ty, expected_ty)| expected_ty.peel_refs() == ty.peel_refs());
|
||||||
|
|
||||||
let prev_call_mutates_and_returns_unit = || {
|
let prev_call_mutates_and_returns_unit = || {
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
|
@ -1026,14 +1026,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.type_dependent_def_id(expr.hir_id)
|
.type_dependent_def_id(expr.hir_id)
|
||||||
.map(|def_id| self.tcx.fn_sig(def_id).skip_binder().skip_binder())
|
.map(|def_id| self.tcx.fn_sig(def_id).skip_binder().skip_binder())
|
||||||
.and_then(|sig| sig.inputs_and_output.split_last())
|
.and_then(|sig| sig.inputs_and_output.split_last())
|
||||||
.map(|(output, inputs)| {
|
.is_some_and(|(output, inputs)| {
|
||||||
output.is_unit()
|
output.is_unit()
|
||||||
&& inputs
|
&& inputs
|
||||||
.get(0)
|
.get(0)
|
||||||
.and_then(|self_ty| self_ty.ref_mutability())
|
.and_then(|self_ty| self_ty.ref_mutability())
|
||||||
.map_or(false, rustc_ast::Mutability::is_mut)
|
.is_some_and(rustc_ast::Mutability::is_mut)
|
||||||
})
|
})
|
||||||
.unwrap_or(false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !(rcvr_has_the_expected_type || prev_call_mutates_and_returns_unit()) {
|
if !(rcvr_has_the_expected_type || prev_call_mutates_and_returns_unit()) {
|
||||||
|
@ -1200,10 +1199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_self = path_segs
|
let has_self =
|
||||||
.last()
|
path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self);
|
||||||
.map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
|
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
|
||||||
let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).subst_identity());
|
let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).subst_identity());
|
||||||
|
|
|
@ -876,7 +876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut errors = errors.into_iter().peekable();
|
let mut errors = errors.into_iter().peekable();
|
||||||
let mut only_extras_so_far = errors
|
let mut only_extras_so_far = errors
|
||||||
.peek()
|
.peek()
|
||||||
.map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
|
.is_some_and(|first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
|
||||||
let mut suggestions = vec![];
|
let mut suggestions = vec![];
|
||||||
while let Some(error) = errors.next() {
|
while let Some(error) = errors.next() {
|
||||||
only_extras_so_far &= matches!(error, Error::Extra(_));
|
only_extras_so_far &= matches!(error, Error::Extra(_));
|
||||||
|
|
|
@ -193,7 +193,7 @@ impl DropRanges {
|
||||||
.get(&TrackedValue::Temporary(hir_id))
|
.get(&TrackedValue::Temporary(hir_id))
|
||||||
.or(self.tracked_value_map.get(&TrackedValue::Variable(hir_id)))
|
.or(self.tracked_value_map.get(&TrackedValue::Variable(hir_id)))
|
||||||
.cloned()
|
.cloned()
|
||||||
.map_or(false, |tracked_value_id| {
|
.is_some_and(|tracked_value_id| {
|
||||||
self.expect_node(location.into()).drop_state.contains(tracked_value_id)
|
self.expect_node(location.into()).drop_state.contains(tracked_value_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ impl<'tcx> Inherited<'tcx> {
|
||||||
// (*) binder skipped
|
// (*) binder skipped
|
||||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
|
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
|
||||||
&& let Some(ty) = self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t))
|
&& let Some(ty) = self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t))
|
||||||
&& self.tcx.lang_items().sized_trait().map_or(false, |st| st != tpred.trait_ref.def_id)
|
&& self.tcx.lang_items().sized_trait().is_some_and(|st| st != tpred.trait_ref.def_id)
|
||||||
{
|
{
|
||||||
let new_self_ty = self.tcx.types.unit;
|
let new_self_ty = self.tcx.types.unit;
|
||||||
|
|
||||||
|
|
|
@ -411,7 +411,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Res::Local(var_id) => {
|
Res::Local(var_id) => {
|
||||||
if self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) {
|
if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) {
|
||||||
self.cat_upvar(hir_id, var_id)
|
self.cat_upvar(hir_id, var_id)
|
||||||
} else {
|
} else {
|
||||||
Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
|
Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
|
||||||
|
|
|
@ -1194,7 +1194,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
pick.autoderefs += 1;
|
pick.autoderefs += 1;
|
||||||
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
|
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
|
||||||
mutbl,
|
mutbl,
|
||||||
unsize: pick.autoref_or_ptr_adjustment.map_or(false, |a| a.get_unsize()),
|
unsize: pick.autoref_or_ptr_adjustment.is_some_and(|a| a.get_unsize()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.map_or(false, |def_id| {
|
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
|
||||||
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
||||||
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
||||||
}) && item_name.name == Symbol::intern("write_fmt");
|
}) && item_name.name == Symbol::intern("write_fmt");
|
||||||
|
@ -1522,7 +1522,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let span_included = match parent_expr.kind {
|
let span_included = match parent_expr.kind {
|
||||||
hir::ExprKind::Struct(_, eps, _) => {
|
hir::ExprKind::Struct(_, eps, _) => {
|
||||||
eps.len() > 0 && eps.last().map_or(false, |ep| ep.span.contains(span))
|
eps.len() > 0 && eps.last().is_some_and(|ep| ep.span.contains(span))
|
||||||
}
|
}
|
||||||
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
||||||
hir::ExprKind::Call(ref func, ..) => func.span.contains(span),
|
hir::ExprKind::Call(ref func, ..) => func.span.contains(span),
|
||||||
|
@ -1781,7 +1781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ProbeScope::TraitsInScope,
|
ProbeScope::TraitsInScope,
|
||||||
return_type,
|
return_type,
|
||||||
)
|
)
|
||||||
.map_or(false, |pick| {
|
.is_ok_and(|pick| {
|
||||||
!never_mention_traits
|
!never_mention_traits
|
||||||
.iter()
|
.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -2468,7 +2468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// implement the `AsRef` trait.
|
// implement the `AsRef` trait.
|
||||||
let skip = skippable.contains(&did)
|
let skip = skippable.contains(&did)
|
||||||
|| (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
|
|| (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
|
||||||
|| inputs_len.map_or(false, |inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() != inputs_len);
|
|| inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() != inputs_len);
|
||||||
// Make sure the method is defined for the *actual* receiver: we don't
|
// Make sure the method is defined for the *actual* receiver: we don't
|
||||||
// want to treat `Box<Self>` as a receiver if it only works because of
|
// want to treat `Box<Self>` as a receiver if it only works because of
|
||||||
// an autoderef to `&self`
|
// an autoderef to `&self`
|
||||||
|
@ -2755,7 +2755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
|
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
|
||||||
let imp_simp =
|
let imp_simp =
|
||||||
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
|
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
|
||||||
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
|
imp_simp.is_some_and(|s| s == simp_rcvr_ty)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
explicitly_negative.push(candidate);
|
explicitly_negative.push(candidate);
|
||||||
|
@ -2893,7 +2893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Adt(def, _) => def.did().is_local(),
|
ty::Adt(def, _) => def.did().is_local(),
|
||||||
ty::Foreign(did) => did.is_local(),
|
ty::Foreign(did) => did.is_local(),
|
||||||
ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
|
ty::Dynamic(tr, ..) => tr.principal().is_some_and(|d| d.def_id().is_local()),
|
||||||
ty::Param(_) => true,
|
ty::Param(_) => true,
|
||||||
|
|
||||||
// Everything else (primitive types, etc.) is effectively
|
// Everything else (primitive types, etc.) is effectively
|
||||||
|
|
|
@ -549,9 +549,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let to_owned_msg = "create an owned `String` from a string reference";
|
let to_owned_msg = "create an owned `String` from a string reference";
|
||||||
|
|
||||||
let string_type = self.tcx.lang_items().string();
|
let string_type = self.tcx.lang_items().string();
|
||||||
let is_std_string = |ty: Ty<'tcx>| {
|
let is_std_string =
|
||||||
ty.ty_adt_def().map_or(false, |ty_def| Some(ty_def.did()) == string_type)
|
|ty: Ty<'tcx>| ty.ty_adt_def().is_some_and(|ty_def| Some(ty_def.did()) == string_type);
|
||||||
};
|
|
||||||
|
|
||||||
match (lhs_ty.kind(), rhs_ty.kind()) {
|
match (lhs_ty.kind(), rhs_ty.kind()) {
|
||||||
(&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str
|
(&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str
|
||||||
|
@ -760,8 +759,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
span,
|
span,
|
||||||
traits::BinOp {
|
traits::BinOp {
|
||||||
rhs_span: opt_rhs_expr.map(|expr| expr.span),
|
rhs_span: opt_rhs_expr.map(|expr| expr.span),
|
||||||
is_lit: opt_rhs_expr
|
is_lit: opt_rhs_expr.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||||
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
|
||||||
output_ty: expected.only_has_type(self),
|
output_ty: expected.only_has_type(self),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -329,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
|
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
|
||||||
// This helps avoid accidental drops.
|
// This helps avoid accidental drops.
|
||||||
if inside_union
|
if inside_union
|
||||||
&& source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
|
&& source.ty_adt_def().is_some_and(|adt| adt.is_manually_drop())
|
||||||
{
|
{
|
||||||
let mut err = self.tcx.sess.struct_span_err(
|
let mut err = self.tcx.sess.struct_span_err(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
|
|
@ -972,15 +972,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut obligations_should_hold = Vec::new();
|
let mut obligations_should_hold = Vec::new();
|
||||||
// Checks if a root variable implements any of the auto traits
|
// Checks if a root variable implements any of the auto traits
|
||||||
for check_trait in auto_traits_def_id.iter() {
|
for check_trait in auto_traits_def_id.iter() {
|
||||||
obligations_should_hold.push(
|
obligations_should_hold.push(check_trait.is_some_and(|check_trait| {
|
||||||
check_trait
|
self.infcx
|
||||||
.map(|check_trait| {
|
.type_implements_trait(check_trait, [ty], self.param_env)
|
||||||
self.infcx
|
.must_apply_modulo_regions()
|
||||||
.type_implements_trait(check_trait, [ty], self.param_env)
|
}));
|
||||||
.must_apply_modulo_regions()
|
|
||||||
})
|
|
||||||
.unwrap_or(false),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut problematic_captures = FxHashMap::default();
|
let mut problematic_captures = FxHashMap::default();
|
||||||
|
@ -996,15 +992,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Checks if a capture implements any of the auto traits
|
// Checks if a capture implements any of the auto traits
|
||||||
let mut obligations_holds_for_capture = Vec::new();
|
let mut obligations_holds_for_capture = Vec::new();
|
||||||
for check_trait in auto_traits_def_id.iter() {
|
for check_trait in auto_traits_def_id.iter() {
|
||||||
obligations_holds_for_capture.push(
|
obligations_holds_for_capture.push(check_trait.is_some_and(|check_trait| {
|
||||||
check_trait
|
self.infcx
|
||||||
.map(|check_trait| {
|
.type_implements_trait(check_trait, [ty], self.param_env)
|
||||||
self.infcx
|
.must_apply_modulo_regions()
|
||||||
.type_implements_trait(check_trait, [ty], self.param_env)
|
}));
|
||||||
.must_apply_modulo_regions()
|
|
||||||
})
|
|
||||||
.unwrap_or(false),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut capture_problems = FxHashSet::default();
|
let mut capture_problems = FxHashSet::default();
|
||||||
|
|
|
@ -1544,7 +1544,7 @@ impl<T: Idx> GrowableBitSet<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains(&self, elem: T) -> bool {
|
pub fn contains(&self, elem: T) -> bool {
|
||||||
let (word_index, mask) = word_index_and_mask(elem);
|
let (word_index, mask) = word_index_and_mask(elem);
|
||||||
self.bit_set.words.get(word_index).map_or(false, |word| (word & mask) != 0)
|
self.bit_set.words.get(word_index).is_some_and(|word| (word & mask) != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1818,7 +1818,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
|
||||||
/// if the matrix represents (transitive) reachability, can
|
/// if the matrix represents (transitive) reachability, can
|
||||||
/// `row` reach `column`?
|
/// `row` reach `column`?
|
||||||
pub fn contains(&self, row: R, column: C) -> bool {
|
pub fn contains(&self, row: R, column: C) -> bool {
|
||||||
self.row(row).map_or(false, |r| r.contains(column))
|
self.row(row).is_some_and(|r| r.contains(column))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the bits from row `read` to the bits from row `write`, and
|
/// Adds the bits from row `read` to the bits from row `write`, and
|
||||||
|
|
|
@ -248,7 +248,7 @@ impl<I: Idx> IntervalSet<I> {
|
||||||
fn check_invariants(&self) -> bool {
|
fn check_invariants(&self) -> bool {
|
||||||
let mut current: Option<u32> = None;
|
let mut current: Option<u32> = None;
|
||||||
for (start, end) in &self.map {
|
for (start, end) in &self.map {
|
||||||
if start > end || current.map_or(false, |x| x + 1 >= *start) {
|
if start > end || current.is_some_and(|x| x + 1 >= *start) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
current = Some(*end);
|
current = Some(*end);
|
||||||
|
@ -321,6 +321,6 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, row: R, point: C) -> bool {
|
pub fn contains(&self, row: R, point: C) -> bool {
|
||||||
self.row(row).map_or(false, |r| r.contains(point))
|
self.row(row).is_some_and(|r| r.contains(point))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1825,7 +1825,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
||||||
|| (exp_found.map_or(false, |ef| {
|
|| (exp_found.is_some_and(|ef| {
|
||||||
// This happens when the type error is a subset of the expectation,
|
// This happens when the type error is a subset of the expectation,
|
||||||
// like when you have two references but one is `usize` and the other
|
// like when you have two references but one is `usize` and the other
|
||||||
// is `f32`. In those cases we still want to show the `note`. If the
|
// is `f32`. In those cases we still want to show the `note`. If the
|
||||||
|
@ -1877,7 +1877,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
let exp_found = match terr {
|
let exp_found = match terr {
|
||||||
// `terr` has more accurate type information than `exp_found` in match expressions.
|
// `terr` has more accurate type information than `exp_found` in match expressions.
|
||||||
ty::error::TypeError::Sorts(terr)
|
ty::error::TypeError::Sorts(terr)
|
||||||
if exp_found.map_or(false, |ef| terr.found == ef.found) =>
|
if exp_found.is_some_and(|ef| terr.found == ef.found) =>
|
||||||
{
|
{
|
||||||
Some(terr)
|
Some(terr)
|
||||||
}
|
}
|
||||||
|
@ -1961,7 +1961,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||||
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
||||||
&& !code.starts_with("\\u") // forbid all Unicode escapes
|
&& !code.starts_with("\\u") // forbid all Unicode escapes
|
||||||
&& code.chars().next().map_or(false, |c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
|
&& code.chars().next().is_some_and(|c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
|
||||||
{
|
{
|
||||||
suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { span, code: escape_literal(code) })
|
suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { span, code: escape_literal(code) })
|
||||||
}
|
}
|
||||||
|
@ -2329,7 +2329,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_prev_source(p.span.shrink_to_hi())
|
.span_to_prev_source(p.span.shrink_to_hi())
|
||||||
.ok()
|
.ok()
|
||||||
.map_or(false, |s| *s.as_bytes().last().unwrap() == b'&')
|
.is_some_and(|s| *s.as_bytes().last().unwrap() == b'&')
|
||||||
{
|
{
|
||||||
add_lt_suggs
|
add_lt_suggs
|
||||||
.push(Some(
|
.push(Some(
|
||||||
|
|
|
@ -671,7 +671,7 @@ impl<'tcx> InferSource<'tcx> {
|
||||||
receiver.span.from_expansion()
|
receiver.span.from_expansion()
|
||||||
}
|
}
|
||||||
InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
|
InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
|
||||||
data.span().from_expansion() || should_wrap_expr.map_or(false, Span::from_expansion)
|
data.span().from_expansion() || should_wrap_expr.is_some_and(Span::from_expansion)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
source_from_expansion || self.span.from_expansion()
|
source_from_expansion || self.span.from_expansion()
|
||||||
|
@ -984,7 +984,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
||||||
) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
|
) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let have_turbofish = path.segments.iter().any(|segment| {
|
let have_turbofish = path.segments.iter().any(|segment| {
|
||||||
segment.args.map_or(false, |args| args.args.iter().any(|arg| arg.is_ty_or_const()))
|
segment.args.is_some_and(|args| args.args.iter().any(|arg| arg.is_ty_or_const()))
|
||||||
});
|
});
|
||||||
// The last segment of a path often has `Res::Err` and the
|
// The last segment of a path often has `Res::Err` and the
|
||||||
// correct `Res` is the one of the whole path.
|
// correct `Res` is the one of the whole path.
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
let mut obligations = vec![];
|
let mut obligations = vec![];
|
||||||
let replace_opaque_type = |def_id: DefId| {
|
let replace_opaque_type = |def_id: DefId| {
|
||||||
def_id.as_local().map_or(false, |def_id| self.opaque_type_origin(def_id).is_some())
|
def_id.as_local().is_some_and(|def_id| self.opaque_type_origin(def_id).is_some())
|
||||||
};
|
};
|
||||||
let value = value.fold_with(&mut BottomUpFolder {
|
let value = value.fold_with(&mut BottomUpFolder {
|
||||||
tcx: self.tcx,
|
tcx: self.tcx,
|
||||||
|
|
|
@ -961,7 +961,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
|
||||||
Some(sugared_span.map_or(attr.span, |span| span.with_hi(attr.span.hi())));
|
Some(sugared_span.map_or(attr.span, |span| span.with_hi(attr.span.hi())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if attrs.peek().map_or(false, |next_attr| next_attr.is_doc_comment()) {
|
if attrs.peek().is_some_and(|next_attr| next_attr.is_doc_comment()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,9 +383,8 @@ impl LateLintPass<'_> for Diagnostics {
|
||||||
debug!(?span, ?def_id, ?substs);
|
debug!(?span, ?def_id, ?substs);
|
||||||
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs)
|
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|inst| inst)
|
.flatten()
|
||||||
.map(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics))
|
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
|
||||||
.unwrap_or(false);
|
|
||||||
if !has_attr {
|
if !has_attr {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||||
// No clue where this argument is coming from.
|
// No clue where this argument is coming from.
|
||||||
return lint;
|
return lint;
|
||||||
}
|
}
|
||||||
if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
|
if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
|
||||||
// A case of `panic!(format!(..))`.
|
// A case of `panic!(format!(..))`.
|
||||||
lint.note(fluent::lint_supports_fmt_note);
|
lint.note(fluent::lint_supports_fmt_note);
|
||||||
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
|
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
|
||||||
|
|
|
@ -677,7 +677,7 @@ pub fn transparent_newtype_field<'a, 'tcx>(
|
||||||
let param_env = tcx.param_env(variant.def_id);
|
let param_env = tcx.param_env(variant.def_id);
|
||||||
variant.fields.iter().find(|field| {
|
variant.fields.iter().find(|field| {
|
||||||
let field_ty = tcx.type_of(field.did).subst_identity();
|
let field_ty = tcx.type_of(field.did).subst_identity();
|
||||||
let is_zst = tcx.layout_of(param_env.and(field_ty)).map_or(false, |layout| layout.is_zst());
|
let is_zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_zst());
|
||||||
!is_zst
|
!is_zst
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,8 +664,8 @@ trait UnusedDelimLint {
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let keep_space = (
|
let keep_space = (
|
||||||
left_pos.map_or(false, |s| s >= value.span.lo()),
|
left_pos.is_some_and(|s| s >= value.span.lo()),
|
||||||
right_pos.map_or(false, |s| s <= value.span.hi()),
|
right_pos.is_some_and(|s| s <= value.span.hi()),
|
||||||
);
|
);
|
||||||
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space);
|
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space);
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||||
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
|
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
|
||||||
|
|
||||||
let private_dep =
|
let private_dep =
|
||||||
self.sess.opts.externs.get(name.as_str()).map_or(false, |e| e.is_private_dep);
|
self.sess.opts.externs.get(name.as_str()).is_some_and(|e| e.is_private_dep);
|
||||||
|
|
||||||
// Claim this crate number and cache it
|
// Claim this crate number and cache it
|
||||||
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
|
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
|
||||||
|
|
|
@ -567,7 +567,7 @@ impl<'a> CrateLocator<'a> {
|
||||||
let mut err_data: Option<Vec<PathBuf>> = None;
|
let mut err_data: Option<Vec<PathBuf>> = None;
|
||||||
for (lib, kind) in m {
|
for (lib, kind) in m {
|
||||||
info!("{} reading metadata from: {}", flavor, lib.display());
|
info!("{} reading metadata from: {}", flavor, lib.display());
|
||||||
if flavor == CrateFlavor::Rmeta && lib.metadata().map_or(false, |m| m.len() == 0) {
|
if flavor == CrateFlavor::Rmeta && lib.metadata().is_ok_and(|m| m.len() == 0) {
|
||||||
// Empty files will cause get_metadata_section to fail. Rmeta
|
// Empty files will cause get_metadata_section to fail. Rmeta
|
||||||
// files can be empty, for example with binaries (which can
|
// files can be empty, for example with binaries (which can
|
||||||
// often appear with `cargo check` when checking a library as
|
// often appear with `cargo check` when checking a library as
|
||||||
|
@ -602,7 +602,7 @@ impl<'a> CrateLocator<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// If we see multiple hashes, emit an error about duplicate candidates.
|
// If we see multiple hashes, emit an error about duplicate candidates.
|
||||||
if slot.as_ref().map_or(false, |s| s.0 != hash) {
|
if slot.as_ref().is_some_and(|s| s.0 != hash) {
|
||||||
if let Some(candidates) = err_data {
|
if let Some(candidates) = err_data {
|
||||||
return Err(CrateError::MultipleCandidates(
|
return Err(CrateError::MultipleCandidates(
|
||||||
self.crate_name,
|
self.crate_name,
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
.expect("argument names not encoded for a function")
|
.expect("argument names not encoded for a function")
|
||||||
.decode((self, sess))
|
.decode((self, sess))
|
||||||
.nth(0)
|
.nth(0)
|
||||||
.map_or(false, |ident| ident.name == kw::SelfLower)
|
.is_some_and(|ident| ident.name == kw::SelfLower)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_associated_item_or_field_def_ids(
|
fn get_associated_item_or_field_def_ids(
|
||||||
|
|
|
@ -410,7 +410,7 @@ impl<'hir> Map<'hir> {
|
||||||
/// item (possibly associated), a closure, or a `hir::AnonConst`.
|
/// item (possibly associated), a closure, or a `hir::AnonConst`.
|
||||||
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
|
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
|
||||||
let parent = self.parent_id(hir_id);
|
let parent = self.parent_id(hir_id);
|
||||||
assert!(self.find(parent).map_or(false, |n| is_body_owner(n, hir_id)), "{hir_id:?}");
|
assert!(self.find(parent).is_some_and(|n| is_body_owner(n, hir_id)), "{hir_id:?}");
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
|
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
|
||||||
pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
|
pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
|
||||||
self.opt_parent(def_id.into())
|
self.opt_parent(def_id.into())
|
||||||
.map_or(false, |parent| matches!(self.def_kind(parent), DefKind::ForeignMod))
|
.is_some_and(|parent| matches!(self.def_kind(parent), DefKind::ForeignMod))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,8 +94,7 @@ pub struct EffectiveVisibilities<Id = LocalDefId> {
|
||||||
|
|
||||||
impl EffectiveVisibilities {
|
impl EffectiveVisibilities {
|
||||||
pub fn is_public_at_level(&self, id: LocalDefId, level: Level) -> bool {
|
pub fn is_public_at_level(&self, id: LocalDefId, level: Level) -> bool {
|
||||||
self.effective_vis(id)
|
self.effective_vis(id).is_some_and(|effective_vis| effective_vis.is_public_at_level(level))
|
||||||
.map_or(false, |effective_vis| effective_vis.is_public_at_level(level))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `Level::Reachable`.
|
/// See `Level::Reachable`.
|
||||||
|
|
|
@ -375,7 +375,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let parent_def_id = self.hir().get_parent_item(id);
|
let parent_def_id = self.hir().get_parent_item(id);
|
||||||
let skip = self
|
let skip = self
|
||||||
.lookup_deprecation_entry(parent_def_id.to_def_id())
|
.lookup_deprecation_entry(parent_def_id.to_def_id())
|
||||||
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
.is_some_and(|parent_depr| parent_depr.same_origin(&depr_entry));
|
||||||
|
|
||||||
// #[deprecated] doesn't emit a notice if we're not on the
|
// #[deprecated] doesn't emit a notice if we're not on the
|
||||||
// topmost deprecation. For example, if a struct is deprecated,
|
// topmost deprecation. For example, if a struct is deprecated,
|
||||||
|
|
|
@ -2341,7 +2341,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_late_bound(self, id: HirId) -> bool {
|
pub fn is_late_bound(self, id: HirId) -> bool {
|
||||||
self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id))
|
self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
|
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
|
||||||
|
@ -2474,7 +2474,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
|tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins);
|
|tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins);
|
||||||
providers.has_panic_handler = |tcx, LocalCrate| {
|
providers.has_panic_handler = |tcx, LocalCrate| {
|
||||||
// We want to check if the panic handler was defined in this crate
|
// We want to check if the panic handler was defined in this crate
|
||||||
tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
|
tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
|
||||||
};
|
};
|
||||||
providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
|
providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ impl<'tcx> Generics {
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.take_while(|param| {
|
.take_while(|param| {
|
||||||
param.default_value(tcx).map_or(false, |default| {
|
param.default_value(tcx).is_some_and(|default| {
|
||||||
default.subst(tcx, substs) == substs[param.index as usize]
|
default.subst(tcx, substs) == substs[param.index as usize]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -659,7 +659,7 @@ fn polymorphize<'tcx>(
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let has_upvars = upvars_ty.map_or(false, |ty| !ty.tuple_fields().is_empty());
|
let has_upvars = upvars_ty.is_some_and(|ty| !ty.tuple_fields().is_empty());
|
||||||
debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);
|
debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);
|
||||||
|
|
||||||
struct PolymorphizationFolder<'tcx> {
|
struct PolymorphizationFolder<'tcx> {
|
||||||
|
|
|
@ -2220,8 +2220,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let impl_trait_ref2 = self.impl_trait_ref(def_id2);
|
let impl_trait_ref2 = self.impl_trait_ref(def_id2);
|
||||||
// If either trait impl references an error, they're allowed to overlap,
|
// If either trait impl references an error, they're allowed to overlap,
|
||||||
// as one of them essentially doesn't exist.
|
// as one of them essentially doesn't exist.
|
||||||
if impl_trait_ref1.map_or(false, |tr| tr.subst_identity().references_error())
|
if impl_trait_ref1.is_some_and(|tr| tr.subst_identity().references_error())
|
||||||
|| impl_trait_ref2.map_or(false, |tr| tr.subst_identity().references_error())
|
|| impl_trait_ref2.is_some_and(|tr| tr.subst_identity().references_error())
|
||||||
{
|
{
|
||||||
return Some(ImplOverlapKind::Permitted { marker: false });
|
return Some(ImplOverlapKind::Permitted { marker: false });
|
||||||
}
|
}
|
||||||
|
@ -2242,7 +2242,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
let is_marker_overlap = {
|
let is_marker_overlap = {
|
||||||
let is_marker_impl = |trait_ref: Option<EarlyBinder<TraitRef<'_>>>| -> bool {
|
let is_marker_impl = |trait_ref: Option<EarlyBinder<TraitRef<'_>>>| -> bool {
|
||||||
trait_ref.map_or(false, |tr| self.trait_def(tr.skip_binder().def_id).is_marker)
|
trait_ref.is_some_and(|tr| self.trait_def(tr.skip_binder().def_id).is_marker)
|
||||||
};
|
};
|
||||||
is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2)
|
is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2)
|
||||||
};
|
};
|
||||||
|
|
|
@ -351,7 +351,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let popped = this.block_context.pop();
|
let popped = this.block_context.pop();
|
||||||
assert!(popped.map_or(false, |bf| bf.is_statement()));
|
assert!(popped.is_some_and(|bf| bf.is_statement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, the block may have an optional trailing expression which is a “return” value
|
// Then, the block may have an optional trailing expression which is a “return” value
|
||||||
|
@ -367,7 +367,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
unpack!(block = this.expr_into_dest(destination, block, expr));
|
unpack!(block = this.expr_into_dest(destination, block, expr));
|
||||||
let popped = this.block_context.pop();
|
let popped = this.block_context.pop();
|
||||||
|
|
||||||
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));
|
assert!(popped.is_some_and(|bf| bf.is_tail_expr()));
|
||||||
} else {
|
} else {
|
||||||
// If a block has no trailing expression, then it is given an implicit return type.
|
// If a block has no trailing expression, then it is given an implicit return type.
|
||||||
// This return type is usually `()`, unless the block is diverging, in which case the
|
// This return type is usually `()`, unless the block is diverging, in which case the
|
||||||
|
|
|
@ -325,10 +325,10 @@ impl DropTree {
|
||||||
entry_points.sort();
|
entry_points.sort();
|
||||||
|
|
||||||
for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() {
|
for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() {
|
||||||
if entry_points.last().map_or(false, |entry_point| entry_point.0 == drop_idx) {
|
if entry_points.last().is_some_and(|entry_point| entry_point.0 == drop_idx) {
|
||||||
let block = *blocks[drop_idx].get_or_insert_with(|| T::make_block(cfg));
|
let block = *blocks[drop_idx].get_or_insert_with(|| T::make_block(cfg));
|
||||||
needs_block[drop_idx] = Block::Own;
|
needs_block[drop_idx] = Block::Own;
|
||||||
while entry_points.last().map_or(false, |entry_point| entry_point.0 == drop_idx) {
|
while entry_points.last().is_some_and(|entry_point| entry_point.0 == drop_idx) {
|
||||||
let entry_block = entry_points.pop().unwrap().1;
|
let entry_block = entry_points.pop().unwrap().1;
|
||||||
T::add_entry(cfg, entry_block, block);
|
T::add_entry(cfg, entry_block, block);
|
||||||
}
|
}
|
||||||
|
@ -731,7 +731,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
|
fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
|
||||||
// If we are emitting a `drop` statement, we need to have the cached
|
// If we are emitting a `drop` statement, we need to have the cached
|
||||||
// diverge cleanup pads ready in case that drop panics.
|
// diverge cleanup pads ready in case that drop panics.
|
||||||
let needs_cleanup = self.scopes.scopes.last().map_or(false, |scope| scope.needs_cleanup());
|
let needs_cleanup = self.scopes.scopes.last().is_some_and(|scope| scope.needs_cleanup());
|
||||||
let is_generator = self.generator_kind.is_some();
|
let is_generator = self.generator_kind.is_some();
|
||||||
let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX };
|
let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX };
|
||||||
|
|
||||||
|
|
|
@ -333,7 +333,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
} else if let Some(box_item) = tcx.lang_items().owned_box() {
|
} else if let Some(box_item) = tcx.lang_items().owned_box() {
|
||||||
if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = fun.kind
|
if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = fun.kind
|
||||||
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
|
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
|
||||||
&& path.res.opt_def_id().map_or(false, |did| did == box_item)
|
&& path.res.opt_def_id().is_some_and(|did| did == box_item)
|
||||||
&& fn_path.ident.name == sym::new
|
&& fn_path.ident.name == sym::new
|
||||||
&& let [value] = args
|
&& let [value] = args
|
||||||
{
|
{
|
||||||
|
@ -956,7 +956,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
let is_upvar = self
|
let is_upvar = self
|
||||||
.tcx
|
.tcx
|
||||||
.upvars_mentioned(self.body_owner)
|
.upvars_mentioned(self.body_owner)
|
||||||
.map_or(false, |upvars| upvars.contains_key(&var_hir_id));
|
.is_some_and(|upvars| upvars.contains_key(&var_hir_id));
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"convert_var({:?}): is_upvar={}, body_owner={:?}",
|
"convert_var({:?}): is_upvar={}, body_owner={:?}",
|
||||||
|
|
|
@ -363,7 +363,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
|
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
|
||||||
let right_size = r.layout.size;
|
let right_size = r.layout.size;
|
||||||
let r_bits = r.to_scalar().to_bits(right_size).ok();
|
let r_bits = r.to_scalar().to_bits(right_size).ok();
|
||||||
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
|
if r_bits.is_some_and(|b| b >= left_size.bits() as u128) {
|
||||||
debug!("check_binary_op: reporting assert for {:?}", location);
|
debug!("check_binary_op: reporting assert for {:?}", location);
|
||||||
let source_info = self.body().source_info(location);
|
let source_info = self.body().source_info(location);
|
||||||
let panic = AssertKind::Overflow(
|
let panic = AssertKind::Overflow(
|
||||||
|
|
|
@ -108,7 +108,7 @@ fn local_eligible_for_nrvo(body: &mut mir::Body<'_>) -> Option<Local> {
|
||||||
|
|
||||||
// If multiple different locals are copied to the return place. We can't pick a
|
// If multiple different locals are copied to the return place. We can't pick a
|
||||||
// single one to rename.
|
// single one to rename.
|
||||||
if copied_to_return_place.map_or(false, |old| old != returned_local) {
|
if copied_to_return_place.is_some_and(|old| old != returned_local) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool {
|
||||||
// Therefore, the absence of a literal `cfg` or `cfg_attr` guarantees that
|
// Therefore, the absence of a literal `cfg` or `cfg_attr` guarantees that
|
||||||
// we don't need to do any eager expansion.
|
// we don't need to do any eager expansion.
|
||||||
attrs.iter().any(|attr| {
|
attrs.iter().any(|attr| {
|
||||||
attr.ident().map_or(false, |ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
|
attr.ident().is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -845,7 +845,7 @@ impl<'a> Parser<'a> {
|
||||||
//
|
//
|
||||||
// `x.foo::<u32>>>(3)`
|
// `x.foo::<u32>>>(3)`
|
||||||
let parsed_angle_bracket_args =
|
let parsed_angle_bracket_args =
|
||||||
segment.args.as_ref().map_or(false, |args| args.is_angle_bracketed());
|
segment.args.as_ref().is_some_and(|args| args.is_angle_bracketed());
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
|
"check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
|
||||||
|
@ -2610,7 +2610,7 @@ impl<'a> Parser<'a> {
|
||||||
let TyKind::Path(qself, path) = &ty.kind else { return Ok(()) };
|
let TyKind::Path(qself, path) = &ty.kind else { return Ok(()) };
|
||||||
let qself_position = qself.as_ref().map(|qself| qself.position);
|
let qself_position = qself.as_ref().map(|qself| qself.position);
|
||||||
for (i, segments) in path.segments.windows(2).enumerate() {
|
for (i, segments) in path.segments.windows(2).enumerate() {
|
||||||
if qself_position.map(|pos| i < pos).unwrap_or(false) {
|
if qself_position.is_some_and(|pos| i < pos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let [a, b] = segments {
|
if let [a, b] = segments {
|
||||||
|
|
|
@ -1188,7 +1188,7 @@ impl<'a> Parser<'a> {
|
||||||
// `token.kind` should not be compared here.
|
// `token.kind` should not be compared here.
|
||||||
// This is because the `snapshot.token.kind` is treated as the same as
|
// This is because the `snapshot.token.kind` is treated as the same as
|
||||||
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different.
|
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different.
|
||||||
self.span_to_snippet(close_paren).map_or(false, |snippet| snippet == ")")
|
self.span_to_snippet(close_paren).is_ok_and(|snippet| snippet == ")")
|
||||||
{
|
{
|
||||||
let mut replacement_err = errors::ParenthesesWithStructFields {
|
let mut replacement_err = errors::ParenthesesWithStructFields {
|
||||||
span,
|
span,
|
||||||
|
@ -2078,7 +2078,7 @@ impl<'a> Parser<'a> {
|
||||||
// Therefore, `token.kind` should not be compared here.
|
// Therefore, `token.kind` should not be compared here.
|
||||||
if snapshot
|
if snapshot
|
||||||
.span_to_snippet(snapshot.token.span)
|
.span_to_snippet(snapshot.token.span)
|
||||||
.map_or(false, |snippet| snippet == "]") =>
|
.is_ok_and(|snippet| snippet == "]") =>
|
||||||
{
|
{
|
||||||
return Err(errors::MissingSemicolonBeforeArray {
|
return Err(errors::MissingSemicolonBeforeArray {
|
||||||
open_delim: open_delim_span,
|
open_delim: open_delim_span,
|
||||||
|
@ -2773,7 +2773,7 @@ impl<'a> Parser<'a> {
|
||||||
// We might have a `=>` -> `=` or `->` typo (issue #89396).
|
// We might have a `=>` -> `=` or `->` typo (issue #89396).
|
||||||
if TokenKind::FatArrow
|
if TokenKind::FatArrow
|
||||||
.similar_tokens()
|
.similar_tokens()
|
||||||
.map_or(false, |similar_tokens| similar_tokens.contains(&this.token.kind))
|
.is_some_and(|similar_tokens| similar_tokens.contains(&this.token.kind))
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
this.token.span,
|
this.token.span,
|
||||||
|
@ -3059,7 +3059,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_shorthand = parsed_field.as_ref().map_or(false, |f| f.is_shorthand);
|
let is_shorthand = parsed_field.as_ref().is_some_and(|f| f.is_shorthand);
|
||||||
// A shorthand field can be turned into a full field with `:`.
|
// A shorthand field can be turned into a full field with `:`.
|
||||||
// We should point this out.
|
// We should point this out.
|
||||||
self.check_or_expected(!is_shorthand, TokenType::Token(token::Colon));
|
self.check_or_expected(!is_shorthand, TokenType::Token(token::Colon));
|
||||||
|
|
|
@ -699,7 +699,7 @@ impl<'a> Parser<'a> {
|
||||||
// ```
|
// ```
|
||||||
&& self
|
&& self
|
||||||
.span_to_snippet(self.prev_token.span)
|
.span_to_snippet(self.prev_token.span)
|
||||||
.map_or(false, |snippet| snippet == "}")
|
.is_ok_and(|snippet| snippet == "}")
|
||||||
&& self.token.kind == token::Semi;
|
&& self.token.kind == token::Semi;
|
||||||
let mut semicolon_span = self.token.span;
|
let mut semicolon_span = self.token.span;
|
||||||
if !is_unnecessary_semicolon {
|
if !is_unnecessary_semicolon {
|
||||||
|
|
|
@ -1816,7 +1816,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
|| (is_simd && is_c)
|
|| (is_simd && is_c)
|
||||||
|| (int_reprs == 1
|
|| (int_reprs == 1
|
||||||
&& is_c
|
&& is_c
|
||||||
&& item.map_or(false, |item| {
|
&& item.is_some_and(|item| {
|
||||||
if let ItemLike::Item(item) = item {
|
if let ItemLike::Item(item) = item {
|
||||||
return is_c_like_enum(item);
|
return is_c_like_enum(item);
|
||||||
}
|
}
|
||||||
|
@ -2095,7 +2095,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
| sym::feature
|
| sym::feature
|
||||||
| sym::repr
|
| sym::repr
|
||||||
| sym::target_feature
|
| sym::target_feature
|
||||||
) && attr.meta_item_list().map_or(false, |list| list.is_empty())
|
) && attr.meta_item_list().is_some_and(|list| list.is_empty())
|
||||||
{
|
{
|
||||||
errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
|
errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
|
|
|
@ -554,10 +554,8 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
|
||||||
|
|
||||||
let is_const = self.tcx.is_const_fn(def_id.to_def_id())
|
let is_const = self.tcx.is_const_fn(def_id.to_def_id())
|
||||||
|| self.tcx.is_const_trait_impl_raw(def_id.to_def_id());
|
|| self.tcx.is_const_trait_impl_raw(def_id.to_def_id());
|
||||||
let is_stable = self
|
let is_stable =
|
||||||
.tcx
|
self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable());
|
||||||
.lookup_stability(def_id)
|
|
||||||
.map_or(false, |stability| stability.level.is_stable());
|
|
||||||
let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none();
|
let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none();
|
||||||
let is_reachable = self.effective_visibilities.is_reachable(def_id);
|
let is_reachable = self.effective_visibilities.is_reachable(def_id);
|
||||||
|
|
||||||
|
@ -772,7 +770,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
// needs to have an error emitted.
|
// needs to have an error emitted.
|
||||||
if features.const_trait_impl
|
if features.const_trait_impl
|
||||||
&& *constness == hir::Constness::Const
|
&& *constness == hir::Constness::Const
|
||||||
&& const_stab.map_or(false, |(stab, _)| stab.is_const_stable())
|
&& const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
|
||||||
{
|
{
|
||||||
self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span });
|
self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span });
|
||||||
}
|
}
|
||||||
|
@ -809,15 +807,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_allowed_through_unstable_modules = |def_id| {
|
let is_allowed_through_unstable_modules = |def_id| {
|
||||||
self.tcx
|
self.tcx.lookup_stability(def_id).is_some_and(|stab| match stab.level {
|
||||||
.lookup_stability(def_id)
|
StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
|
||||||
.map(|stab| match stab.level {
|
allowed_through_unstable_modules
|
||||||
StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
|
}
|
||||||
allowed_through_unstable_modules
|
_ => false,
|
||||||
}
|
})
|
||||||
_ => false,
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if item_is_allowed && !is_allowed_through_unstable_modules(def_id) {
|
if item_is_allowed && !is_allowed_through_unstable_modules(def_id) {
|
||||||
|
|
|
@ -656,7 +656,7 @@ impl<K: DepKind> DepGraphData<K> {
|
||||||
/// current compilation session. Used in various assertions
|
/// current compilation session. Used in various assertions
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool {
|
pub fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool {
|
||||||
self.colors.get(prev_index).map_or(false, |c| c.is_green())
|
self.colors.get(prev_index).is_some_and(|c| c.is_green())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -677,7 +677,7 @@ impl<K: DepKind> DepGraphData<K> {
|
||||||
impl<K: DepKind> DepGraph<K> {
|
impl<K: DepKind> DepGraph<K> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dep_node_exists(&self, dep_node: &DepNode<K>) -> bool {
|
pub fn dep_node_exists(&self, dep_node: &DepNode<K>) -> bool {
|
||||||
self.data.as_ref().map_or(false, |data| data.dep_node_exists(dep_node))
|
self.data.as_ref().is_some_and(|data| data.dep_node_exists(dep_node))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a previous work product exists for `v` and, if
|
/// Checks whether a previous work product exists for `v` and, if
|
||||||
|
@ -955,7 +955,7 @@ impl<K: DepKind> DepGraph<K> {
|
||||||
/// Returns true if the given node has been marked as green during the
|
/// Returns true if the given node has been marked as green during the
|
||||||
/// current compilation session. Used in various assertions
|
/// current compilation session. Used in various assertions
|
||||||
pub fn is_green(&self, dep_node: &DepNode<K>) -> bool {
|
pub fn is_green(&self, dep_node: &DepNode<K>) -> bool {
|
||||||
self.node_color(dep_node).map_or(false, |c| c.is_green())
|
self.node_color(dep_node).is_some_and(|c| c.is_green())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method loads all on-disk cacheable query results into memory, so
|
/// This method loads all on-disk cacheable query results into memory, so
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| {
|
.filter(|attr| {
|
||||||
!attr.is_doc_comment()
|
!attr.is_doc_comment()
|
||||||
&& !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
|
&& !attr.ident().is_some_and(|ident| hcx.is_ignored_attr(ident.name))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
|
||||||
impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
||||||
fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
|
fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
|
||||||
// Make sure that these have been filtered out.
|
// Make sure that these have been filtered out.
|
||||||
debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
|
debug_assert!(!attr.ident().is_some_and(|ident| self.is_ignored_attr(ident.name)));
|
||||||
debug_assert!(!attr.is_doc_comment());
|
debug_assert!(!attr.is_doc_comment());
|
||||||
|
|
||||||
let ast::Attribute { kind, id: _, style, span } = attr;
|
let ast::Attribute { kind, id: _, style, span } = attr;
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
expn_id,
|
expn_id,
|
||||||
self.def_span(def_id),
|
self.def_span(def_id),
|
||||||
// FIXME: Account for `#[no_implicit_prelude]` attributes.
|
// FIXME: Account for `#[no_implicit_prelude]` attributes.
|
||||||
parent.map_or(false, |module| module.no_implicit_prelude),
|
parent.is_some_and(|module| module.no_implicit_prelude),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,16 +117,11 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ast::UseTreeKind::Simple(Some(ident)) => {
|
ast::UseTreeKind::Simple(Some(ident)) => {
|
||||||
if ident.name == kw::Underscore
|
if ident.name == kw::Underscore
|
||||||
&& !self
|
&& !self.r.import_res_map.get(&id).is_some_and(|per_ns| {
|
||||||
.r
|
per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
|
||||||
.import_res_map
|
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
|
||||||
.get(&id)
|
|
||||||
.map(|per_ns| {
|
|
||||||
per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
|
|
||||||
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.unwrap_or(false)
|
})
|
||||||
{
|
{
|
||||||
self.unused_import(self.base_id).add(id);
|
self.unused_import(self.base_id).add(id);
|
||||||
}
|
}
|
||||||
|
@ -469,7 +464,7 @@ impl Resolver<'_, '_> {
|
||||||
.r
|
.r
|
||||||
.extern_prelude
|
.extern_prelude
|
||||||
.get(&extern_crate.ident)
|
.get(&extern_crate.ident)
|
||||||
.map_or(false, |entry| !entry.introduced_by_item)
|
.is_some_and(|entry| !entry.introduced_by_item)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1843,7 +1843,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
|
} else if ident.name.as_str().chars().next().is_some_and(|c| c.is_ascii_uppercase()) {
|
||||||
// Check whether the name refers to an item in the value namespace.
|
// Check whether the name refers to an item in the value namespace.
|
||||||
let binding = if let Some(ribs) = ribs {
|
let binding = if let Some(ribs) = ribs {
|
||||||
self.resolve_ident_in_lexical_scope(
|
self.resolve_ident_in_lexical_scope(
|
||||||
|
@ -2165,7 +2165,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
let is_definitely_crate = import
|
let is_definitely_crate = import
|
||||||
.module_path
|
.module_path
|
||||||
.first()
|
.first()
|
||||||
.map_or(false, |f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
|
.is_some_and(|f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
|
||||||
|
|
||||||
// Add the import to the start, with a `{` if required.
|
// Add the import to the start, with a `{` if required.
|
||||||
let start_point = source_map.start_point(after_crate_name);
|
let start_point = source_map.start_point(after_crate_name);
|
||||||
|
|
|
@ -197,8 +197,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(span)
|
.span_to_snippet(span)
|
||||||
.map(|snippet| snippet.ends_with(')'))
|
.is_ok_and(|snippet| snippet.ends_with(')'))
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
Res::Def(
|
Res::Def(
|
||||||
DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
|
DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
|
||||||
|
@ -722,7 +721,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
|
if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
|
||||||
&& res
|
&& res
|
||||||
.opt_def_id()
|
.opt_def_id()
|
||||||
.map_or(false, |id| id.is_local() || is_in_same_file(span, sugg_span))
|
.is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span))
|
||||||
{
|
{
|
||||||
err.span_label(
|
err.span_label(
|
||||||
sugg_span,
|
sugg_span,
|
||||||
|
@ -856,7 +855,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
// The current function has a `self` parameter, but we were unable to resolve
|
// The current function has a `self` parameter, but we were unable to resolve
|
||||||
// a reference to `self`. This can only happen if the `self` identifier we
|
// a reference to `self`. This can only happen if the `self` identifier we
|
||||||
// are resolving came from a different hygiene context.
|
// are resolving came from a different hygiene context.
|
||||||
if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
|
if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
|
||||||
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
|
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
|
||||||
} else {
|
} else {
|
||||||
let doesnt = if is_assoc_fn {
|
let doesnt = if is_assoc_fn {
|
||||||
|
@ -1632,7 +1631,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
.tcx
|
.tcx
|
||||||
.fn_arg_names(def_id)
|
.fn_arg_names(def_id)
|
||||||
.first()
|
.first()
|
||||||
.map_or(false, |ident| ident.name == kw::SelfLower),
|
.is_some_and(|ident| ident.name == kw::SelfLower),
|
||||||
};
|
};
|
||||||
if has_self {
|
if has_self {
|
||||||
return Some(AssocSuggestion::MethodWithSelf { called });
|
return Some(AssocSuggestion::MethodWithSelf { called });
|
||||||
|
@ -1931,10 +1930,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
let def_id = self.r.tcx.parent(ctor_def_id);
|
let def_id = self.r.tcx.parent(ctor_def_id);
|
||||||
match kind {
|
match kind {
|
||||||
CtorKind::Const => false,
|
CtorKind::Const => false,
|
||||||
CtorKind::Fn => !self
|
CtorKind::Fn => {
|
||||||
.r
|
!self.r.field_def_ids(def_id).is_some_and(|field_ids| field_ids.is_empty())
|
||||||
.field_def_ids(def_id)
|
}
|
||||||
.map_or(false, |field_ids| field_ids.is_empty()),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1477,7 +1477,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_builtin_macro(&mut self, res: Res) -> bool {
|
fn is_builtin_macro(&mut self, res: Res) -> bool {
|
||||||
self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some())
|
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
|
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
|
||||||
|
|
|
@ -823,8 +823,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
let is_allowed = |feature| {
|
let is_allowed = |feature| {
|
||||||
self.active_features.contains(&feature) || span.allows_unstable(feature)
|
self.active_features.contains(&feature) || span.allows_unstable(feature)
|
||||||
};
|
};
|
||||||
let allowed_by_implication =
|
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
|
||||||
implied_by.map(|feature| is_allowed(feature)).unwrap_or(false);
|
|
||||||
if !is_allowed(feature) && !allowed_by_implication {
|
if !is_allowed(feature) && !allowed_by_implication {
|
||||||
let lint_buffer = &mut self.lint_buffer;
|
let lint_buffer = &mut self.lint_buffer;
|
||||||
let soft_handler =
|
let soft_handler =
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue