Skip to content

Commit

Permalink
Auto merge of rust-lang#132035 - matthiaskrgr:rollup-ty1e4q0, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#125205 (Fixup Windows verbatim paths when used with the `include!` macro)
 - rust-lang#131049 (Validate args are correct for `UnevaluatedConst`, `ExistentialTraitRef`/`ExistentialProjection`)
 - rust-lang#131549 (Add a note for `?` on a `impl Future<Output = Result<..>>` in sync function)
 - rust-lang#131731 (add `TestFloatParse` to `tools.rs` for bootstrap)
 - rust-lang#131732 (Add doc(plugins), doc(passes), etc. to INVALID_DOC_ATTRIBUTES)
 - rust-lang#132006 (don't stage-off to previous compiler when CI rustc is available)
 - rust-lang#132022 (Move `cmp_in_dominator_order` out of graph dominator computation)
 - rust-lang#132033 (compiletest: Make `line_directive` return a `DirectiveLine`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 22, 2024
2 parents bca5fde + 6db5f33 commit 86d69c7
Show file tree
Hide file tree
Showing 35 changed files with 473 additions and 253 deletions.
23 changes: 1 addition & 22 deletions compiler/rustc_data_structures/src/graph/dominators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
//! Thomas Lengauer and Robert Endre Tarjan.
//! <https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf>
use std::cmp::Ordering;

use rustc_index::{Idx, IndexSlice, IndexVec};

use super::ControlFlowGraph;
Expand Down Expand Up @@ -64,9 +62,6 @@ fn is_small_path_graph<G: ControlFlowGraph>(g: &G) -> bool {
}

fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
// compute the post order index (rank) for each node
let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());

// We allocate capacity for the full set of nodes, because most of the time
// most of the nodes *are* reachable.
let mut parent: IndexVec<PreorderIndex, PreorderIndex> =
Expand All @@ -83,12 +78,10 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
pre_order_to_real.push(graph.start_node());
parent.push(PreorderIndex::ZERO); // the parent of the root node is the root for now.
real_to_pre_order[graph.start_node()] = Some(PreorderIndex::ZERO);
let mut post_order_idx = 0;

// Traverse the graph, collecting a number of things:
//
// * Preorder mapping (to it, and back to the actual ordering)
// * Postorder mapping (used exclusively for `cmp_in_dominator_order` on the final product)
// * Parents for each vertex in the preorder tree
//
// These are all done here rather than through one of the 'standard'
Expand All @@ -104,8 +97,6 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
continue 'recurse;
}
}
post_order_rank[pre_order_to_real[frame.pre_order_idx]] = post_order_idx;
post_order_idx += 1;

stack.pop();
}
Expand Down Expand Up @@ -282,7 +273,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {

let time = compute_access_time(start_node, &immediate_dominators);

Inner { post_order_rank, immediate_dominators, time }
Inner { immediate_dominators, time }
}

/// Evaluate the link-eval virtual forest, providing the currently minimum semi
Expand Down Expand Up @@ -348,7 +339,6 @@ fn compress(
/// Tracks the list of dominators for each node.
#[derive(Clone, Debug)]
struct Inner<N: Idx> {
post_order_rank: IndexVec<N, usize>,
// Even though we track only the immediate dominator of each node, it's
// possible to get its full list of dominators by looking up the dominator
// of each dominator.
Expand Down Expand Up @@ -379,17 +369,6 @@ impl<Node: Idx> Dominators<Node> {
}
}

/// Provide deterministic ordering of nodes such that, if any two nodes have a dominator
/// relationship, the dominator will always precede the dominated. (The relative ordering
/// of two unrelated nodes will also be consistent, but otherwise the order has no
/// meaning.) This method cannot be used to determine if either Node dominates the other.
pub fn cmp_in_dominator_order(&self, lhs: Node, rhs: Node) -> Ordering {
match &self.kind {
Kind::Path => lhs.index().cmp(&rhs.index()),
Kind::General(g) => g.post_order_rank[rhs].cmp(&g.post_order_rank[lhs]),
}
}

/// Returns true if `a` dominates `b`.
///
/// # Panics
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::default::Default;
use std::iter;
use std::path::Component::Prefix;
use std::path::{Path, PathBuf};
use std::rc::Rc;

Expand Down Expand Up @@ -1293,7 +1294,12 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
base_path.push(path);
Ok(base_path)
} else {
Ok(path)
// This ensures that Windows verbatim paths are fixed if mixed path separators are used,
// which can happen when `concat!` is used to join paths.
match path.components().next() {
Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
_ => Ok(path),
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
})
.collect();
let args = tcx.mk_args(&args);

let span = i.bottom().1;
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
Expand Down Expand Up @@ -292,7 +291,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.emit();
}

ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args)
})
});

Expand Down
28 changes: 21 additions & 7 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, ErrorGuaranteed, StashKey, Subdiagnostic, pluralize, struct_span_code_err,
Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, pluralize,
struct_span_code_err,
};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -2763,12 +2764,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field_ident.span,
"field not available in `impl Future`, but it is available in its `Output`",
);
err.span_suggestion_verbose(
base.span.shrink_to_hi(),
"consider `await`ing on the `Future` and access the field of its `Output`",
".await",
Applicability::MaybeIncorrect,
);
match self.tcx.coroutine_kind(self.body_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
err.span_suggestion_verbose(
base.span.shrink_to_hi(),
"consider `await`ing on the `Future` to access the field",
".await",
Applicability::MaybeIncorrect,
);
}
_ => {
let mut span: MultiSpan = base.span.into();
span.push_span_label(self.tcx.def_span(self.body_id), "this is not `async`");
err.span_note(
span,
"this implements `Future` and its output type has the field, \
but the future cannot be awaited in a synchronous function",
);
}
}
}

fn ban_nonexisting_field(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl<'tcx> Const<'tcx> {

#[inline]
pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> {
tcx.debug_assert_args_compatible(uv.def, uv.args);
Const::new(tcx, ty::ConstKind::Unevaluated(uv))
}

Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.debug_assert_args_compatible(def_id, args);
}

/// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
/// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
/// a dummy self type and forward to `debug_assert_args_compatible`.
fn debug_assert_existential_args_compatible(
self,
def_id: Self::DefId,
args: Self::GenericArgs,
) {
// FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
// to avoid needing to reintern the set of args...
if cfg!(debug_assertions) {
self.debug_assert_args_compatible(
def_id,
self.mk_args_from_iter(
[self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
),
);
}
}

fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
Expand Down
25 changes: 23 additions & 2 deletions compiler/rustc_mir_transform/src/coverage/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub(crate) struct CoverageGraph {
pub(crate) successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
pub(crate) predecessors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
dominators: Option<Dominators<BasicCoverageBlock>>,
/// Allows nodes to be compared in some total order such that _if_
/// `a` dominates `b`, then `a < b`. If neither node dominates the other,
/// their relative order is consistent but arbitrary.
dominator_order_rank: IndexVec<BasicCoverageBlock, u32>,
}

impl CoverageGraph {
Expand Down Expand Up @@ -54,10 +58,27 @@ impl CoverageGraph {
}
}

let mut this = Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
let num_nodes = bcbs.len();
let mut this = Self {
bcbs,
bb_to_bcb,
successors,
predecessors,
dominators: None,
dominator_order_rank: IndexVec::from_elem_n(0, num_nodes),
};
assert_eq!(num_nodes, this.num_nodes());

this.dominators = Some(dominators::dominators(&this));

// The dominator rank of each node is just its index in a reverse-postorder traversal.
let reverse_post_order = graph::iterate::reverse_post_order(&this, this.start_node());
// The coverage graph is created by traversal, so all nodes are reachable.
assert_eq!(reverse_post_order.len(), this.num_nodes());
for (rank, bcb) in (0u32..).zip(reverse_post_order) {
this.dominator_order_rank[bcb] = rank;
}

// The coverage graph's entry-point node (bcb0) always starts with bb0,
// which never has predecessors. Any other blocks merged into bcb0 can't
// have multiple (coverage-relevant) predecessors, so bcb0 always has
Expand Down Expand Up @@ -162,7 +183,7 @@ impl CoverageGraph {
a: BasicCoverageBlock,
b: BasicCoverageBlock,
) -> Ordering {
self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
self.dominator_order_rank[a].cmp(&self.dominator_order_rank[b])
}

/// Returns the source of this node's sole in-edge, if it has exactly one.
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,19 @@ passes_doc_test_unknown_include =
unknown `doc` attribute `{$path}`
.suggestion = use `doc = include_str!` instead
passes_doc_test_unknown_passes =
unknown `doc` attribute `{$path}`
.note = `doc` attribute `{$path}` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136>
.label = no longer functions
.help = you may want to use `doc(document_private_items)`
.no_op_note = `doc({$path})` is now a no-op
passes_doc_test_unknown_plugins =
unknown `doc` attribute `{$path}`
.note = `doc` attribute `{$path}` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> and CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>
.label = no longer functions
.no_op_note = `doc({$path})` is now a no-op
passes_doc_test_unknown_spotlight =
unknown `doc` attribute `{$path}`
.note = `doc(spotlight)` was renamed to `doc(notable_trait)`
Expand Down
26 changes: 17 additions & 9 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,15 +1183,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {

sym::masked => self.check_doc_masked(attr, meta, hir_id, target),

// no_default_passes: deprecated
// passes: deprecated
// plugins: removed, but rustdoc warns about it itself
sym::cfg
| sym::hidden
| sym::no_default_passes
| sym::notable_trait
| sym::passes
| sym::plugins => {}
sym::cfg | sym::hidden | sym::notable_trait => {}

sym::rust_logo => {
if self.check_attr_crate_level(attr, meta, hir_id)
Expand Down Expand Up @@ -1240,6 +1232,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
sugg: (attr.meta().unwrap().span, applicability),
},
);
} else if i_meta.has_name(sym::passes)
|| i_meta.has_name(sym::no_default_passes)
{
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span,
errors::DocTestUnknownPasses { path, span: i_meta.span },
);
} else if i_meta.has_name(sym::plugins) {
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span,
errors::DocTestUnknownPlugins { path, span: i_meta.span },
);
} else {
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,27 @@ pub(crate) struct DocTestUnknownSpotlight {
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_doc_test_unknown_passes)]
#[note]
#[help]
#[note(passes_no_op_note)]
pub(crate) struct DocTestUnknownPasses {
pub path: String,
#[label]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_doc_test_unknown_plugins)]
#[note]
#[note(passes_no_op_note)]
pub(crate) struct DocTestUnknownPlugins {
pub path: String,
#[label]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_doc_test_unknown_include)]
pub(crate) struct DocTestUnknownInclude {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl<'tcx> ReachableContext<'tcx> {
self.visit(ty);
// Manually visit to actually see the trait's `DefId`. Type visitors won't see it
if let Some(trait_ref) = dyn_ty.principal() {
let ExistentialTraitRef { def_id, args } = trait_ref.skip_binder();
let ExistentialTraitRef { def_id, args, .. } = trait_ref.skip_binder();
self.visit_def_id(def_id, "", &"");
self.visit(args);
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility,
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{
self, Const, GenericArgs, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
TypeVisitable, TypeVisitor,
self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitor,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
Expand Down Expand Up @@ -246,10 +246,10 @@ where
ty::ExistentialPredicate::Trait(trait_ref) => trait_ref,
ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
ty::ExistentialPredicate::AutoTrait(def_id) => {
ty::ExistentialTraitRef { def_id, args: GenericArgs::empty() }
ty::ExistentialTraitRef::new(tcx, def_id, ty::GenericArgs::empty())
}
};
let ty::ExistentialTraitRef { def_id, args: _ } = trait_ref;
let ty::ExistentialTraitRef { def_id, .. } = trait_ref;
try_visit!(self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,15 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
alias_ty.to_ty(tcx),
);
debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx));
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
def_id: assoc_ty.def_id,
args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args,
term: resolved.into(),
})
ty::ExistentialPredicate::Projection(
ty::ExistentialProjection::erase_self_ty(
tcx,
ty::ProjectionPredicate {
projection_term: alias_ty.into(),
term: resolved.into(),
},
),
)
})
})
})
Expand Down Expand Up @@ -318,10 +322,11 @@ pub(crate) fn transform_instance<'tcx>(
.lang_items()
.drop_trait()
.unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new_from_args(
tcx,
def_id,
args: List::empty(),
});
ty::List::empty(),
));
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
instance.args = tcx.mk_args_trait(self_ty, List::empty());
Expand Down
Loading

0 comments on commit 86d69c7

Please sign in to comment.