Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #124034

Merged
merged 24 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a30a79c
std: use queue-based `RwLock` on SGX
joboet Apr 11, 2024
8afee14
std: use queue-based `RwLock` on Xous
joboet Apr 11, 2024
dbda4f9
std: use queue-based `RwLock` on Windows 7
joboet Apr 11, 2024
ff2e4ed
Factor out common code in interface tests.
nnethercote Mar 21, 2024
62c32ae
Construct `SourceMap` at the same time as `SessionGlobals`.
nnethercote Mar 21, 2024
9b0ced0
Move `initialize_checked_jobserver`.
nnethercote Mar 21, 2024
93544d5
Match ergonomics 2024: Implement eat-one-layer
Jules-Bertholet Apr 1, 2024
4cd87c4
Properly downgrade inherited mutability
Jules-Bertholet Apr 6, 2024
b6c4097
Support `let &mut x = &&mut 0;`
Jules-Bertholet Apr 6, 2024
e3945bd
Ensure inherited reference is never set to `&mut` behind an `&`
Jules-Bertholet Apr 6, 2024
88cd821
Address review comments
Jules-Bertholet Apr 14, 2024
3efbe3e
Simplify `calc_default_binding_mode`
Jules-Bertholet Apr 14, 2024
82e7773
Subtype predicates only exist on inference types, so we can allow the…
oli-obk Apr 15, 2024
780dfb8
Outline default query and hook provider function implementations
DaniPopes Apr 16, 2024
864eb7f
Remove uneeded clones now that TrustedStep implies Copy
krtab Apr 12, 2024
10b6ca1
std: fix lint on SGX
joboet Apr 16, 2024
a03aeca
Allow workproducts without object files.
pacak Apr 16, 2024
14496d5
Rollup merge of #122811 - nnethercote:mv-SourceMap-init, r=WaffleLapkin
GuillaumeGomez Apr 16, 2024
239b372
Rollup merge of #123512 - Jules-Bertholet:ref-pat-eat-one-layer-2024,…
GuillaumeGomez Apr 16, 2024
1176134
Rollup merge of #123811 - joboet:queue_em_up, r=ChrisDenton
GuillaumeGomez Apr 16, 2024
183c706
Rollup merge of #123859 - krtab:uneeded_clone, r=cuviper
GuillaumeGomez Apr 16, 2024
f939d1f
Rollup merge of #123979 - oli-obk:define_opaque_types7, r=compiler-er…
GuillaumeGomez Apr 16, 2024
4779115
Rollup merge of #124016 - DaniPopes:dedup-default-providers, r=lcnr
GuillaumeGomez Apr 16, 2024
7709b7d
Rollup merge of #124023 - pacak:less-splody, r=jieyouxu
GuillaumeGomez Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use rustc_macros::HashStable_Generic;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
use std::cmp;
use std::fmt;
use std::mem;
use thin_vec::{thin_vec, ThinVec};
Expand Down Expand Up @@ -731,6 +732,13 @@ impl BindingAnnotation {
Self::MUT_REF_MUT => "mut ref mut ",
}
}

pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
if let ByRef::Yes(old_mutbl) = &mut self.0 {
*old_mutbl = cmp::min(*old_mutbl, mutbl);
}
self
}
}

#[derive(Clone, Encodable, Decodable, Debug)]
Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,8 +907,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
module: CachedModuleCodegen,
module_config: &ModuleConfig,
) -> WorkItemResult<B> {
assert!(module_config.emit_obj != EmitObj::None);

let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();

let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| {
Expand All @@ -928,12 +926,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
}
};

let object = load_from_incr_comp_dir(
cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)),
module.source.saved_files.get("o").unwrap_or_else(|| {
cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
}),
);
let dwarf_object =
module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
let dwarf_obj_out = cgcx
Expand All @@ -955,9 +947,14 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
}
};

let should_emit_obj = module_config.emit_obj != EmitObj::None;
let assembly = load_from_incr_cache(module_config.emit_asm, OutputType::Assembly);
let llvm_ir = load_from_incr_cache(module_config.emit_ir, OutputType::LlvmAssembly);
let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode);
let object = load_from_incr_cache(should_emit_obj, OutputType::Object);
if should_emit_obj && object.is_none() {
cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
}

WorkItemResult::Finished(CompiledModule {
name: module.name,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ declare_features! (
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
(unstable, raw_ref_op, "1.41.0", Some(64490)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
(incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
/// Allows using the `#[register_tool]` attribute.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() {
// the crate by changing the crate disambiguator (e.g. via bumping the
// crate's version number).

create_session_globals_then(Edition::Edition2024, || {
create_session_globals_then(Edition::Edition2024, None, || {
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");

Expand Down
199 changes: 122 additions & 77 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct TopInfo<'tcx> {
#[derive(Copy, Clone)]
struct PatInfo<'tcx, 'a> {
binding_mode: BindingAnnotation,
max_ref_mutbl: Mutability,
top_info: TopInfo<'tcx>,
decl_origin: Option<DeclOrigin<'a>>,

Expand Down Expand Up @@ -161,8 +162,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
decl_origin: Option<DeclOrigin<'tcx>>,
) {
let info = TopInfo { expected, origin_expr, span };
let pat_info =
PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin, current_depth: 0 };
let pat_info = PatInfo {
binding_mode: INITIAL_BM,
max_ref_mutbl: Mutability::Mut,
top_info: info,
decl_origin,
current_depth: 0,
};
self.check_pat(pat, expected, pat_info);
}

Expand All @@ -173,7 +179,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Conversely, inside this module, `check_pat_top` should never be used.
#[instrument(level = "debug", skip(self, pat_info))]
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
let PatInfo { binding_mode: def_bm, top_info: ti, current_depth, .. } = pat_info;
let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } =
pat_info;

let path_res = match &pat.kind {
PatKind::Path(qpath) => Some(
Expand All @@ -182,10 +189,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => None,
};
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
let (expected, def_bm, ref_pattern_already_consumed) =
self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) =
self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl);
let pat_info = PatInfo {
binding_mode: def_bm,
max_ref_mutbl,
top_info: ti,
decl_origin: pat_info.decl_origin,
current_depth: current_depth + 1,
Expand Down Expand Up @@ -290,16 +298,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
def_bm: BindingAnnotation,
adjust_mode: AdjustMode,
) -> (Ty<'tcx>, BindingAnnotation, bool) {
max_ref_mutbl: Mutability,
) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) {
if let ByRef::Yes(mutbl) = def_bm.0 {
debug_assert!(mutbl <= max_ref_mutbl);
}
match adjust_mode {
AdjustMode::Pass => (expected, def_bm, false),
AdjustMode::Reset => (expected, INITIAL_BM, false),
AdjustMode::ResetAndConsumeRef(mutbl) => {
(expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl))
AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false),
AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false),
AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => {
let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl);
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
if mutbls_match {
debug!("consuming inherited reference");
(expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true)
} else {
let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut {
self.peel_off_references(
pat,
expected,
def_bm,
Mutability::Not,
max_ref_mutbl,
)
} else {
(expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not)
};
(new_ty, new_bm, max_ref_mutbl, false)
}
} else {
(expected, INITIAL_BM, max_ref_mutbl, mutbls_match)
}
}
AdjustMode::Peel => {
let peeled = self.peel_off_references(pat, expected, def_bm);
(peeled.0, peeled.1, false)
let peeled =
self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl);
(peeled.0, peeled.1, peeled.2, false)
}
}
}
Expand Down Expand Up @@ -380,7 +414,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>,
mut def_bm: BindingAnnotation,
) -> (Ty<'tcx>, BindingAnnotation) {
max_peelable_mutability: Mutability,
mut max_ref_mutability: Mutability,
) -> (Ty<'tcx>, BindingAnnotation, Mutability) {
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
Expand All @@ -391,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
//
// See the examples in `ui/match-defbm*.rs`.
let mut pat_adjustments = vec![];
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
&& inner_mutability <= max_peelable_mutability
{
debug!("inspecting {:?}", expected);

debug!("current discriminant is Ref, inserting implicit deref");
Expand All @@ -411,6 +449,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
});
}

if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
def_bm = def_bm.cap_ref_mutability(max_ref_mutability);
if def_bm.0 == ByRef::Yes(Mutability::Not) {
max_ref_mutability = Mutability::Not;
}
}

if !pat_adjustments.is_empty() {
debug!("default binding mode is now {:?}", def_bm);
self.typeck_results
Expand All @@ -419,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.insert(pat.hir_id, pat_adjustments);
}

(expected, def_bm)
(expected, def_bm, max_ref_mutability)
}

fn check_pat_lit(
Expand Down Expand Up @@ -1109,15 +1154,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
pat_info: PatInfo<'tcx, '_>,
) -> Ty<'tcx> {
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth } = pat_info;
let tcx = self.tcx;
let on_error = |e| {
for pat in subpats {
self.check_pat(
pat,
Ty::new_error(tcx, e),
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth },
);
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
}
};
let report_unexpected_res = |res: Res| {
Expand Down Expand Up @@ -1162,7 +1202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");

// Type-check the tuple struct pattern against the expected type.
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info);
let had_err = if let Some(err) = diag {
err.emit();
true
Expand All @@ -1180,11 +1220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
let field = &variant.fields[FieldIdx::from_usize(i)];
let field_ty = self.field_ty(subpat.span, field, args);
self.check_pat(
subpat,
field_ty,
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth },
);
self.check_pat(subpat, field_ty, pat_info);

self.tcx.check_stability(
variant.fields[FieldIdx::from_usize(i)].did,
Expand Down Expand Up @@ -2071,61 +2107,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat_info: PatInfo<'tcx, '_>,
consumed_inherited_ref: bool,
) -> Ty<'tcx> {
let tcx = self.tcx;
let expected = self.shallow_resolve(expected);
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
Ok(()) => {
// `demand::subtype` would be good enough, but using `eqtype` turns
// out to be equally general. See (note_1) for details.

// Take region, inner-type from expected type if we can,
// to avoid creating needless variables. This also helps with
// the bad interactions of the given hack detailed in (note_1).
debug!("check_pat_ref: expected={:?}", expected);
match *expected.kind() {
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
_ => {
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
// We already matched against a match-ergonmics inserted reference,
// so we don't need to match against a reference from the original type.
// Save this infor for use in lowering later
self.typeck_results
.borrow_mut()
.skipped_ref_pats_mut()
.insert(pat.hir_id);
(expected, expected)
} else {
let inner_ty = self.next_ty_var(TypeVariableOrigin {
param_def_id: None,
span: inner.span,
});
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
let err = self.demand_eqtype_pat_diag(
pat.span,
expected,
ref_ty,
pat_info.top_info,
);
if consumed_inherited_ref
&& pat.span.at_least_rust_2024()
&& self.tcx.features().ref_pat_eat_one_layer_2024
{
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
self.check_pat(inner, expected, pat_info);
expected
} else {
let tcx = self.tcx;
let expected = self.shallow_resolve(expected);
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
Ok(()) => {
// `demand::subtype` would be good enough, but using `eqtype` turns
// out to be equally general. See (note_1) for details.

// Take region, inner-type from expected type if we can,
// to avoid creating needless variables. This also helps with
// the bad interactions of the given hack detailed in (note_1).
debug!("check_pat_ref: expected={:?}", expected);
match *expected.kind() {
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
_ => {
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
// We already matched against a match-ergonmics inserted reference,
// so we don't need to match against a reference from the original type.
// Save this infor for use in lowering later
self.typeck_results
.borrow_mut()
.skipped_ref_pats_mut()
.insert(pat.hir_id);
(expected, expected)
} else {
let inner_ty = self.next_ty_var(TypeVariableOrigin {
param_def_id: None,
span: inner.span,
});
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
let err = self.demand_eqtype_pat_diag(
pat.span,
expected,
ref_ty,
pat_info.top_info,
);

// Look for a case like `fn foo(&foo: u32)` and suggest
// `fn foo(foo: &u32)`
if let Some(mut err) = err {
self.borrow_pat_suggestion(&mut err, pat);
err.emit();
// Look for a case like `fn foo(&foo: u32)` and suggest
// `fn foo(foo: &u32)`
if let Some(mut err) = err {
self.borrow_pat_suggestion(&mut err, pat);
err.emit();
}
(ref_ty, inner_ty)
}
(ref_ty, inner_ty)
}
}
}
}
Err(guar) => {
let err = Ty::new_error(tcx, guar);
(err, err)
}
};
self.check_pat(inner, inner_ty, pat_info);
ref_ty
Err(guar) => {
let err = Ty::new_error(tcx, guar);
(err, err)
}
};
self.check_pat(inner, inner_ty, pat_info);
ref_ty
}
}

/// Create a reference type with a fresh region variable.
Expand Down
Loading
Loading