Skip to content

Commit 2c93fab

Browse files
committed
Auto merge of #129130 - matthiaskrgr:rollup-603jta0, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #128348 (Unconditionally allow shadow call-stack sanitizer for AArch64) - #129065 (Use `impl PartialEq<TokenKind> for Token` more.) - #129072 (Infer async closure args from `Fn` bound even if there is no corresponding `Future` bound on return) - #129096 (Print more verbose error for commands that capture output) - #129101 (Fix projections when parent capture is by-ref but child capture is by-value in the `ByMoveBody` pass) - #129106 (Remove redundant type ops: `Eq`/`Subtype`) - #129122 (Remove duplicated `Rustdoc::output` method from `run-make-support` lib) - #129124 (rustdoc-json: Use FxHashMap from rustdoc_json_types) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d2b5aa6 + ef72a6a commit 2c93fab

File tree

50 files changed

+396
-306
lines changed

Some content is hidden

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

50 files changed

+396
-306
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ pub fn parse_asm_args<'a>(
328328
/// Otherwise, the suggestion will be incorrect.
329329
fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
330330
// Tool-only output
331-
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
331+
let full_span = if p.token == token::Comma { span.to(p.token.span) } else { span };
332332
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
333333
}
334334

@@ -338,7 +338,7 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
338338
/// Otherwise, the suggestion will be incorrect.
339339
fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
340340
// Tool-only output
341-
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
341+
let full_span = if p.token == token::Comma { span.to(p.token.span) } else { span };
342342
p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
343343
}
344344

compiler/rustc_expand/src/mbe/macro_rules.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,7 @@ fn check_matcher_core<'tt>(
11541154
&& matches!(kind, NonterminalKind::Pat(PatParam { inferred: true }))
11551155
&& matches!(
11561156
next_token,
1157-
TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or)
1157+
TokenTree::Token(token) if *token == BinOp(token::BinOpToken::Or)
11581158
)
11591159
{
11601160
// It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.

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_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1853,7 +1853,7 @@ impl KeywordIdents {
18531853
if !prev_dollar {
18541854
self.check_ident_token(cx, UnderMacro(true), ident);
18551855
}
1856-
} else if token.kind == TokenKind::Dollar {
1856+
} else if *token == TokenKind::Dollar {
18571857
prev_dollar = true;
18581858
continue;
18591859
}

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_parse/src/lexer/tokentrees.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
229229
} else {
230230
let this_spacing = if next_tok.is_punct() {
231231
Spacing::Joint
232-
} else if next_tok.kind == token::Eof {
232+
} else if next_tok == token::Eof {
233233
Spacing::Alone
234234
} else {
235235
Spacing::JointHidden

compiler/rustc_parse/src/parser/attr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl<'a> Parser<'a> {
162162
}
163163
loop {
164164
// skip any other attributes, we want the item
165-
if snapshot.token.kind == token::Pound {
165+
if snapshot.token == token::Pound {
166166
if let Err(err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) {
167167
err.cancel();
168168
return Some(replacement_span);
@@ -343,7 +343,7 @@ impl<'a> Parser<'a> {
343343

344344
// Presumably, the majority of the time there will only be one attr.
345345
let mut expanded_attrs = Vec::with_capacity(1);
346-
while self.token.kind != token::Eof {
346+
while self.token != token::Eof {
347347
let lo = self.token.span;
348348
let item = self.parse_attr_item(ForceCollect::Yes)?;
349349
expanded_attrs.push((item, lo.to(self.prev_token.span)));
@@ -359,7 +359,7 @@ impl<'a> Parser<'a> {
359359
pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::NestedMetaItem>> {
360360
// Presumably, the majority of the time there will only be one attr.
361361
let mut nmis = ThinVec::with_capacity(1);
362-
while self.token.kind != token::Eof {
362+
while self.token != token::Eof {
363363
nmis.push(self.parse_meta_item_inner()?);
364364
if !self.eat(&token::Comma) {
365365
break;

0 commit comments

Comments
 (0)