1
Fork 0

Auto merge of #127476 - jieyouxu:rollup-16wyb0b, r=jieyouxu

Rollup of 10 pull requests

Successful merges:

 - #126841 ([`macro_metavar_expr_concat`] Add support for literals)
 - #126881 (Make `NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE` a deny-by-default lint in edition 2024)
 - #126921 (Give VaList its own home)
 - #127367 (Run alloc sync tests)
 - #127431 (Use field ident spans directly instead of the full field span in diagnostics on local fields)
 - #127437 (Uplift trait ref is knowable into `rustc_next_trait_solver`)
 - #127439 (Uplift elaboration into `rustc_type_ir`)
 - #127451 (Improve `run-make/output-type-permutations` code and improve `filename_not_in_denylist` API)
 - #127452 (Fix intrinsic const parameter counting with `effects`)
 - #127459 (rustdoc-json: add type/trait alias tests)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-08 06:47:12 +00:00
commit 7fdefb804e
79 changed files with 1989 additions and 1570 deletions

View file

@ -7,7 +7,6 @@ pub mod select;
pub mod solve;
pub mod specialization_graph;
mod structural_impls;
pub mod util;
use crate::mir::ConstraintCategory;
use crate::ty::abstract_const::NotConstEvaluatable;

View file

@ -1,62 +0,0 @@
use rustc_data_structures::fx::FxHashSet;
use crate::ty::{Clause, PolyTraitRef, ToPolyTraitRef, TyCtxt, Upcast};
/// Given a [`PolyTraitRef`], get the [`Clause`]s implied by the trait's definition.
///
/// This only exists in `rustc_middle` because the more powerful elaborator depends on
/// `rustc_infer` for elaborating outlives bounds -- this should only be used for pretty
/// printing.
pub fn super_predicates_for_pretty_printing<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: PolyTraitRef<'tcx>,
) -> impl Iterator<Item = Clause<'tcx>> {
let clause = trait_ref.upcast(tcx);
Elaborator { tcx, visited: FxHashSet::from_iter([clause]), stack: vec![clause] }
}
/// Like [`super_predicates_for_pretty_printing`], except it only returns traits and filters out
/// all other [`Clause`]s.
pub fn supertraits_for_pretty_printing<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: PolyTraitRef<'tcx>,
) -> impl Iterator<Item = PolyTraitRef<'tcx>> {
super_predicates_for_pretty_printing(tcx, trait_ref).filter_map(|clause| {
clause.as_trait_clause().map(|trait_clause| trait_clause.to_poly_trait_ref())
})
}
struct Elaborator<'tcx> {
tcx: TyCtxt<'tcx>,
visited: FxHashSet<Clause<'tcx>>,
stack: Vec<Clause<'tcx>>,
}
impl<'tcx> Elaborator<'tcx> {
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
let super_predicates =
self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|&(pred, _)| {
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
self.visited.insert(clause).then_some(clause)
},
);
self.stack.extend(super_predicates);
}
}
impl<'tcx> Iterator for Elaborator<'tcx> {
type Item = Clause<'tcx>;
fn next(&mut self) -> Option<Clause<'tcx>> {
if let Some(clause) = self.stack.pop() {
if let Some(trait_clause) = clause.as_trait_clause() {
self.elaborate(trait_clause.to_poly_trait_ref());
}
Some(clause)
} else {
None
}
}
}

View file

@ -229,6 +229,10 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
self.sized_constraint(tcx)
}
fn is_fundamental(self) -> bool {
self.is_fundamental()
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]

View file

@ -37,7 +37,7 @@ use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
use rustc_data_structures::defer;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::intern::Interned;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
@ -347,12 +347,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn explicit_super_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
ty::EarlyBinder::bind(self.explicit_super_predicates_of(def_id).instantiate_identity(self))
}
fn explicit_implied_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
ty::EarlyBinder::bind(
self.explicit_super_predicates_of(def_id)
.instantiate_identity(self)
.predicates
.into_iter(),
self.explicit_implied_predicates_of(def_id).instantiate_identity(self),
)
}
@ -524,12 +528,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.is_object_safe(trait_def_id)
}
fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).implement_via_object
fn trait_is_fundamental(self, def_id: DefId) -> bool {
self.trait_def(def_id).is_fundamental
}
fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.supertrait_def_ids(trait_def_id)
fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).implement_via_object
}
fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
@ -569,6 +573,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
) -> Ty<'tcx> {
placeholder.find_const_ty_from_env(param_env)
}
fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
self,
binder: ty::Binder<'tcx, T>,
) -> ty::Binder<'tcx, T> {
self.anonymize_bound_vars(binder)
}
}
macro_rules! bidirectional_lang_item_map {
@ -635,6 +646,10 @@ bidirectional_lang_item_map! {
}
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
fn is_local(self) -> bool {
self.is_local()
}
fn as_local(self) -> Option<LocalDefId> {
self.as_local()
}
@ -2484,25 +2499,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// to identify which traits may define a given associated type to help avoid cycle errors,
/// and to make size estimates for vtable layout computation.
pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
let mut set = FxHashSet::default();
let mut stack = vec![trait_def_id];
set.insert(trait_def_id);
iter::from_fn(move || -> Option<DefId> {
let trait_did = stack.pop()?;
let generic_predicates = self.explicit_super_predicates_of(trait_did);
for (predicate, _) in generic_predicates.predicates {
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
if set.insert(data.def_id()) {
stack.push(data.def_id());
}
}
}
Some(trait_did)
})
rustc_type_ir::elaborate::supertrait_def_ids(self, trait_def_id)
}
/// Given a closure signature, returns an equivalent fn signature. Detuples

View file

@ -0,0 +1,84 @@
use rustc_span::Span;
use rustc_type_ir::elaborate::Elaboratable;
use crate::ty::{self, TyCtxt};
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.as_predicate()
}
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
clause
}
fn child_with_derived_cause(
&self,
clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
clause
}
}
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx> {
*self
}
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
clause.as_predicate()
}
fn child_with_derived_cause(
&self,
clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
clause.as_predicate()
}
}
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for (ty::Predicate<'tcx>, Span) {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.0
}
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
(clause.as_predicate(), self.1)
}
fn child_with_derived_cause(
&self,
clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
(clause.as_predicate(), self.1)
}
}
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for (ty::Clause<'tcx>, Span) {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.0.as_predicate()
}
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
(clause, self.1)
}
fn child_with_derived_cause(
&self,
clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
(clause, self.1)
}
}

View file

@ -394,7 +394,7 @@ impl<'tcx> GenericPredicates<'tcx> {
}
pub fn instantiate_own_identity(&self) -> impl Iterator<Item = (Clause<'tcx>, Span)> {
EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied()
EarlyBinder::bind(self.predicates).iter_identity_copied()
}
#[instrument(level = "debug", skip(self, tcx))]

View file

@ -148,6 +148,7 @@ mod closure;
mod consts;
mod context;
mod diagnostics;
mod elaborate_impl;
mod erase_regions;
mod generic_args;
mod generics;

View file

@ -46,6 +46,10 @@ pub struct Predicate<'tcx>(
);
impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {
fn as_clause(self) -> Option<ty::Clause<'tcx>> {
self.as_clause()
}
fn is_coinductive(self, interner: TyCtxt<'tcx>) -> bool {
self.is_coinductive(interner)
}
@ -173,7 +177,11 @@ pub struct Clause<'tcx>(
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
);
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {}
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
self.instantiate_supertrait(tcx, trait_ref)
}
}
impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;

View file

@ -1,7 +1,6 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::query::IntoQueryParam;
use crate::query::Providers;
use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
use crate::ty::GenericArgKind;
use crate::ty::{
ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
@ -23,6 +22,7 @@ use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::FileNameDisplayPreference;
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
use rustc_type_ir::{elaborate, Upcast as _};
use smallvec::SmallVec;
use std::cell::Cell;
@ -1255,14 +1255,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
entry.has_fn_once = true;
return;
} else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) {
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
return;
} else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) {
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
@ -1343,10 +1343,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
let bound_principal_with_self = bound_principal
.with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
let super_projections: Vec<_> =
super_predicates_for_pretty_printing(cx.tcx(), bound_principal_with_self)
.filter_map(|clause| clause.as_projection_clause())
.collect();
let clause: ty::Clause<'tcx> = bound_principal_with_self.upcast(cx.tcx());
let super_projections: Vec<_> = elaborate::elaborate(cx.tcx(), [clause])
.filter_only_self()
.filter_map(|clause| clause.as_projection_clause())
.collect();
let mut projections: Vec<_> = predicates
.projection_bounds()

View file

@ -811,6 +811,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
Ty::new_var(tcx, vid)
}
fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamTy) -> Self {
Ty::new_param(tcx, param.index, param.name)
}
fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Self {
Ty::new_placeholder(tcx, placeholder)
}
fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundTy) -> Self {
Ty::new_bound(interner, debruijn, var)
}

View file

@ -31,7 +31,7 @@ pub struct TraitDef {
/// and thus `impl`s of it are allowed to overlap.
pub is_marker: bool,
/// If `true`, then this trait has to `#[rustc_coinductive]` attribute or
/// If `true`, then this trait has the `#[rustc_coinductive]` attribute or
/// is an auto trait. This indicates that trait solver cycles involving an
/// `X: ThisTrait` goal are accepted.
///
@ -40,6 +40,11 @@ pub struct TraitDef {
/// also have already switched to the new trait solver.
pub is_coinductive: bool,
/// If `true`, then this trait has the `#[fundamental]` attribute. This
/// affects how conherence computes whether a trait may have trait implementations
/// added in the future.
pub is_fundamental: bool,
/// If `true`, then this trait has the `#[rustc_skip_during_method_dispatch(array)]`
/// attribute, indicating that editions before 2021 should not consider this trait
/// during method dispatch if the receiver is an array.