Skip to content

Commit c829707

Browse files
committed
Auto merge of #148178 - matthiaskrgr:rollup-yy0swwt, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #147840 (Rework unsizing coercions in the new solver) - #148139 (Add `coverage` scope for controlling paths in code coverage) - #148154 (Add a mailmap entry) - #148158 (ci: loongarch64: use medium code model to avoid relocation overflows) - #148172 (rustc-dev-guide subtree update) - #148175 (Fix typos: duplicate words in comments) r? `@ghost` `@rustbot` modify labels: rollup
2 parents adaa838 + c315850 commit c829707

39 files changed

+402
-58
lines changed

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ Valerii Lashmanov <[email protected]>
680680
Vitali Haravy <[email protected]> Vitali Haravy <[email protected]>
681681
Vitaly Shukela <[email protected]>
682682
Waffle Lapkin <[email protected]>
683+
Waffle Lapkin <[email protected]> <Waffle Lapkin>
683684
684685
Weihang Lo <[email protected]>
685686

compiler/rustc_ast_pretty/src/pp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ impl Printer {
298298
}
299299
}
300300

301-
// This is is where `BoxMarker`s are produced.
301+
// This is where `BoxMarker`s are produced.
302302
fn scan_begin(&mut self, token: BeginToken) -> BoxMarker {
303303
if self.scan_stack.is_empty() {
304304
self.left_total = 1;
@@ -310,7 +310,7 @@ impl Printer {
310310
BoxMarker
311311
}
312312

313-
// This is is where `BoxMarker`s are consumed.
313+
// This is where `BoxMarker`s are consumed.
314314
fn scan_end(&mut self, b: BoxMarker) {
315315
if self.scan_stack.is_empty() {
316316
self.print_end();

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl GlobalFileTable {
128128
for file in all_files {
129129
raw_file_table.entry(file.stable_id).or_insert_with(|| {
130130
file.name
131-
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
131+
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
132132
.to_string_lossy()
133133
.into_owned()
134134
});
@@ -147,7 +147,7 @@ impl GlobalFileTable {
147147
.sess
148148
.opts
149149
.working_dir
150-
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
150+
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
151151
.to_string_lossy();
152152
table.push(base_dir.as_ref());
153153

compiler/rustc_const_eval/src/interpret/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {
121121
/// ### `tracing_separate_thread` parameter
122122
///
123123
/// This macro was introduced to obtain better traces of Miri without impacting release performance.
124-
/// Miri saves traces using the the `tracing_chrome` `tracing::Layer` so that they can be visualized
124+
/// Miri saves traces using the `tracing_chrome` `tracing::Layer` so that they can be visualized
125125
/// in <https://ui.perfetto.dev>. To instruct `tracing_chrome` to put some spans on a separate trace
126126
/// thread/line than other spans when viewed in <https://ui.perfetto.dev>, you can pass
127127
/// `tracing_separate_thread = tracing::field::Empty` to the tracing macros. This is useful to

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 107 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@
3535
//! // and are then unable to coerce `&7i32` to `&mut i32`.
3636
//! ```
3737
38-
use std::ops::Deref;
38+
use std::ops::{ControlFlow, Deref};
3939

4040
use rustc_errors::codes::*;
4141
use rustc_errors::{Applicability, Diag, struct_span_code_err};
42-
use rustc_hir as hir;
4342
use rustc_hir::attrs::InlineAttr;
4443
use rustc_hir::def_id::{DefId, LocalDefId};
44+
use rustc_hir::{self as hir, LangItem};
4545
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
4646
use rustc_infer::infer::relate::RelateResult;
4747
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, InferResult, RegionVariableOrigin};
@@ -56,6 +56,8 @@ use rustc_middle::ty::error::TypeError;
5656
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
5757
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
5858
use rustc_trait_selection::infer::InferCtxtExt as _;
59+
use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
60+
use rustc_trait_selection::solve::{Certainty, Goal, NoSolution};
5961
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
6062
use rustc_trait_selection::traits::{
6163
self, ImplSource, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
@@ -639,24 +641,52 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
639641
Adjust::Pointer(PointerCoercion::Unsize),
640642
)?;
641643

642-
let mut selcx = traits::SelectionContext::new(self);
643-
644644
// Create an obligation for `Source: CoerceUnsized<Target>`.
645645
let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target });
646+
let pred = ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]);
647+
let obligation = Obligation::new(self.tcx, cause, self.fcx.param_env, pred);
648+
649+
if self.next_trait_solver() {
650+
coercion.obligations.push(obligation);
651+
652+
if self
653+
.infcx
654+
.visit_proof_tree(
655+
Goal::new(self.tcx, self.param_env, pred),
656+
&mut CoerceVisitor { fcx: self.fcx, span: self.cause.span },
657+
)
658+
.is_break()
659+
{
660+
return Err(TypeError::Mismatch);
661+
}
662+
} else {
663+
self.coerce_unsized_old_solver(
664+
obligation,
665+
&mut coercion,
666+
coerce_unsized_did,
667+
unsize_did,
668+
)?;
669+
}
646670

671+
Ok(coercion)
672+
}
673+
674+
fn coerce_unsized_old_solver(
675+
&self,
676+
obligation: Obligation<'tcx, ty::Predicate<'tcx>>,
677+
coercion: &mut InferOk<'tcx, (Vec<Adjustment<'tcx>>, Ty<'tcx>)>,
678+
coerce_unsized_did: DefId,
679+
unsize_did: DefId,
680+
) -> Result<(), TypeError<'tcx>> {
681+
let mut selcx = traits::SelectionContext::new(self);
647682
// Use a FIFO queue for this custom fulfillment procedure.
648683
//
649684
// A Vec (or SmallVec) is not a natural choice for a queue. However,
650685
// this code path is hot, and this queue usually has a max length of 1
651686
// and almost never more than 3. By using a SmallVec we avoid an
652687
// allocation, at the (very small) cost of (occasionally) having to
653688
// shift subsequent elements down when removing the front element.
654-
let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new(
655-
self.tcx,
656-
cause,
657-
self.fcx.param_env,
658-
ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
659-
)];
689+
let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![obligation];
660690

661691
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
662692
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@@ -749,7 +779,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
749779
// with the unsizing - the lack of a coercion should
750780
// be silent, as it causes a type mismatch later.
751781
}
752-
753782
Ok(Some(ImplSource::UserDefined(impl_source))) => {
754783
queue.extend(impl_source.nested);
755784
// Certain incoherent `CoerceUnsized` implementations may cause ICEs,
@@ -767,7 +796,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
767796
}
768797
}
769798

770-
Ok(coercion)
799+
Ok(())
771800
}
772801

773802
/// Applies reborrowing for `Pin`
@@ -2005,3 +2034,69 @@ impl AsCoercionSite for hir::Arm<'_> {
20052034
self.body
20062035
}
20072036
}
2037+
2038+
/// Recursively visit goals to decide whether an unsizing is possible.
2039+
/// `Break`s when it isn't, and an error should be raised.
2040+
/// `Continue`s when an unsizing ok based on an implementation of the `Unsize` trait / lang item.
2041+
struct CoerceVisitor<'a, 'tcx> {
2042+
fcx: &'a FnCtxt<'a, 'tcx>,
2043+
span: Span,
2044+
}
2045+
2046+
impl<'tcx> ProofTreeVisitor<'tcx> for CoerceVisitor<'_, 'tcx> {
2047+
type Result = ControlFlow<()>;
2048+
2049+
fn span(&self) -> Span {
2050+
self.span
2051+
}
2052+
2053+
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
2054+
let Some(pred) = goal.goal().predicate.as_trait_clause() else {
2055+
return ControlFlow::Continue(());
2056+
};
2057+
2058+
// Make sure this predicate is referring to either an `Unsize` or `CoerceUnsized` trait,
2059+
// Otherwise there's nothing to do.
2060+
if !self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::Unsize)
2061+
&& !self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::CoerceUnsized)
2062+
{
2063+
return ControlFlow::Continue(());
2064+
}
2065+
2066+
match goal.result() {
2067+
// If we prove the `Unsize` or `CoerceUnsized` goal, continue recursing.
2068+
Ok(Certainty::Yes) => ControlFlow::Continue(()),
2069+
Err(NoSolution) => {
2070+
// Even if we find no solution, continue recursing if we find a single candidate
2071+
// for which we're shallowly certain it holds to get the right error source.
2072+
if let [only_candidate] = &goal.candidates()[..]
2073+
&& only_candidate.shallow_certainty() == Certainty::Yes
2074+
{
2075+
only_candidate.visit_nested_no_probe(self)
2076+
} else {
2077+
ControlFlow::Break(())
2078+
}
2079+
}
2080+
Ok(Certainty::Maybe { .. }) => {
2081+
// FIXME: structurally normalize?
2082+
if self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::Unsize)
2083+
&& let ty::Dynamic(..) = pred.skip_binder().trait_ref.args.type_at(1).kind()
2084+
&& let ty::Infer(ty::TyVar(vid)) = *pred.self_ty().skip_binder().kind()
2085+
&& self.fcx.type_var_is_sized(vid)
2086+
{
2087+
// We get here when trying to unsize a type variable to a `dyn Trait`,
2088+
// knowing that that variable is sized. Unsizing definitely has to happen in that case.
2089+
// If the variable weren't sized, we may not need an unsizing coercion.
2090+
// In general, we don't want to add coercions too eagerly since it makes error messages much worse.
2091+
ControlFlow::Continue(())
2092+
} else if let Some(cand) = goal.unique_applicable_candidate()
2093+
&& cand.shallow_certainty() == Certainty::Yes
2094+
{
2095+
cand.visit_nested_no_probe(self)
2096+
} else {
2097+
ControlFlow::Break(())
2098+
}
2099+
}
2100+
}
2101+
}
2102+
}

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
55
use rustc_span::Span;
66
use rustc_trait_selection::solve::Certainty;
77
use rustc_trait_selection::solve::inspect::{
8-
InspectConfig, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor,
8+
InferCtxtProofTreeExt, InspectConfig, InspectGoal, ProofTreeVisitor,
99
};
1010
use tracing::{debug, instrument, trace};
1111

compiler/rustc_session/src/config.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,10 +1386,12 @@ bitflags::bitflags! {
13861386
const DIAGNOSTICS = 1 << 1;
13871387
/// Apply remappings to debug information
13881388
const DEBUGINFO = 1 << 3;
1389+
/// Apply remappings to coverage information
1390+
const COVERAGE = 1 << 4;
13891391

1390-
/// An alias for `macro` and `debuginfo`. This ensures all paths in compiled
1391-
/// executables or libraries are remapped but not elsewhere.
1392-
const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits();
1392+
/// An alias for `macro`, `debuginfo` and `coverage`. This ensures all paths in compiled
1393+
/// executables, libraries and objects are remapped but not elsewhere.
1394+
const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits() | Self::COVERAGE.bits();
13931395
}
13941396
}
13951397

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,8 +869,7 @@ mod desc {
869869
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)";
870870
pub(crate) const parse_proc_macro_execution_strategy: &str =
871871
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
872-
pub(crate) const parse_remap_path_scope: &str =
873-
"comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`";
872+
pub(crate) const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`";
874873
pub(crate) const parse_inlining_threshold: &str =
875874
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
876875
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
@@ -1705,6 +1704,7 @@ pub mod parse {
17051704
"macro" => RemapPathScopeComponents::MACRO,
17061705
"diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
17071706
"debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1707+
"coverage" => RemapPathScopeComponents::COVERAGE,
17081708
"object" => RemapPathScopeComponents::OBJECT,
17091709
"all" => RemapPathScopeComponents::all(),
17101710
_ => return false,

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use tracing::instrument;
2424
use self::derive_errors::*;
2525
use super::Certainty;
2626
use super::delegate::SolverDelegate;
27-
use super::inspect::{self, ProofTreeInferCtxtExt};
27+
use super::inspect::{self, InferCtxtProofTreeExt};
2828
use crate::traits::{FulfillmentError, ScrubbedTraitError};
2929

3030
mod derive_errors;

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _}
1515
use tracing::{instrument, trace};
1616

1717
use crate::solve::delegate::SolverDelegate;
18-
use crate::solve::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
18+
use crate::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
1919
use crate::solve::{Certainty, deeply_normalize_for_diagnostics};
2020
use crate::traits::{FulfillmentError, FulfillmentErrorCode, wf};
2121

0 commit comments

Comments
 (0)