Skip to content

Commit ed311ef

Browse files
committed
Auto merge of rust-lang#129126 - GuillaumeGomez:rollup-abnvlgj, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - rust-lang#128348 (Unconditionally allow shadow call-stack sanitizer for AArch64) - rust-lang#128922 (rust-analyzer: use in-tree `pattern_analysis` crate) - rust-lang#128935 (More work on `zstd` compression) - rust-lang#129072 (Infer async closure args from `Fn` bound even if there is no corresponding `Future` bound on return) - rust-lang#129101 (Fix projections when parent capture is by-ref but child capture is by-value in the `ByMoveBody` pass) - rust-lang#129106 (Remove redundant type ops: `Eq`/`Subtype`) - rust-lang#129122 (Remove duplicated `Rustdoc::output` method from `run-make-support` lib) - rust-lang#129124 (rustdoc-json: Use FxHashMap from rustdoc_json_types) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d2b5aa6 + 38c9f38 commit ed311ef

File tree

43 files changed

+408
-234
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+408
-234
lines changed

compiler/rustc_hir_typeck/src/closure.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::span_bug;
1414
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
1515
use rustc_middle::ty::{self, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
1616
use rustc_span::def_id::LocalDefId;
17-
use rustc_span::Span;
17+
use rustc_span::{Span, DUMMY_SP};
1818
use rustc_target::spec::abi::Abi;
1919
use rustc_trait_selection::error_reporting::traits::ArgKind;
2020
use rustc_trait_selection::traits;
@@ -539,6 +539,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
539539
/// we identify the `FnOnce<Args, Output = ?Fut>` bound, and if the output type is
540540
/// an inference variable `?Fut`, we check if that is bounded by a `Future<Output = Ty>`
541541
/// projection.
542+
///
543+
/// This function is actually best-effort with the return type; if we don't find a
544+
/// `Future` projection, we still will return arguments that we extracted from the `FnOnce`
545+
/// projection, and the output will be an unconstrained type variable instead.
542546
fn extract_sig_from_projection_and_future_bound(
543547
&self,
544548
cause_span: Option<Span>,
@@ -564,24 +568,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
564568
};
565569

566570
// FIXME: We may want to elaborate here, though I assume this will be exceedingly rare.
571+
let mut return_ty = None;
567572
for bound in self.obligations_for_self_ty(return_vid) {
568573
if let Some(ret_projection) = bound.predicate.as_projection_clause()
569574
&& let Some(ret_projection) = ret_projection.no_bound_vars()
570575
&& self.tcx.is_lang_item(ret_projection.def_id(), LangItem::FutureOutput)
571576
{
572-
let sig = projection.rebind(self.tcx.mk_fn_sig(
573-
input_tys,
574-
ret_projection.term.expect_type(),
575-
false,
576-
hir::Safety::Safe,
577-
Abi::Rust,
578-
));
579-
580-
return Some(ExpectedSig { cause_span, sig });
577+
return_ty = Some(ret_projection.term.expect_type());
578+
break;
581579
}
582580
}
583581

584-
None
582+
// SUBTLE: If we didn't find a `Future<Output = ...>` bound for the return
583+
// vid, we still want to attempt to provide inference guidance for the async
584+
// closure's arguments. Instantiate a new vid to plug into the output type.
585+
//
586+
// You may be wondering, what if it's higher-ranked? Well, given that we
587+
// found a type variable for the `FnOnce::Output` projection above, we know
588+
// that the output can't mention any of the vars.
589+
//
590+
// Also note that we use a fresh var here for the signature since the signature
591+
// records the output of the *future*, and `return_vid` above is the type
592+
// variable of the future, not its output.
593+
//
594+
// FIXME: We probably should store this signature inference output in a way
595+
// that does not misuse a `FnSig` type, but that can be done separately.
596+
let return_ty =
597+
return_ty.unwrap_or_else(|| self.next_ty_var(cause_span.unwrap_or(DUMMY_SP)));
598+
599+
let sig = projection.rebind(self.tcx.mk_fn_sig(
600+
input_tys,
601+
return_ty,
602+
false,
603+
hir::Safety::Safe,
604+
Abi::Rust,
605+
));
606+
607+
return Some(ExpectedSig { cause_span, sig });
585608
}
586609

587610
fn sig_of_closure(

compiler/rustc_middle/src/query/mod.rs

+3-24
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ use crate::query::plumbing::{
6565
};
6666
use crate::traits::query::{
6767
CanonicalAliasGoal, CanonicalPredicateGoal, CanonicalTyGoal,
68-
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
69-
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, DropckConstraint,
70-
DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
71-
OutlivesBound,
68+
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal,
69+
CanonicalTypeOpProvePredicateGoal, DropckConstraint, DropckOutlivesResult,
70+
MethodAutoderefStepsResult, NoSolution, NormalizationResult, OutlivesBound,
7271
};
7372
use crate::traits::{
7473
specialization_graph, CodegenObligationError, EvaluationResult, ImplSource,
@@ -2090,26 +2089,6 @@ rustc_queries! {
20902089
desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value }
20912090
}
20922091

2093-
/// Do not call this query directly: part of the `Eq` type-op
2094-
query type_op_eq(
2095-
goal: CanonicalTypeOpEqGoal<'tcx>
2096-
) -> Result<
2097-
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
2098-
NoSolution,
2099-
> {
2100-
desc { "evaluating `type_op_eq` `{:?}`", goal.value.value }
2101-
}
2102-
2103-
/// Do not call this query directly: part of the `Subtype` type-op
2104-
query type_op_subtype(
2105-
goal: CanonicalTypeOpSubtypeGoal<'tcx>
2106-
) -> Result<
2107-
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
2108-
NoSolution,
2109-
> {
2110-
desc { "evaluating `type_op_subtype` `{:?}`", goal.value.value }
2111-
}
2112-
21132092
/// Do not call this query directly: part of the `ProvePredicate` type-op
21142093
query type_op_prove_predicate(
21152094
goal: CanonicalTypeOpProvePredicateGoal<'tcx>

compiler/rustc_mir_transform/src/coroutine/by_move_body.rs

+40-14
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ use rustc_middle::mir::{self, dump_mir, MirPass};
7878
use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
7979
use rustc_target::abi::{FieldIdx, VariantIdx};
8080

81+
use crate::pass_manager::validate_body;
82+
8183
pub struct ByMoveBody;
8284

8385
impl<'tcx> MirPass<'tcx> for ByMoveBody {
@@ -131,20 +133,40 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
131133
|(parent_field_idx, parent_capture), (child_field_idx, child_capture)| {
132134
// Store this set of additional projections (fields and derefs).
133135
// We need to re-apply them later.
134-
let child_precise_captures =
135-
&child_capture.place.projections[parent_capture.place.projections.len()..];
136+
let mut child_precise_captures = child_capture.place.projections
137+
[parent_capture.place.projections.len()..]
138+
.to_vec();
136139

137-
// If the parent captures by-move, and the child captures by-ref, then we
138-
// need to peel an additional `deref` off of the body of the child.
139-
let needs_deref = child_capture.is_by_ref() && !parent_capture.is_by_ref();
140-
if needs_deref {
141-
assert_ne!(
142-
coroutine_kind,
143-
ty::ClosureKind::FnOnce,
140+
// If the parent capture is by-ref, then we need to apply an additional
141+
// deref before applying any further projections to this place.
142+
if parent_capture.is_by_ref() {
143+
child_precise_captures.insert(
144+
0,
145+
Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref },
146+
);
147+
}
148+
// If the child capture is by-ref, then we need to apply a "ref"
149+
// projection (i.e. `&`) at the end. But wait! We don't have that
150+
// as a projection kind. So instead, we can apply its dual and
151+
// *peel* a deref off of the place when it shows up in the MIR body.
152+
// Luckily, by construction this is always possible.
153+
let peel_deref = if child_capture.is_by_ref() {
154+
assert!(
155+
parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce,
144156
"`FnOnce` coroutine-closures return coroutines that capture from \
145157
their body; it will always result in a borrowck error!"
146158
);
147-
}
159+
true
160+
} else {
161+
false
162+
};
163+
164+
// Regarding the behavior above, you may think that it's redundant to both
165+
// insert a deref and then peel a deref if the parent and child are both
166+
// captured by-ref. This would be correct, except for the case where we have
167+
// precise capturing projections, since the inserted deref is to the *beginning*
168+
// and the peeled deref is at the *end*. I cannot seem to actually find a
169+
// case where this happens, though, but let's keep this code flexible.
148170

149171
// Finally, store the type of the parent's captured place. We need
150172
// this when building the field projection in the MIR body later on.
@@ -164,7 +186,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
164186
(
165187
FieldIdx::from_usize(parent_field_idx + num_args),
166188
parent_capture_ty,
167-
needs_deref,
189+
peel_deref,
168190
child_precise_captures,
169191
),
170192
)
@@ -192,6 +214,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
192214
let mut by_move_body = body.clone();
193215
MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
194216
dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(()));
217+
218+
// Let's just always validate this body.
219+
validate_body(tcx, &mut by_move_body, "Initial coroutine_by_move body".to_string());
220+
195221
// FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body.
196222
by_move_body.source = mir::MirSource::from_instance(InstanceKind::CoroutineKindShim {
197223
coroutine_def_id: coroutine_def_id.to_def_id(),
@@ -202,7 +228,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
202228

203229
struct MakeByMoveBody<'tcx> {
204230
tcx: TyCtxt<'tcx>,
205-
field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, &'tcx [Projection<'tcx>])>,
231+
field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, Vec<Projection<'tcx>>)>,
206232
by_move_coroutine_ty: Ty<'tcx>,
207233
}
208234

@@ -223,14 +249,14 @@ impl<'tcx> MutVisitor<'tcx> for MakeByMoveBody<'tcx> {
223249
if place.local == ty::CAPTURE_STRUCT_LOCAL
224250
&& let Some((&mir::ProjectionElem::Field(idx, _), projection)) =
225251
place.projection.split_first()
226-
&& let Some(&(remapped_idx, remapped_ty, needs_deref, bridging_projections)) =
252+
&& let Some(&(remapped_idx, remapped_ty, peel_deref, ref bridging_projections)) =
227253
self.field_remapping.get(&idx)
228254
{
229255
// As noted before, if the parent closure captures a field by value, and
230256
// the child captures a field by ref, then for the by-move body we're
231257
// generating, we also are taking that field by value. Peel off a deref,
232258
// since a layer of ref'ing has now become redundant.
233-
let final_projections = if needs_deref {
259+
let final_projections = if peel_deref {
234260
let Some((mir::ProjectionElem::Deref, projection)) = projection.split_first()
235261
else {
236262
bug!(

compiler/rustc_session/src/session.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11881188

11891189
// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
11901190
let supported_sanitizers = sess.target.options.supported_sanitizers;
1191-
let unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers;
1191+
let mut unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers;
1192+
// Niche: if `fixed-x18`, or effectively switching on `reserved-x18` flag, is enabled
1193+
// we should allow Shadow Call Stack sanitizer.
1194+
if sess.opts.unstable_opts.fixed_x18 && sess.target.arch == "aarch64" {
1195+
unsupported_sanitizers -= SanitizerSet::SHADOWCALLSTACK;
1196+
}
11921197
match unsupported_sanitizers.into_iter().count() {
11931198
0 => {}
11941199
1 => {

compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs

-33
This file was deleted.

compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ use crate::traits::{ObligationCause, ObligationCtxt};
1616

1717
pub mod ascribe_user_type;
1818
pub mod custom;
19-
pub mod eq;
2019
pub mod implied_outlives_bounds;
2120
pub mod normalize;
2221
pub mod outlives;
2322
pub mod prove_predicate;
24-
pub mod subtype;
2523

2624
pub use rustc_middle::traits::query::type_op::*;
2725

compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs

-30
This file was deleted.

compiler/rustc_traits/src/type_op.rs

-24
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,14 @@ use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
1010
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
1111
type_op_ascribe_user_type_with_span, AscribeUserType,
1212
};
13-
use rustc_trait_selection::traits::query::type_op::eq::Eq;
1413
use rustc_trait_selection::traits::query::type_op::normalize::Normalize;
1514
use rustc_trait_selection::traits::query::type_op::prove_predicate::ProvePredicate;
16-
use rustc_trait_selection::traits::query::type_op::subtype::Subtype;
1715
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt};
1816

1917
pub(crate) fn provide(p: &mut Providers) {
2018
*p = Providers {
2119
type_op_ascribe_user_type,
22-
type_op_eq,
2320
type_op_prove_predicate,
24-
type_op_subtype,
2521
type_op_normalize_ty,
2622
type_op_normalize_clause,
2723
type_op_normalize_fn_sig,
@@ -39,16 +35,6 @@ fn type_op_ascribe_user_type<'tcx>(
3935
})
4036
}
4137

42-
fn type_op_eq<'tcx>(
43-
tcx: TyCtxt<'tcx>,
44-
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,
45-
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
46-
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
47-
let (param_env, Eq { a, b }) = key.into_parts();
48-
Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?)
49-
})
50-
}
51-
5238
fn type_op_normalize<'tcx, T>(
5339
ocx: &ObligationCtxt<'_, 'tcx>,
5440
key: ParamEnvAnd<'tcx, Normalize<T>>,
@@ -91,16 +77,6 @@ fn type_op_normalize_poly_fn_sig<'tcx>(
9177
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
9278
}
9379

94-
fn type_op_subtype<'tcx>(
95-
tcx: TyCtxt<'tcx>,
96-
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>,
97-
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
98-
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
99-
let (param_env, Subtype { sub, sup }) = key.into_parts();
100-
Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?)
101-
})
102-
}
103-
10480
fn type_op_prove_predicate<'tcx>(
10581
tcx: TyCtxt<'tcx>,
10682
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>,

src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
6262
RUN ./build-clang.sh
6363
ENV CC=clang CXX=clang++
6464

65-
# rustc's LLVM needs zstd.
66-
COPY scripts/zstd.sh /tmp/
67-
RUN ./zstd.sh
65+
# Build zstd to enable `llvm.libzstd`.
66+
COPY host-x86_64/dist-x86_64-linux/build-zstd.sh /tmp/
67+
RUN ./build-zstd.sh
6868

6969
COPY scripts/sccache.sh /scripts/
7070
RUN sh /scripts/sccache.sh

src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ ENV RUST_CONFIGURE_ARGS \
2828
--build=x86_64-unknown-linux-gnu \
2929
--enable-sanitizers \
3030
--enable-profiler \
31-
--enable-compiler-docs
31+
--enable-compiler-docs \
32+
--set llvm.libzstd=true
3233
ENV SCRIPT python3 ../x.py --stage 2 test

src/doc/rustc/src/platform-support/android.md

+5
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,8 @@ Currently the `riscv64-linux-android` target requires the following architecture
6161
* `Zba` (address calculation instructions)
6262
* `Zbb` (base instructions)
6363
* `Zbs` (single-bit instructions)
64+
65+
### aarch64-linux-android on Nightly compilers
66+
67+
As soon as `-Zfixed-x18` compiler flag is supplied, the [`ShadowCallStack` sanitizer](https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html)
68+
instrumentation is also made avaiable by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`.

0 commit comments

Comments
 (0)