Skip to content

Commit

Permalink
Auto merge of #123968 - jieyouxu:rollup-1pnkxor, r=jieyouxu
Browse files Browse the repository at this point in the history
Rollup of 12 pull requests

Successful merges:

 - #123423 (Distribute LLVM bitcode linker as a preview component)
 - #123548 (libtest: also measure time in Miri)
 - #123666 (Fix some typos in doc)
 - #123864 (Remove a HACK by instead inferring opaque types during expected/formal type checking)
 - #123896 (Migrate some diagnostics in `rustc_resolve` to session diagnostic)
 - #123919 (builtin-derive: tag → discriminant)
 - #123922 (Remove magic constants when using `base_n`.)
 - #123931 (Don't leak unnameable types in `-> _` recover)
 - #123933 (move the LargeAssignments lint logic into its own file)
 - #123934 (`rustc_data_structures::graph` mini refactor)
 - #123941 (Fix UB in LLVM FFI when passing zero or >1 bundle)
 - #123957 (disable create_dir_all_bare test on all(miri, windows))

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 15, 2024
2 parents 0230848 + 723c0e2 commit 99d0186
Show file tree
Hide file tree
Showing 53 changed files with 1,318 additions and 795 deletions.
13 changes: 2 additions & 11 deletions compiler/rustc_borrowck/src/constraints/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,23 +216,14 @@ impl<'s, 'tcx, D: ConstraintGraphDirection> Iterator for Successors<'s, 'tcx, D>

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::DirectedGraph for RegionGraph<'s, 'tcx, D> {
type Node = RegionVid;
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithNumNodes for RegionGraph<'s, 'tcx, D> {
fn num_nodes(&self) -> usize {
self.constraint_graph.first_constraints.len()
}
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithSuccessors for RegionGraph<'s, 'tcx, D> {
fn successors(&self, node: Self::Node) -> <Self as graph::GraphSuccessors<'_>>::Iter {
impl<'s, 'tcx, D: ConstraintGraphDirection> graph::Successors for RegionGraph<'s, 'tcx, D> {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
self.outgoing_regions(node)
}
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::GraphSuccessors<'_>
for RegionGraph<'s, 'tcx, D>
{
type Item = RegionVid;
type Iter = Successors<'s, 'tcx, D>;
}
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::WithSuccessors;
use rustc_data_structures::graph;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{
self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges,
Expand Down Expand Up @@ -262,7 +262,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {

// We first handle the cases where the loan doesn't go out of scope, depending on the issuing
// region's successors.
for successor in self.regioncx.region_graph().depth_first_search(issuing_region) {
for successor in graph::depth_first_search(&self.regioncx.region_graph(), issuing_region) {
// 1. Via applied member constraints
//
// The issuing region can flow into the choice regions, and they are either:
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::constraints::ConstraintSccIndex;
use crate::RegionInferenceContext;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph;
use rustc_data_structures::graph::vec_graph::VecGraph;
use rustc_data_structures::graph::WithSuccessors;
use rustc_middle::ty::RegionVid;
use std::ops::Range;

Expand All @@ -23,8 +23,7 @@ impl ReverseSccGraph {
scc0: ConstraintSccIndex,
) -> impl Iterator<Item = RegionVid> + 'a {
let mut duplicates = FxIndexSet::default();
self.graph
.depth_first_search(scc0)
graph::depth_first_search(&self.graph, scc0)
.flat_map(move |scc1| {
self.scc_regions
.get(&scc1)
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::WithSuccessors;
use rustc_index::bit_set::BitSet;
use rustc_index::interval::IntervalSet;
use rustc_infer::infer::canonical::QueryRegionConstraints;
Expand Down Expand Up @@ -64,7 +63,10 @@ pub(super) fn trace<'mir, 'tcx>(
// Traverse each issuing region's constraints, and record the loan as flowing into the
// outlived region.
for (loan, issuing_region_data) in borrow_set.iter_enumerated() {
for succ in region_graph.depth_first_search(issuing_region_data.region) {
for succ in rustc_data_structures::graph::depth_first_search(
&region_graph,
issuing_region_data.region,
) {
// We don't need to mention that a loan flows into its issuing region.
if succ == issuing_region_data.region {
continue;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ fn cs_clone(
all_fields = af;
vdata = &variant.data;
}
EnumTag(..) | AllFieldlessEnum(..) => {
cx.dcx().span_bug(trait_span, format!("enum tags in `derive({name})`",))
EnumDiscr(..) | AllFieldlessEnum(..) => {
cx.dcx().span_bug(trait_span, format!("enum discriminants in `derive({name})`",))
}
StaticEnum(..) | StaticStruct(..) => {
cx.dcx().span_bug(trait_span, format!("associated function in `derive({name})`"))
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ pub fn expand_deriving_partial_ord(
Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std));

// Order in which to perform matching
let tag_then_data = if let Annotatable::Item(item) = item
let discr_then_data = if let Annotatable::Item(item) = item
&& let ItemKind::Enum(def, _) = &item.kind
{
let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect();
match dataful.iter().filter(|&&b| b).count() {
// No data, placing the tag check first makes codegen simpler
// No data, placing the discriminant check first makes codegen simpler
0 => true,
1..=2 => false,
_ => (0..dataful.len() - 1).any(|i| {
Expand All @@ -50,7 +50,7 @@ pub fn expand_deriving_partial_ord(
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr, tag_then_data)
cs_partial_cmp(cx, span, substr, discr_then_data)
})),
};

Expand All @@ -72,7 +72,7 @@ fn cs_partial_cmp(
cx: &ExtCtxt<'_>,
span: Span,
substr: &Substructure<'_>,
tag_then_data: bool,
discr_then_data: bool,
) -> BlockOrExpr {
let test_id = Ident::new(sym::cmp, span);
let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
Expand Down Expand Up @@ -108,12 +108,12 @@ fn cs_partial_cmp(
// cmp => cmp
// }
// ```
// where `expr2` is `partial_cmp(self_tag, other_tag)`, and `expr1` is a `match`
// against the enum variants. This means that we begin by comparing the enum tags,
// where `expr2` is `partial_cmp(self_discr, other_discr)`, and `expr1` is a `match`
// against the enum variants. This means that we begin by comparing the enum discriminants,
// before either inspecting their contents (if they match), or returning
// the `cmp::Ordering` of comparing the enum tags.
// the `cmp::Ordering` of comparing the enum discriminants.
// ```
// match partial_cmp(self_tag, other_tag) {
// match partial_cmp(self_discr, other_discr) {
// Some(Ordering::Equal) => match (self, other) {
// (Self::A(self_0), Self::A(other_0)) => partial_cmp(self_0, other_0),
// (Self::B(self_0), Self::B(other_0)) => partial_cmp(self_0, other_0),
Expand All @@ -126,12 +126,12 @@ fn cs_partial_cmp(
// ```
// match (self, other) {
// (Self::A(self_0), Self::A(other_0)) => partial_cmp(self_0, other_0),
// _ => partial_cmp(self_tag, other_tag)
// _ => partial_cmp(self_discr, other_discr)
// }
// ```
// Reference: https://github.com/rust-lang/rust/pull/103659#issuecomment-1328126354

if !tag_then_data
if !discr_then_data
&& let ExprKind::Match(_, arms, _) = &mut expr1.kind
&& let Some(last) = arms.last_mut()
&& let PatKind::Wild = last.pat.kind
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, v, fields) => (v.ident, &v.data, fields),
AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr),
EnumTag(..) | StaticStruct(..) | StaticEnum(..) => {
EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => {
cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
}
};
Expand Down
88 changes: 44 additions & 44 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
//! `struct T(i32, char)`).
//! - `EnumMatching`, when `Self` is an enum and all the arguments are the
//! same variant of the enum (e.g., `Some(1)`, `Some(3)` and `Some(4)`)
//! - `EnumTag` when `Self` is an enum, for comparing the enum tags.
//! - `EnumDiscr` when `Self` is an enum, for comparing the enum discriminants.
//! - `StaticEnum` and `StaticStruct` for static methods, where the type
//! being derived upon is either an enum or struct respectively. (Any
//! argument with type Self is just grouped among the non-self
Expand Down Expand Up @@ -143,11 +143,11 @@
//! )
//! ```
//!
//! For the tags,
//! For the discriminants,
//!
//! ```text
//! EnumTag(
//! &[<ident of self tag>, <ident of other tag>],
//! EnumDiscr(
//! &[<ident of self discriminant>, <ident of other discriminant>],
//! <expr to combine with>,
//! )
//! ```
Expand Down Expand Up @@ -315,10 +315,10 @@ pub enum SubstructureFields<'a> {
/// variant.
EnumMatching(usize, &'a ast::Variant, Vec<FieldInfo>),

/// The tag of an enum. The first field is a `FieldInfo` for the tags, as
/// The discriminant of an enum. The first field is a `FieldInfo` for the discriminants, as
/// if they were fields. The second field is the expression to combine the
/// tag expression with; it will be `None` if no match is necessary.
EnumTag(FieldInfo, Option<P<Expr>>),
/// discriminant expression with; it will be `None` if no match is necessary.
EnumDiscr(FieldInfo, Option<P<Expr>>),

/// A static method where `Self` is a struct.
StaticStruct(&'a ast::VariantData, StaticFields),
Expand Down Expand Up @@ -1137,9 +1137,9 @@ impl<'a> MethodDef<'a> {
/// impl ::core::cmp::PartialEq for A {
/// #[inline]
/// fn eq(&self, other: &A) -> bool {
/// let __self_tag = ::core::intrinsics::discriminant_value(self);
/// let __arg1_tag = ::core::intrinsics::discriminant_value(other);
/// __self_tag == __arg1_tag
/// let __self_discr = ::core::intrinsics::discriminant_value(self);
/// let __arg1_discr = ::core::intrinsics::discriminant_value(other);
/// __self_discr == __arg1_discr
/// && match (self, other) {
/// (A::A2(__self_0), A::A2(__arg1_0)) => *__self_0 == *__arg1_0,
/// _ => true,
Expand All @@ -1148,7 +1148,7 @@ impl<'a> MethodDef<'a> {
/// }
/// ```
///
/// Creates a tag check combined with a match for a tuple of all
/// Creates a discriminant check combined with a match for a tuple of all
/// `selflike_args`, with an arm for each variant with fields, possibly an
/// arm for each fieldless variant (if `unify_fieldless_variants` is not
/// `Unify`), and possibly a default arm.
Expand All @@ -1169,7 +1169,7 @@ impl<'a> MethodDef<'a> {
let span = trait_.span;
let variants = &enum_def.variants;

// Traits that unify fieldless variants always use the tag(s).
// Traits that unify fieldless variants always use the discriminant(s).
let unify_fieldless_variants =
self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify;

Expand Down Expand Up @@ -1199,25 +1199,25 @@ impl<'a> MethodDef<'a> {
//
// e.g. for `PartialEq::eq` builds two statements:
// ```
// let __self_tag = ::core::intrinsics::discriminant_value(self);
// let __arg1_tag = ::core::intrinsics::discriminant_value(other);
// let __self_discr = ::core::intrinsics::discriminant_value(self);
// let __arg1_discr = ::core::intrinsics::discriminant_value(other);
// ```
let get_tag_pieces = |cx: &ExtCtxt<'_>| {
let tag_idents: Vec<_> = prefixes
let get_discr_pieces = |cx: &ExtCtxt<'_>| {
let discr_idents: Vec<_> = prefixes
.iter()
.map(|name| Ident::from_str_and_span(&format!("{name}_tag"), span))
.map(|name| Ident::from_str_and_span(&format!("{name}_discr"), span))
.collect();

let mut tag_exprs: Vec<_> = tag_idents
let mut discr_exprs: Vec<_> = discr_idents
.iter()
.map(|&ident| cx.expr_addr_of(span, cx.expr_ident(span, ident)))
.collect();

let self_expr = tag_exprs.remove(0);
let other_selflike_exprs = tag_exprs;
let tag_field = FieldInfo { span, name: None, self_expr, other_selflike_exprs };
let self_expr = discr_exprs.remove(0);
let other_selflike_exprs = discr_exprs;
let discr_field = FieldInfo { span, name: None, self_expr, other_selflike_exprs };

let tag_let_stmts: ThinVec<_> = iter::zip(&tag_idents, &selflike_args)
let discr_let_stmts: ThinVec<_> = iter::zip(&discr_idents, &selflike_args)
.map(|(&ident, selflike_arg)| {
let variant_value = deriving::call_intrinsic(
cx,
Expand All @@ -1229,7 +1229,7 @@ impl<'a> MethodDef<'a> {
})
.collect();

(tag_field, tag_let_stmts)
(discr_field, discr_let_stmts)
};

// There are some special cases involving fieldless enums where no
Expand All @@ -1239,19 +1239,19 @@ impl<'a> MethodDef<'a> {
if variants.len() > 1 {
match self.fieldless_variants_strategy {
FieldlessVariantsStrategy::Unify => {
// If the type is fieldless and the trait uses the tag and
// If the type is fieldless and the trait uses the discriminant and
// there are multiple variants, we need just an operation on
// the tag(s).
let (tag_field, mut tag_let_stmts) = get_tag_pieces(cx);
let mut tag_check = self.call_substructure_method(
// the discriminant(s).
let (discr_field, mut discr_let_stmts) = get_discr_pieces(cx);
let mut discr_check = self.call_substructure_method(
cx,
trait_,
type_ident,
nonselflike_args,
&EnumTag(tag_field, None),
&EnumDiscr(discr_field, None),
);
tag_let_stmts.append(&mut tag_check.0);
return BlockOrExpr(tag_let_stmts, tag_check.1);
discr_let_stmts.append(&mut discr_check.0);
return BlockOrExpr(discr_let_stmts, discr_check.1);
}
FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => {
return self.call_substructure_method(
Expand All @@ -1266,7 +1266,7 @@ impl<'a> MethodDef<'a> {
}
} else if variants.len() == 1 {
// If there is a single variant, we don't need an operation on
// the tag(s). Just use the most degenerate result.
// the discriminant(s). Just use the most degenerate result.
return self.call_substructure_method(
cx,
trait_,
Expand Down Expand Up @@ -1380,22 +1380,22 @@ impl<'a> MethodDef<'a> {
cx.expr_match(span, match_arg, match_arms)
};

// If the trait uses the tag and there are multiple variants, we need
// to add a tag check operation before the match. Otherwise, the match
// If the trait uses the discriminant and there are multiple variants, we need
// to add a discriminant check operation before the match. Otherwise, the match
// is enough.
if unify_fieldless_variants && variants.len() > 1 {
let (tag_field, mut tag_let_stmts) = get_tag_pieces(cx);
let (discr_field, mut discr_let_stmts) = get_discr_pieces(cx);

// Combine a tag check with the match.
let mut tag_check_plus_match = self.call_substructure_method(
// Combine a discriminant check with the match.
let mut discr_check_plus_match = self.call_substructure_method(
cx,
trait_,
type_ident,
nonselflike_args,
&EnumTag(tag_field, Some(get_match_expr(selflike_args))),
&EnumDiscr(discr_field, Some(get_match_expr(selflike_args))),
);
tag_let_stmts.append(&mut tag_check_plus_match.0);
BlockOrExpr(tag_let_stmts, tag_check_plus_match.1)
discr_let_stmts.append(&mut discr_check_plus_match.0);
BlockOrExpr(discr_let_stmts, discr_check_plus_match.1)
} else {
BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args)))
}
Expand Down Expand Up @@ -1701,16 +1701,16 @@ where
rest.iter().rfold(base_expr, op)
}
}
EnumTag(tag_field, match_expr) => {
let tag_check_expr = f(cx, CsFold::Single(tag_field));
EnumDiscr(discr_field, match_expr) => {
let discr_check_expr = f(cx, CsFold::Single(discr_field));
if let Some(match_expr) = match_expr {
if use_foldl {
f(cx, CsFold::Combine(trait_span, tag_check_expr, match_expr.clone()))
f(cx, CsFold::Combine(trait_span, discr_check_expr, match_expr.clone()))
} else {
f(cx, CsFold::Combine(trait_span, match_expr.clone(), tag_check_expr))
f(cx, CsFold::Combine(trait_span, match_expr.clone(), discr_check_expr))
}
} else {
tag_check_expr
discr_check_expr
}
}
StaticEnum(..) | StaticStruct(..) => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'
fields.iter().map(|field| call_hash(field.span, field.self_expr.clone())).collect();
(stmts, None)
}
EnumTag(tag_field, match_expr) => {
assert!(tag_field.other_selflike_exprs.is_empty());
let stmts = thin_vec![call_hash(tag_field.span, tag_field.self_expr.clone())];
EnumDiscr(discr_field, match_expr) => {
assert!(discr_field.other_selflike_exprs.is_empty());
let stmts = thin_vec![call_hash(discr_field.span, discr_field.self_expr.clone())];
(stmts, match_expr.clone())
}
_ => cx.dcx().span_bug(trait_span, "impossible substructure in `derive(Hash)`"),
Expand Down
Loading

0 comments on commit 99d0186

Please sign in to comment.