Skip to content

Commit 2f8d804

Browse files
committed
Auto merge of #104600 - Dylan-DPC:rollup-glw1e8b, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #104001 (Improve generating Custom entry function) - #104411 (nll: correctly deal with bivariance) - #104528 (Properly link `{Once,Lazy}{Cell,Lock}` in docs) - #104553 (Improve accuracy of asinh and acosh) - #104554 (Use `ErrorGuaranteed::unchecked_claim_error_was_emitted` less) - #104566 (couple of clippy::perf fixes) - #104575 (deduplicate tests) - #104580 (diagnostics: only show one suggestion for method -> assoc fn) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents becc24a + 3cf3a65 commit 2f8d804

File tree

73 files changed

+563
-338
lines changed

Some content is hidden

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

73 files changed

+563
-338
lines changed

compiler/rustc_borrowck/src/lib.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern crate tracing;
1919
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2020
use rustc_data_structures::graph::dominators::Dominators;
2121
use rustc_data_structures::vec_map::VecMap;
22-
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
22+
use rustc_errors::{Diagnostic, DiagnosticBuilder};
2323
use rustc_hir as hir;
2424
use rustc_hir::def_id::LocalDefId;
2525
use rustc_index::bit_set::ChunkedBitSet;
@@ -192,13 +192,13 @@ fn do_mir_borrowck<'tcx>(
192192
}
193193
}
194194

195-
let mut errors = error::BorrowckErrors::new();
195+
let mut errors = error::BorrowckErrors::new(infcx.tcx);
196196

197197
// Gather the upvars of a closure, if any.
198198
let tables = tcx.typeck_opt_const_arg(def);
199-
if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
200-
infcx.set_tainted_by_errors();
201-
errors.set_tainted_by_errors();
199+
if let Some(e) = tables.tainted_by_errors {
200+
infcx.set_tainted_by_errors(e);
201+
errors.set_tainted_by_errors(e);
202202
}
203203
let upvars: Vec<_> = tables
204204
.closure_min_captures_flattened(def.did)
@@ -2260,6 +2260,7 @@ mod error {
22602260
use super::*;
22612261

22622262
pub struct BorrowckErrors<'tcx> {
2263+
tcx: TyCtxt<'tcx>,
22632264
/// This field keeps track of move errors that are to be reported for given move indices.
22642265
///
22652266
/// There are situations where many errors can be reported for a single move out (see #53807)
@@ -2282,28 +2283,33 @@ mod error {
22822283
tainted_by_errors: Option<ErrorGuaranteed>,
22832284
}
22842285

2285-
impl BorrowckErrors<'_> {
2286-
pub fn new() -> Self {
2286+
impl<'tcx> BorrowckErrors<'tcx> {
2287+
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
22872288
BorrowckErrors {
2289+
tcx,
22882290
buffered_move_errors: BTreeMap::new(),
22892291
buffered: Default::default(),
22902292
tainted_by_errors: None,
22912293
}
22922294
}
22932295

2294-
// FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
2295-
// set before any emission actually happens (weakening the guarantee).
22962296
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
2297-
self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
2297+
if let None = self.tainted_by_errors {
2298+
self.tainted_by_errors = Some(
2299+
self.tcx
2300+
.sess
2301+
.delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"),
2302+
)
2303+
}
22982304
t.buffer(&mut self.buffered);
22992305
}
23002306

23012307
pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
23022308
t.buffer(&mut self.buffered);
23032309
}
23042310

2305-
pub fn set_tainted_by_errors(&mut self) {
2306-
self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
2311+
pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
2312+
self.tainted_by_errors = Some(e);
23072313
}
23082314
}
23092315

compiler/rustc_borrowck/src/nll.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
303303

304304
if !nll_errors.is_empty() {
305305
// Suppress unhelpful extra errors in `infer_opaque_types`.
306-
infcx.set_tainted_by_errors();
306+
infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
307+
body.span,
308+
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
309+
));
307310
}
308311

309312
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
219219
instantiated_ty: OpaqueHiddenType<'tcx>,
220220
origin: OpaqueTyOrigin,
221221
) -> Ty<'tcx> {
222-
if self.is_tainted_by_errors() {
223-
return self.tcx.ty_error();
222+
if let Some(e) = self.tainted_by_errors() {
223+
return self.tcx.ty_error_with_guaranteed(e);
224224
}
225225

226226
let definition_ty = instantiated_ty

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,19 @@ fn clif_sig_from_fn_abi<'tcx>(
2222
default_call_conv: CallConv,
2323
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
2424
) -> Signature {
25-
let call_conv = match fn_abi.conv {
25+
let call_conv = conv_to_call_conv(fn_abi.conv, default_call_conv);
26+
27+
let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
28+
29+
let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
30+
// Sometimes the first param is an pointer to the place where the return value needs to be stored.
31+
let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
32+
33+
Signature { params, returns, call_conv }
34+
}
35+
36+
pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallConv {
37+
match c {
2638
Conv::Rust | Conv::C => default_call_conv,
2739
Conv::RustCold => CallConv::Cold,
2840
Conv::X86_64SysV => CallConv::SystemV,
@@ -38,15 +50,8 @@ fn clif_sig_from_fn_abi<'tcx>(
3850
| Conv::X86VectorCall
3951
| Conv::AmdGpuKernel
4052
| Conv::AvrInterrupt
41-
| Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
42-
};
43-
let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
44-
45-
let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
46-
// Sometimes the first param is an pointer to the place where the return value needs to be stored.
47-
let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
48-
49-
Signature { params, returns, call_conv }
53+
| Conv::AvrNonBlockingInterrupt => todo!("{:?}", c),
54+
}
5055
}
5156

5257
pub(crate) fn get_function_sig<'tcx>(

compiler/rustc_codegen_cranelift/src/main_shim.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,14 @@ pub(crate) fn maybe_create_entry_wrapper(
6363
AbiParam::new(m.target_config().pointer_type()),
6464
],
6565
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
66-
call_conv: CallConv::triple_default(m.isa().triple()),
66+
call_conv: crate::conv_to_call_conv(
67+
tcx.sess.target.options.entry_abi,
68+
CallConv::triple_default(m.isa().triple()),
69+
),
6770
};
6871

69-
let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();
72+
let entry_name = tcx.sess.target.options.entry_name.as_ref();
73+
let cmain_func_id = m.declare_function(entry_name, Linkage::Export, &cmain_sig).unwrap();
7074

7175
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
7276

compiler/rustc_codegen_gcc/src/context.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,9 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
425425
}
426426

427427
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
428-
if self.get_declared_value("main").is_none() {
429-
Some(self.declare_cfn("main", fn_type))
428+
let entry_name = self.sess().target.entry_name.as_ref();
429+
if self.get_declared_value(entry_name).is_none() {
430+
Some(self.declare_entry_fn(entry_name, fn_type, ()))
430431
}
431432
else {
432433
// If the symbol already exists, it is an error: for example, the user wrote

compiler/rustc_codegen_gcc/src/declare.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
6565
global
6666
}
6767

68-
pub fn declare_cfn(&self, name: &str, _fn_type: Type<'gcc>) -> RValue<'gcc> {
68+
pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> {
6969
// TODO(antoyo): use the fn_type parameter.
7070
let const_string = self.context.new_type::<u8>().make_pointer().make_pointer();
7171
let return_type = self.type_i32();
7272
let variadic = false;
7373
self.linkage.set(FunctionType::Exported);
74-
let func = declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, &[self.type_i32(), const_string], variadic);
74+
let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic);
7575
// NOTE: it is needed to set the current_func here as well, because get_fn() is not called
7676
// for the main function.
7777
*self.current_func.borrow_mut() = Some(func);

compiler/rustc_codegen_llvm/src/abi.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -398,23 +398,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
398398
}
399399

400400
fn llvm_cconv(&self) -> llvm::CallConv {
401-
match self.conv {
402-
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
403-
Conv::RustCold => llvm::ColdCallConv,
404-
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
405-
Conv::AvrInterrupt => llvm::AvrInterrupt,
406-
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
407-
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
408-
Conv::Msp430Intr => llvm::Msp430Intr,
409-
Conv::PtxKernel => llvm::PtxKernel,
410-
Conv::X86Fastcall => llvm::X86FastcallCallConv,
411-
Conv::X86Intr => llvm::X86_Intr,
412-
Conv::X86Stdcall => llvm::X86StdcallCallConv,
413-
Conv::X86ThisCall => llvm::X86_ThisCall,
414-
Conv::X86VectorCall => llvm::X86_VectorCall,
415-
Conv::X86_64SysV => llvm::X86_64_SysV,
416-
Conv::X86_64Win64 => llvm::X86_64_Win64,
417-
}
401+
self.conv.into()
418402
}
419403

420404
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
@@ -596,3 +580,25 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
596580
llvm::get_param(self.llfn(), index as c_uint)
597581
}
598582
}
583+
584+
impl From<Conv> for llvm::CallConv {
585+
fn from(conv: Conv) -> Self {
586+
match conv {
587+
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
588+
Conv::RustCold => llvm::ColdCallConv,
589+
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
590+
Conv::AvrInterrupt => llvm::AvrInterrupt,
591+
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
592+
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
593+
Conv::Msp430Intr => llvm::Msp430Intr,
594+
Conv::PtxKernel => llvm::PtxKernel,
595+
Conv::X86Fastcall => llvm::X86FastcallCallConv,
596+
Conv::X86Intr => llvm::X86_Intr,
597+
Conv::X86Stdcall => llvm::X86StdcallCallConv,
598+
Conv::X86ThisCall => llvm::X86_ThisCall,
599+
Conv::X86VectorCall => llvm::X86_VectorCall,
600+
Conv::X86_64SysV => llvm::X86_64_SysV,
601+
Conv::X86_64Win64 => llvm::X86_64_Win64,
602+
}
603+
}
604+
}

compiler/rustc_codegen_llvm/src/context.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,14 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
576576
}
577577

578578
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
579-
if self.get_declared_value("main").is_none() {
580-
Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
579+
let entry_name = self.sess().target.entry_name.as_ref();
580+
if self.get_declared_value(entry_name).is_none() {
581+
Some(self.declare_entry_fn(
582+
entry_name,
583+
self.sess().target.entry_abi.into(),
584+
llvm::UnnamedAddr::Global,
585+
fn_type,
586+
))
581587
} else {
582588
// If the symbol already exists, it is an error: for example, the user wrote
583589
// #[no_mangle] extern "C" fn main(..) {..}

compiler/rustc_codegen_llvm/src/declare.rs

+22
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,28 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
9090
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
9191
}
9292

93+
/// Declare an entry Function
94+
///
95+
/// The ABI of this function can change depending on the target (although for now the same as
96+
/// `declare_cfn`)
97+
///
98+
/// If there’s a value with the same name already declared, the function will
99+
/// update the declaration and return existing Value instead.
100+
pub fn declare_entry_fn(
101+
&self,
102+
name: &str,
103+
callconv: llvm::CallConv,
104+
unnamed: llvm::UnnamedAddr,
105+
fn_type: &'ll Type,
106+
) -> &'ll Value {
107+
let visibility = if self.tcx.sess.target.default_hidden_visibility {
108+
llvm::Visibility::Hidden
109+
} else {
110+
llvm::Visibility::Default
111+
};
112+
declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
113+
}
114+
93115
/// Declare a Rust function.
94116
///
95117
/// If there’s a value with the same name already declared, the function will

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ fn exported_symbols_provider_local<'tcx>(
180180
.collect();
181181

182182
if tcx.entry_fn(()).is_some() {
183-
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main"));
183+
let exported_symbol =
184+
ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
184185

185186
symbols.push((
186187
exported_symbol,

compiler/rustc_const_eval/src/interpret/eval_context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::{
2323
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
2424
Scalar, StackPopJump,
2525
};
26-
use crate::transform::validate::equal_up_to_regions;
26+
use crate::util;
2727

2828
pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
2929
/// Stores the `Machine` instance.
@@ -354,8 +354,8 @@ pub(super) fn mir_assign_valid_types<'tcx>(
354354
// Type-changing assignments can happen when subtyping is used. While
355355
// all normal lifetimes are erased, higher-ranked types with their
356356
// late-bound lifetimes are still around and can lead to type
357-
// differences. So we compare ignoring lifetimes.
358-
if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) {
357+
// differences.
358+
if util::is_subtype(tcx, param_env, src.ty, dest.ty) {
359359
// Make sure the layout is equal, too -- just to be safe. Miri really
360360
// needs layout equality. For performance reason we skip this check when
361361
// the types are equal. Equal types *can* have different layouts when

compiler/rustc_const_eval/src/transform/validate.rs

+2-57
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use rustc_data_structures::fx::FxHashSet;
44
use rustc_index::bit_set::BitSet;
5-
use rustc_infer::infer::TyCtxtInferExt;
65
use rustc_middle::mir::interpret::Scalar;
76
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
87
use rustc_middle::mir::visit::{PlaceContext, Visitor};
@@ -12,8 +11,7 @@ use rustc_middle::mir::{
1211
ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
1312
TerminatorKind, UnOp, START_BLOCK,
1413
};
15-
use rustc_middle::ty::fold::BottomUpFolder;
16-
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable};
14+
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
1715
use rustc_mir_dataflow::impls::MaybeStorageLive;
1816
use rustc_mir_dataflow::storage::always_storage_live_locals;
1917
use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -70,44 +68,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
7068
}
7169
}
7270

73-
/// Returns whether the two types are equal up to lifetimes.
74-
/// All lifetimes, including higher-ranked ones, get ignored for this comparison.
75-
/// (This is unlike the `erasing_regions` methods, which keep higher-ranked lifetimes for soundness reasons.)
76-
///
77-
/// The point of this function is to approximate "equal up to subtyping". However,
78-
/// the approximation is incorrect as variance is ignored.
79-
pub fn equal_up_to_regions<'tcx>(
80-
tcx: TyCtxt<'tcx>,
81-
param_env: ParamEnv<'tcx>,
82-
src: Ty<'tcx>,
83-
dest: Ty<'tcx>,
84-
) -> bool {
85-
// Fast path.
86-
if src == dest {
87-
return true;
88-
}
89-
90-
// Normalize lifetimes away on both sides, then compare.
91-
let normalize = |ty: Ty<'tcx>| {
92-
tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with(
93-
&mut BottomUpFolder {
94-
tcx,
95-
// FIXME: We erase all late-bound lifetimes, but this is not fully correct.
96-
// If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
97-
// this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`,
98-
// since one may have an `impl SomeTrait for fn(&32)` and
99-
// `impl SomeTrait for fn(&'static u32)` at the same time which
100-
// specify distinct values for Assoc. (See also #56105)
101-
lt_op: |_| tcx.lifetimes.re_erased,
102-
// Leave consts and types unchanged.
103-
ct_op: |ct| ct,
104-
ty_op: |ty| ty,
105-
},
106-
)
107-
};
108-
tcx.infer_ctxt().build().can_eq(param_env, normalize(src), normalize(dest)).is_ok()
109-
}
110-
11171
struct TypeChecker<'a, 'tcx> {
11272
when: &'a str,
11373
body: &'a Body<'tcx>,
@@ -183,22 +143,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
183143
return true;
184144
}
185145

186-
// Normalize projections and things like that.
187-
// Type-changing assignments can happen when subtyping is used. While
188-
// all normal lifetimes are erased, higher-ranked types with their
189-
// late-bound lifetimes are still around and can lead to type
190-
// differences. So we compare ignoring lifetimes.
191-
192-
// First, try with reveal_all. This might not work in some cases, as the predicates
193-
// can be cleared in reveal_all mode. We try the reveal first anyways as it is used
194-
// by some other passes like inlining as well.
195-
let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
196-
if equal_up_to_regions(self.tcx, param_env, src, dest) {
197-
return true;
198-
}
199-
200-
// If this fails, we can try it without the reveal.
201-
equal_up_to_regions(self.tcx, self.param_env, src, dest)
146+
crate::util::is_subtype(self.tcx, self.param_env, src, dest)
202147
}
203148
}
204149

0 commit comments

Comments
 (0)