Skip to content

Commit a73daed

Browse files
committed
Auto merge of #131785 - Urgau:rollup-v431zf4, r=Urgau
Rollup of 10 pull requests Successful merges: - #129181 (Pass end position of span through inline ASM cookie) - #130989 (Don't check unsize goal in MIR validation when opaques remain) - #131657 (Rustfmt `for<'a> async` correctly) - #131691 (Delay ambiguous intra-doc link resolution after `Cache` has been populated) - #131730 (Refactor some `core::fmt` macros) - #131751 (Rename `can_coerce` to `may_coerce`, and then structurally resolve correctly in the probe) - #131753 (Unify `secondary_span` and `swap_secondary_and_primary` args in `note_type_err`) - #131776 (Emscripten: Xfail backtrace ui tests) - #131777 (Fix trivially_copy_pass_by_ref in stable_mir) - #131778 (Fix needless_lifetimes in stable_mir) r? `@ghost` `@rustbot` modify labels: rollup
2 parents bed75e7 + 7d1ff20 commit a73daed

File tree

64 files changed

+1484
-351
lines changed

Some content is hidden

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

64 files changed

+1484
-351
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,13 @@ pub(crate) fn inline_asm_call<'ll>(
487487
let key = "srcloc";
488488
let kind = llvm::LLVMGetMDKindIDInContext(
489489
bx.llcx,
490-
key.as_ptr() as *const c_char,
490+
key.as_ptr().cast::<c_char>(),
491491
key.len() as c_uint,
492492
);
493493

494-
// srcloc contains one integer for each line of assembly code.
495-
// Unfortunately this isn't enough to encode a full span so instead
496-
// we just encode the start position of each line.
497-
// FIXME: Figure out a way to pass the entire line spans.
494+
// `srcloc` contains one 64-bit integer for each line of assembly code,
495+
// where the lower 32 bits hold the lo byte position and the upper 32 bits
496+
// hold the hi byte position.
498497
let mut srcloc = vec![];
499498
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
500499
// LLVM inserts an extra line to add the ".intel_syntax", so add
@@ -504,13 +503,13 @@ pub(crate) fn inline_asm_call<'ll>(
504503
// due to the asm template string coming from a macro. LLVM will
505504
// default to the first srcloc for lines that don't have an
506505
// associated srcloc.
507-
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_i32(0)));
506+
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
508507
}
509-
srcloc.extend(
510-
line_spans
511-
.iter()
512-
.map(|span| llvm::LLVMValueAsMetadata(bx.const_i32(span.lo().to_u32() as i32))),
513-
);
508+
srcloc.extend(line_spans.iter().map(|span| {
509+
llvm::LLVMValueAsMetadata(bx.const_u64(
510+
u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32),
511+
))
512+
}));
514513
let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len());
515514
let md = llvm::LLVMMetadataAsValue(&bx.llcx, md);
516515
llvm::LLVMSetMetadata(call, kind, md);

compiler/rustc_codegen_llvm/src/back/write.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use rustc_session::Session;
2424
use rustc_session::config::{
2525
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
2626
};
27-
use rustc_span::InnerSpan;
2827
use rustc_span::symbol::sym;
28+
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext};
2929
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
3030
use tracing::debug;
3131

@@ -411,21 +411,32 @@ fn report_inline_asm(
411411
cgcx: &CodegenContext<LlvmCodegenBackend>,
412412
msg: String,
413413
level: llvm::DiagnosticLevel,
414-
mut cookie: u64,
414+
cookie: u64,
415415
source: Option<(String, Vec<InnerSpan>)>,
416416
) {
417417
// In LTO build we may get srcloc values from other crates which are invalid
418418
// since they use a different source map. To be safe we just suppress these
419419
// in LTO builds.
420-
if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
421-
cookie = 0;
422-
}
420+
let span = if cookie == 0 || matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
421+
SpanData::default()
422+
} else {
423+
let lo = BytePos::from_u32(cookie as u32);
424+
let hi = BytePos::from_u32((cookie >> 32) as u32);
425+
SpanData {
426+
lo,
427+
// LLVM version < 19 silently truncates the cookie to 32 bits in some situations.
428+
hi: if hi.to_u32() != 0 { hi } else { lo },
429+
ctxt: SyntaxContext::root(),
430+
parent: None,
431+
}
432+
};
423433
let level = match level {
424434
llvm::DiagnosticLevel::Error => Level::Error,
425435
llvm::DiagnosticLevel::Warning => Level::Warning,
426436
llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
427437
};
428-
cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
438+
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
439+
cgcx.diag_emitter.inline_asm_error(span, msg, level, source);
429440
}
430441

431442
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {

compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl InlineAsmDiagnostic {
151151
unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
152152
InlineAsmDiagnostic {
153153
level: smdiag.level,
154-
cookie: cookie.into(),
154+
cookie,
155155
message: smdiag.message,
156156
source: smdiag.source,
157157
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2271,7 +2271,7 @@ unsafe extern "C" {
22712271

22722272
pub fn LLVMRustGetSMDiagnostic<'a>(
22732273
DI: &'a DiagnosticInfo,
2274-
cookie_out: &mut c_uint,
2274+
cookie_out: &mut u64,
22752275
) -> &'a SMDiagnostic;
22762276

22772277
#[allow(improper_ctypes)]

compiler/rustc_codegen_ssa/src/back/write.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_session::config::{
3434
};
3535
use rustc_span::source_map::SourceMap;
3636
use rustc_span::symbol::sym;
37-
use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span};
37+
use rustc_span::{FileName, InnerSpan, Span, SpanData};
3838
use rustc_target::spec::{MergeFunctions, SanitizerSet};
3939
use tracing::debug;
4040

@@ -1852,7 +1852,7 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
18521852

18531853
enum SharedEmitterMessage {
18541854
Diagnostic(Diagnostic),
1855-
InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
1855+
InlineAsmError(SpanData, String, Level, Option<(String, Vec<InnerSpan>)>),
18561856
Fatal(String),
18571857
}
18581858

@@ -1874,12 +1874,12 @@ impl SharedEmitter {
18741874

18751875
pub fn inline_asm_error(
18761876
&self,
1877-
cookie: u32,
1877+
span: SpanData,
18781878
msg: String,
18791879
level: Level,
18801880
source: Option<(String, Vec<InnerSpan>)>,
18811881
) {
1882-
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
1882+
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(span, msg, level, source)));
18831883
}
18841884

18851885
fn fatal(&self, msg: &str) {
@@ -1964,17 +1964,12 @@ impl SharedEmitterMain {
19641964
dcx.emit_diagnostic(d);
19651965
sess.dcx().abort_if_errors();
19661966
}
1967-
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
1967+
Ok(SharedEmitterMessage::InlineAsmError(span, msg, level, source)) => {
19681968
assert_matches!(level, Level::Error | Level::Warning | Level::Note);
1969-
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
19701969
let mut err = Diag::<()>::new(sess.dcx(), level, msg);
1971-
1972-
// If the cookie is 0 then we don't have span information.
1973-
if cookie != 0 {
1974-
let pos = BytePos::from_u32(cookie);
1975-
let span = Span::with_root_ctxt(pos, pos);
1976-
err.span(span);
1977-
};
1970+
if !span.is_dummy() {
1971+
err.span(span.span());
1972+
}
19781973

19791974
// Point to the generated assembly if it is available.
19801975
if let Some((buffer, spans)) = source {

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
592592
&cause,
593593
hir.get_if_local(impl_m.def_id)
594594
.and_then(|node| node.fn_decl())
595-
.map(|decl| (decl.output.span(), Cow::from("return type in trait"))),
595+
.map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)),
596596
Some(infer::ValuePairs::Terms(ExpectedFound {
597597
expected: trait_return_ty.into(),
598598
found: impl_return_ty.into(),
599599
})),
600600
terr,
601601
false,
602-
false,
603602
);
604603
return Err(diag.emit());
605604
}
@@ -1018,14 +1017,13 @@ fn report_trait_method_mismatch<'tcx>(
10181017
infcx.err_ctxt().note_type_err(
10191018
&mut diag,
10201019
&cause,
1021-
trait_err_span.map(|sp| (sp, Cow::from("type in trait"))),
1020+
trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)),
10221021
Some(infer::ValuePairs::PolySigs(ExpectedFound {
10231022
expected: ty::Binder::dummy(trait_sig),
10241023
found: ty::Binder::dummy(impl_sig),
10251024
})),
10261025
terr,
10271026
false,
1028-
false,
10291027
);
10301028

10311029
diag.emit()
@@ -1825,14 +1823,13 @@ fn compare_const_predicate_entailment<'tcx>(
18251823
infcx.err_ctxt().note_type_err(
18261824
&mut diag,
18271825
&cause,
1828-
trait_c_span.map(|span| (span, Cow::from("type in trait"))),
1826+
trait_c_span.map(|span| (span, Cow::from("type in trait"), false)),
18291827
Some(infer::ValuePairs::Terms(ExpectedFound {
18301828
expected: trait_ty.into(),
18311829
found: impl_ty.into(),
18321830
})),
18331831
terr,
18341832
false,
1835-
false,
18361833
);
18371834
return Err(diag.emit());
18381835
};

compiler/rustc_hir_analysis/src/check/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,6 @@ pub fn check_function_signature<'tcx>(
652652
})),
653653
err,
654654
false,
655-
false,
656655
);
657656
return Err(diag.emit());
658657
}

compiler/rustc_hir_typeck/src/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
235235
Some(ret_coercion) => {
236236
let ret_ty = ret_coercion.borrow().expected_ty();
237237
let ret_ty = self.infcx.shallow_resolve(ret_ty);
238-
self.can_coerce(arm_ty, ret_ty)
239-
&& prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty))
238+
self.may_coerce(arm_ty, ret_ty)
239+
&& prior_arm.is_none_or(|(_, ty, _)| self.may_coerce(ty, ret_ty))
240240
// The match arms need to unify for the case of `impl Trait`.
241241
&& !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
242242
}

compiler/rustc_hir_typeck/src/cast.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
409409
let mut sugg_mutref = false;
410410
if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
411411
if let ty::RawPtr(expr_ty, _) = *self.expr_ty.kind()
412-
&& fcx.can_coerce(
412+
&& fcx.may_coerce(
413413
Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, expr_ty, mutbl),
414414
self.cast_ty,
415415
)
@@ -418,22 +418,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
418418
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
419419
&& expr_mutbl == Mutability::Not
420420
&& mutbl == Mutability::Mut
421-
&& fcx.can_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty)
421+
&& fcx.may_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty)
422422
{
423423
sugg_mutref = true;
424424
}
425425

426426
if !sugg_mutref
427427
&& sugg == None
428-
&& fcx.can_coerce(
428+
&& fcx.may_coerce(
429429
Ty::new_ref(fcx.tcx, reg, self.expr_ty, mutbl),
430430
self.cast_ty,
431431
)
432432
{
433433
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
434434
}
435435
} else if let ty::RawPtr(_, mutbl) = *self.cast_ty.kind()
436-
&& fcx.can_coerce(
436+
&& fcx.may_coerce(
437437
Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, self.expr_ty, mutbl),
438438
self.cast_ty,
439439
)

compiler/rustc_hir_typeck/src/coercion.rs

+30-12
Original file line numberDiff line numberDiff line change
@@ -1084,24 +1084,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10841084
})
10851085
}
10861086

1087-
/// Same as `coerce()`, but without side-effects.
1087+
/// Probe whether `expr_ty` can be coerced to `target_ty`. This has no side-effects,
1088+
/// and may return false positives if types are not yet fully constrained by inference.
10881089
///
1089-
/// Returns false if the coercion creates any obligations that result in
1090-
/// errors.
1091-
pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
1092-
// FIXME(-Znext-solver): We need to structurally resolve both types here.
1093-
let source = self.resolve_vars_with_obligations(expr_ty);
1094-
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
1095-
1090+
/// Returns false if the coercion is not possible, or if the coercion creates any
1091+
/// sub-obligations that result in errors.
1092+
///
1093+
/// This should only be used for diagnostics.
1094+
pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool {
10961095
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable);
10971096
// We don't ever need two-phase here since we throw out the result of the coercion.
10981097
// We also just always set `coerce_never` to true, since this is a heuristic.
1099-
let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true);
1098+
let coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No, true);
11001099
self.probe(|_| {
1101-
let Ok(ok) = coerce.coerce(source, target) else {
1100+
// Make sure to structurally resolve the types, since we use
1101+
// the `TyKind`s heavily in coercion.
1102+
let ocx = ObligationCtxt::new(self);
1103+
let structurally_resolve = |ty| {
1104+
let ty = self.shallow_resolve(ty);
1105+
if self.next_trait_solver()
1106+
&& let ty::Alias(..) = ty.kind()
1107+
{
1108+
ocx.structurally_normalize(&cause, self.param_env, ty)
1109+
} else {
1110+
Ok(ty)
1111+
}
1112+
};
1113+
let Ok(expr_ty) = structurally_resolve(expr_ty) else {
1114+
return false;
1115+
};
1116+
let Ok(target_ty) = structurally_resolve(target_ty) else {
1117+
return false;
1118+
};
1119+
1120+
let Ok(ok) = coerce.coerce(expr_ty, target_ty) else {
11021121
return false;
11031122
};
1104-
let ocx = ObligationCtxt::new(self);
11051123
ocx.register_obligations(ok.obligations);
11061124
ocx.select_where_possible().is_empty()
11071125
})
@@ -1370,7 +1388,7 @@ pub fn can_coerce<'tcx>(
13701388
) -> bool {
13711389
let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id);
13721390
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id);
1373-
fn_ctxt.can_coerce(ty, output_ty)
1391+
fn_ctxt.may_coerce(ty, output_ty)
13741392
}
13751393

13761394
/// CoerceMany encapsulates the pattern you should use when you have

compiler/rustc_hir_typeck/src/expr.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1330,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13301330
let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| {
13311331
let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs());
13321332
let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs());
1333-
self.can_coerce(rhs, lhs)
1333+
self.may_coerce(rhs, lhs)
13341334
};
1335-
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
1335+
let (applicability, eq) = if self.may_coerce(rhs_ty, lhs_ty) {
13361336
(Applicability::MachineApplicable, true)
13371337
} else if refs_can_coerce(rhs_ty, lhs_ty) {
13381338
// The lhs and rhs are likely missing some references in either side. Subsequent
@@ -1349,7 +1349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13491349
let actual_lhs_ty = self.check_expr(rhs_expr);
13501350
(
13511351
Applicability::MaybeIncorrect,
1352-
self.can_coerce(rhs_ty, actual_lhs_ty)
1352+
self.may_coerce(rhs_ty, actual_lhs_ty)
13531353
|| refs_can_coerce(rhs_ty, actual_lhs_ty),
13541354
)
13551355
} else if let ExprKind::Binary(
@@ -1363,7 +1363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13631363
let actual_rhs_ty = self.check_expr(lhs_expr);
13641364
(
13651365
Applicability::MaybeIncorrect,
1366-
self.can_coerce(actual_rhs_ty, lhs_ty)
1366+
self.may_coerce(actual_rhs_ty, lhs_ty)
13671367
|| refs_can_coerce(actual_rhs_ty, lhs_ty),
13681368
)
13691369
} else {
@@ -1414,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14141414
self.param_env,
14151415
)
14161416
.may_apply();
1417-
if lhs_deref_ty_is_sized && self.can_coerce(rhs_ty, lhs_deref_ty) {
1417+
if lhs_deref_ty_is_sized && self.may_coerce(rhs_ty, lhs_deref_ty) {
14181418
err.span_suggestion_verbose(
14191419
lhs.span.shrink_to_lo(),
14201420
"consider dereferencing here to assign to the mutably borrowed value",

0 commit comments

Comments
 (0)