Skip to content

Commit 1921968

Browse files
committed
Auto merge of rust-lang#123497 - GuillaumeGomez:rollup-usqb4q9, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - rust-lang#122334 (Vendor rustc_codegen_gcc) - rust-lang#122894 (Move check for error in impl header outside of reporting) - rust-lang#123149 (Port argument-non-c-like-enum to Rust) - rust-lang#123311 (Match ergonomics: implement "`&`pat everywhere") - rust-lang#123350 (Actually use the inferred `ClosureKind` from signature inference in coroutine-closures) - rust-lang#123474 (Port `run-make/issue-7349` to a codegen test) - rust-lang#123489 (handle rustc args properly in bootstrap) - rust-lang#123496 (ping on wf changes, remove fixme) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5958f5e + 9cb517a commit 1921968

Some content is hidden

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

42 files changed

+910
-167
lines changed

compiler/rustc_codegen_gcc/Cargo.lock

+6-4
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,18 @@ dependencies = [
7979

8080
[[package]]
8181
name = "gccjit"
82-
version = "1.0.0"
83-
source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e"
82+
version = "2.0.0"
83+
source = "registry+https://github.com/rust-lang/crates.io-index"
84+
checksum = "ecaa4c3da2d74c1a991b4faff75d49ab1d0522d9a99d8e2614b3b04d226417ce"
8485
dependencies = [
8586
"gccjit_sys",
8687
]
8788

8889
[[package]]
8990
name = "gccjit_sys"
90-
version = "0.0.1"
91-
source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e"
91+
version = "0.1.0"
92+
source = "registry+https://github.com/rust-lang/crates.io-index"
93+
checksum = "406a66fba005f1a02661f2f9443e5693dd3a667b7c58e70aa4ccc4c8b50b4758"
9294
dependencies = [
9395
"libc",
9496
]

compiler/rustc_codegen_gcc/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ master = ["gccjit/master"]
2222
default = ["master"]
2323

2424
[dependencies]
25-
gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
25+
gccjit = "2.0"
2626

2727
# Local copy.
2828
#gccjit = { path = "../gccjit.rs" }

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ declare_features! (
567567
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
568568
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
569569
(unstable, raw_ref_op, "1.41.0", Some(64490)),
570+
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
571+
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
570572
/// Allows using the `#[register_tool]` attribute.
571573
(unstable, register_tool, "1.41.0", Some(66079)),
572574
/// Allows the `#[repr(i128)]` attribute for enums.

compiler/rustc_hir_typeck/src/closure.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
227227
kind: TypeVariableOriginKind::ClosureSynthetic,
228228
span: expr_span,
229229
});
230-
let closure_kind_ty = self.next_ty_var(TypeVariableOrigin {
231-
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
232-
kind: TypeVariableOriginKind::ClosureSynthetic,
233-
span: expr_span,
234-
});
230+
231+
let closure_kind_ty = match expected_kind {
232+
Some(kind) => Ty::from_closure_kind(tcx, kind),
233+
234+
// Create a type variable (for now) to represent the closure kind.
235+
// It will be unified during the upvar inference phase (`upvar.rs`)
236+
None => self.next_ty_var(TypeVariableOrigin {
237+
kind: TypeVariableOriginKind::ClosureSynthetic,
238+
span: expr_span,
239+
}),
240+
};
241+
235242
let coroutine_captures_by_ref_ty = self.next_ty_var(TypeVariableOrigin {
236243
kind: TypeVariableOriginKind::ClosureSynthetic,
237244
span: expr_span,
@@ -262,10 +269,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
262269
},
263270
);
264271

265-
let coroutine_kind_ty = self.next_ty_var(TypeVariableOrigin {
266-
kind: TypeVariableOriginKind::ClosureSynthetic,
267-
span: expr_span,
268-
});
272+
let coroutine_kind_ty = match expected_kind {
273+
Some(kind) => Ty::from_coroutine_closure_kind(tcx, kind),
274+
275+
// Create a type variable (for now) to represent the closure kind.
276+
// It will be unified during the upvar inference phase (`upvar.rs`)
277+
None => self.next_ty_var(TypeVariableOrigin {
278+
kind: TypeVariableOriginKind::ClosureSynthetic,
279+
span: expr_span,
280+
}),
281+
};
282+
269283
let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin {
270284
kind: TypeVariableOriginKind::ClosureSynthetic,
271285
span: expr_span,

compiler/rustc_hir_typeck/src/pat.rs

+64-27
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,14 @@ enum AdjustMode {
130130
/// Peel off all immediate reference types.
131131
Peel,
132132
/// Reset binding mode to the initial mode.
133+
/// Used for destructuring assignment, where we don't want any match ergonomics.
133134
Reset,
135+
/// Produced by ref patterns.
136+
/// Reset the binding mode to the initial mode,
137+
/// and if the old biding mode was by-reference
138+
/// with mutability matching the pattern,
139+
/// mark the pattern as having consumed this reference.
140+
ResetAndConsumeRef(Mutability),
134141
/// Pass on the input binding mode and expected type.
135142
Pass,
136143
}
@@ -174,7 +181,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
174181
_ => None,
175182
};
176183
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
177-
let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
184+
let (expected, def_bm, ref_pattern_already_consumed) =
185+
self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
178186
let pat_info = PatInfo {
179187
binding_mode: def_bm,
180188
top_info: ti,
@@ -211,7 +219,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
211219
}
212220
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
213221
PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
214-
PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
222+
PatKind::Ref(inner, mutbl) => self.check_pat_ref(
223+
pat,
224+
inner,
225+
mutbl,
226+
expected,
227+
pat_info,
228+
ref_pattern_already_consumed,
229+
),
215230
PatKind::Slice(before, slice, after) => {
216231
self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
217232
}
@@ -264,17 +279,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
264279

265280
/// Compute the new expected type and default binding mode from the old ones
266281
/// as well as the pattern form we are currently checking.
282+
///
283+
/// Last entry is only relevant for ref patterns (`&` and `&mut`);
284+
/// if `true`, then the ref pattern consumed a match ergonomics inserted reference
285+
/// and so does no need to match against a reference in the scrutinee type.
267286
fn calc_default_binding_mode(
268287
&self,
269288
pat: &'tcx Pat<'tcx>,
270289
expected: Ty<'tcx>,
271290
def_bm: BindingAnnotation,
272291
adjust_mode: AdjustMode,
273-
) -> (Ty<'tcx>, BindingAnnotation) {
292+
) -> (Ty<'tcx>, BindingAnnotation, bool) {
274293
match adjust_mode {
275-
AdjustMode::Pass => (expected, def_bm),
276-
AdjustMode::Reset => (expected, INITIAL_BM),
277-
AdjustMode::Peel => self.peel_off_references(pat, expected, def_bm),
294+
AdjustMode::Pass => (expected, def_bm, false),
295+
AdjustMode::Reset => (expected, INITIAL_BM, false),
296+
AdjustMode::ResetAndConsumeRef(mutbl) => {
297+
(expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl))
298+
}
299+
AdjustMode::Peel => {
300+
let peeled = self.peel_off_references(pat, expected, def_bm);
301+
(peeled.0, peeled.1, false)
302+
}
278303
}
279304
}
280305

@@ -329,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
329354
// ```
330355
//
331356
// See issue #46688.
332-
PatKind::Ref(..) => AdjustMode::Reset,
357+
PatKind::Ref(_, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl),
333358
// A `_` pattern works with any expected type, so there's no need to do anything.
334359
PatKind::Wild
335360
// A malformed pattern doesn't have an expected type, so let's just accept any type.
@@ -840,8 +865,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
840865
&& let Some(mt) = self.shallow_resolve(expected).builtin_deref(true)
841866
&& let ty::Dynamic(..) = mt.ty.kind()
842867
{
843-
// This is "x = SomeTrait" being reduced from
844-
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
868+
// This is "x = dyn SomeTrait" being reduced from
869+
// "let &x = &dyn SomeTrait" or "let box x = Box<dyn SomeTrait>", an error.
845870
let type_str = self.ty_to_string(expected);
846871
let mut err = struct_span_code_err!(
847872
self.dcx(),
@@ -2036,6 +2061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20362061
mutbl: Mutability,
20372062
expected: Ty<'tcx>,
20382063
pat_info: PatInfo<'tcx, '_>,
2064+
consumed_inherited_ref: bool,
20392065
) -> Ty<'tcx> {
20402066
let tcx = self.tcx;
20412067
let expected = self.shallow_resolve(expected);
@@ -2051,26 +2077,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20512077
match *expected.kind() {
20522078
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
20532079
_ => {
2054-
let inner_ty = self.next_ty_var(TypeVariableOrigin {
2055-
kind: TypeVariableOriginKind::TypeInference,
2056-
span: inner.span,
2057-
});
2058-
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
2059-
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
2060-
let err = self.demand_eqtype_pat_diag(
2061-
pat.span,
2062-
expected,
2063-
ref_ty,
2064-
pat_info.top_info,
2065-
);
2080+
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
2081+
// We already matched against a match-ergonmics inserted reference,
2082+
// so we don't need to match against a reference from the original type.
2083+
// Save this infor for use in lowering later
2084+
self.typeck_results
2085+
.borrow_mut()
2086+
.skipped_ref_pats_mut()
2087+
.insert(pat.hir_id);
2088+
(expected, expected)
2089+
} else {
2090+
let inner_ty = self.next_ty_var(TypeVariableOrigin {
2091+
kind: TypeVariableOriginKind::TypeInference,
2092+
span: inner.span,
2093+
});
2094+
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
2095+
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
2096+
let err = self.demand_eqtype_pat_diag(
2097+
pat.span,
2098+
expected,
2099+
ref_ty,
2100+
pat_info.top_info,
2101+
);
20662102

2067-
// Look for a case like `fn foo(&foo: u32)` and suggest
2068-
// `fn foo(foo: &u32)`
2069-
if let Some(mut err) = err {
2070-
self.borrow_pat_suggestion(&mut err, pat);
2071-
err.emit();
2103+
// Look for a case like `fn foo(&foo: u32)` and suggest
2104+
// `fn foo(foo: &u32)`
2105+
if let Some(mut err) = err {
2106+
self.borrow_pat_suggestion(&mut err, pat);
2107+
err.emit();
2108+
}
2109+
(ref_ty, inner_ty)
20722110
}
2073-
(ref_ty, inner_ty)
20742111
}
20752112
}
20762113
}

compiler/rustc_hir_typeck/src/upvar.rs

+39-11
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166166
span: Span,
167167
body_id: hir::BodyId,
168168
body: &'tcx hir::Body<'tcx>,
169-
capture_clause: hir::CaptureBy,
169+
mut capture_clause: hir::CaptureBy,
170170
) {
171171
// Extract the type of the closure.
172172
let ty = self.node_ty(closure_hir_id);
@@ -259,6 +259,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
259259
)
260260
.consume_body(body);
261261

262+
// If a coroutine is comes from a coroutine-closure that is `move`, but
263+
// the coroutine-closure was inferred to be `FnOnce` during signature
264+
// inference, then it's still possible that we try to borrow upvars from
265+
// the coroutine-closure because they are not used by the coroutine body
266+
// in a way that forces a move.
267+
//
268+
// This would lead to an impossible to satisfy situation, since `AsyncFnOnce`
269+
// coroutine bodies can't borrow from their parent closure. To fix this,
270+
// we force the inner coroutine to also be `move`. This only matters for
271+
// coroutine-closures that are `move` since otherwise they themselves will
272+
// be borrowing from the outer environment, so there's no self-borrows occuring.
273+
if let UpvarArgs::Coroutine(..) = args
274+
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
275+
self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
276+
&& let parent_hir_id =
277+
self.tcx.local_def_id_to_hir_id(self.tcx.local_parent(closure_def_id))
278+
&& let parent_ty = self.node_ty(parent_hir_id)
279+
&& let Some(ty::ClosureKind::FnOnce) = self.closure_kind(parent_ty)
280+
{
281+
capture_clause = self.tcx.hir_node(parent_hir_id).expect_closure().capture_clause;
282+
}
283+
262284
debug!(
263285
"For closure={:?}, capture_information={:#?}",
264286
closure_def_id, delegate.capture_information
@@ -399,16 +421,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
399421
);
400422

401423
// Additionally, we can now constrain the coroutine's kind type.
402-
let ty::Coroutine(_, coroutine_args) =
403-
*self.typeck_results.borrow().expr_ty(body.value).kind()
404-
else {
405-
bug!();
406-
};
407-
self.demand_eqtype(
408-
span,
409-
coroutine_args.as_coroutine().kind_ty(),
410-
Ty::from_coroutine_closure_kind(self.tcx, closure_kind),
411-
);
424+
//
425+
// We only do this if `infer_kind`, because if we have constrained
426+
// the kind from closure signature inference, the kind inferred
427+
// for the inner coroutine may actually be more restrictive.
428+
if infer_kind {
429+
let ty::Coroutine(_, coroutine_args) =
430+
*self.typeck_results.borrow().expr_ty(body.value).kind()
431+
else {
432+
bug!();
433+
};
434+
self.demand_eqtype(
435+
span,
436+
coroutine_args.as_coroutine().kind_ty(),
437+
Ty::from_coroutine_closure_kind(self.tcx, closure_kind),
438+
);
439+
}
412440
}
413441

414442
self.log_closure_min_capture_info(closure_def_id, span);

compiler/rustc_hir_typeck/src/writeback.rs

+9
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
345345
_ => {}
346346
};
347347

348+
self.visit_skipped_ref_pats(p.hir_id);
348349
self.visit_pat_adjustments(p.span, p.hir_id);
349350

350351
self.visit_node_id(p.span, p.hir_id);
@@ -674,6 +675,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
674675
}
675676
}
676677

678+
#[instrument(skip(self), level = "debug")]
679+
fn visit_skipped_ref_pats(&mut self, hir_id: hir::HirId) {
680+
if self.fcx.typeck_results.borrow_mut().skipped_ref_pats_mut().remove(hir_id) {
681+
debug!("node is a skipped ref pat");
682+
self.typeck_results.skipped_ref_pats_mut().insert(hir_id);
683+
}
684+
}
685+
677686
fn visit_liberated_fn_sigs(&mut self) {
678687
let fcx_typeck_results = self.fcx.typeck_results.borrow();
679688
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);

0 commit comments

Comments
 (0)