Skip to content

Commit 49e5e4e

Browse files
committed
Auto merge of rust-lang#140043 - ChrisDenton:rollup-vwf0s9j, r=ChrisDenton
Rollup of 8 pull requests Successful merges: - rust-lang#138934 (support config extensions) - rust-lang#139091 (Rewrite on_unimplemented format string parser.) - rust-lang#139753 (Make `#[naked]` an unsafe attribute) - rust-lang#139762 (Don't assemble non-env/bound candidates if projection is rigid) - rust-lang#139834 (Don't canonicalize crate paths) - rust-lang#139868 (Move `pal::env` to `std::sys::env_consts`) - rust-lang#139978 (Add citool command for generating a test dashboard) - rust-lang#139995 (Clean UI tests 4 of n) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 90fd16e + f0a0efd commit 49e5e4e

File tree

138 files changed

+2813
-1576
lines changed

Some content is hidden

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

138 files changed

+2813
-1576
lines changed

bootstrap.example.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
# Note that this has no default value (x.py uses the defaults in `bootstrap.example.toml`).
2020
#profile = <none>
2121

22+
# Inherits configuration values from different configuration files (a.k.a. config extensions).
23+
# Supports absolute paths, and uses the current directory (where the bootstrap was invoked)
24+
# as the base if the given path is not absolute.
25+
#
26+
# The overriding logic follows a right-to-left order. For example, in `include = ["a.toml", "b.toml"]`,
27+
# extension `b.toml` overrides `a.toml`. Also, parent extensions always overrides the inner ones.
28+
#include = []
29+
2230
# Keeps track of major changes made to this configuration.
2331
#
2432
# This value also represents ID of the PR that caused major changes. Meaning,

compiler/rustc_builtin_macros/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ builtin_macros_multiple_defaults = multiple declared defaults
247247
.suggestion = make `{$ident}` default
248248
249249
builtin_macros_naked_functions_testing_attribute =
250-
cannot use `#[naked]` with testing attributes
250+
cannot use `#[unsafe(naked)]` with testing attributes
251251
.label = function marked with testing attribute here
252-
.naked_attribute = `#[naked]` is incompatible with testing attributes
252+
.naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes
253253
254254
builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
255255
.label = this enum needs a unit variant marked with `#[default]`

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,9 @@ global_asm! {
387387
}
388388

389389
#[cfg(all(not(jit), target_arch = "x86_64"))]
390-
#[naked]
390+
#[unsafe(naked)]
391391
extern "C" fn naked_test() {
392-
unsafe {
393-
naked_asm!("ret");
394-
}
392+
naked_asm!("ret")
395393
}
396394

397395
#[repr(C)]

compiler/rustc_error_codes/src/error_codes/E0736.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Erroneous code example:
1111

1212
```compile_fail,E0736
1313
#[inline]
14-
#[naked]
14+
#[unsafe(naked)]
1515
fn foo() {}
1616
```
1717

compiler/rustc_error_codes/src/error_codes/E0787.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Erroneous code example:
55
```compile_fail,E0787
66
#![feature(naked_functions)]
77
8-
#[naked]
8+
#[unsafe(naked)]
99
pub extern "C" fn f() -> u32 {
1010
42
1111
}

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
517517

518518
// Linking:
519519
gated!(
520-
naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
520+
unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
521521
naked_functions, experimental!(naked)
522522
),
523523

compiler/rustc_metadata/src/locator.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,21 @@ impl<'a> CrateLocator<'a> {
427427

428428
let (rlibs, rmetas, dylibs) =
429429
candidates.entry(hash.to_string()).or_default();
430-
let path =
431-
try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.to_path_buf());
432-
if seen_paths.contains(&path) {
433-
continue;
434-
};
435-
seen_paths.insert(path.clone());
430+
{
431+
// As a perforamnce optimisation we canonicalize the path and skip
432+
// ones we've already seeen. This allows us to ignore crates
433+
// we know are exactual equal to ones we've already found.
434+
// Going to the same crate through different symlinks does not change the result.
435+
let path = try_canonicalize(&spf.path)
436+
.unwrap_or_else(|_| spf.path.to_path_buf());
437+
if seen_paths.contains(&path) {
438+
continue;
439+
};
440+
seen_paths.insert(path);
441+
}
442+
// Use the original path (potentially with unresolved symlinks),
443+
// filesystem code should not care, but this is nicer for diagnostics.
444+
let path = spf.path.to_path_buf();
436445
match kind {
437446
CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
438447
CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,13 +564,17 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
564564
}
565565
}
566566
ExprKind::InlineAsm(box InlineAsmExpr {
567-
asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
567+
asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm),
568568
ref operands,
569569
template: _,
570570
options: _,
571571
line_spans: _,
572572
}) => {
573-
self.requires_unsafe(expr.span, UseOfInlineAssembly);
573+
// The `naked` attribute and the `naked_asm!` block form one atomic unit of
574+
// unsafety, and `naked_asm!` does not itself need to be wrapped in an unsafe block.
575+
if let AsmMacro::Asm = asm_macro {
576+
self.requires_unsafe(expr.span, UseOfInlineAssembly);
577+
}
574578

575579
// For inline asm, do not use `walk_expr`, since we want to handle the label block
576580
// specially.

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,21 @@ where
288288
) -> Vec<Candidate<I>>;
289289
}
290290

291+
/// Allows callers of `assemble_and_evaluate_candidates` to choose whether to limit
292+
/// candidate assembly to param-env and alias-bound candidates.
293+
///
294+
/// On top of being a micro-optimization, as it avoids doing unnecessary work when
295+
/// a param-env trait bound candidate shadows impls for normalization, this is also
296+
/// required to prevent query cycles due to RPITIT inference. See the issue at:
297+
/// <https://github.com/rust-lang/trait-system-refactor-initiative/issues/173>.
298+
pub(super) enum AssembleCandidatesFrom {
299+
All,
300+
/// Only assemble candidates from the environment and alias bounds, ignoring
301+
/// user-written and built-in impls. We only expect `ParamEnv` and `AliasBound`
302+
/// candidates to be assembled.
303+
EnvAndBounds,
304+
}
305+
291306
impl<D, I> EvalCtxt<'_, D>
292307
where
293308
D: SolverDelegate<Interner = I>,
@@ -296,6 +311,7 @@ where
296311
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
297312
&mut self,
298313
goal: Goal<I, G>,
314+
assemble_from: AssembleCandidatesFrom,
299315
) -> Vec<Candidate<I>> {
300316
let Ok(normalized_self_ty) =
301317
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
@@ -322,16 +338,18 @@ where
322338
}
323339
}
324340

325-
self.assemble_impl_candidates(goal, &mut candidates);
326-
327-
self.assemble_builtin_impl_candidates(goal, &mut candidates);
328-
329341
self.assemble_alias_bound_candidates(goal, &mut candidates);
330-
331-
self.assemble_object_bound_candidates(goal, &mut candidates);
332-
333342
self.assemble_param_env_candidates(goal, &mut candidates);
334343

344+
match assemble_from {
345+
AssembleCandidatesFrom::All => {
346+
self.assemble_impl_candidates(goal, &mut candidates);
347+
self.assemble_builtin_impl_candidates(goal, &mut candidates);
348+
self.assemble_object_bound_candidates(goal, &mut candidates);
349+
}
350+
AssembleCandidatesFrom::EnvAndBounds => {}
351+
}
352+
335353
candidates
336354
}
337355

@@ -754,6 +772,9 @@ where
754772
})
755773
}
756774

775+
/// Assemble and merge candidates for goals which are related to an underlying trait
776+
/// goal. Right now, this is normalizes-to and host effect goals.
777+
///
757778
/// We sadly can't simply take all possible candidates for normalization goals
758779
/// and check whether they result in the same constraints. We want to make sure
759780
/// that trying to normalize an alias doesn't result in constraints which aren't
@@ -782,47 +803,44 @@ where
782803
///
783804
/// See trait-system-refactor-initiative#124 for more details.
784805
#[instrument(level = "debug", skip(self, inject_normalize_to_rigid_candidate), ret)]
785-
pub(super) fn merge_candidates(
806+
pub(super) fn assemble_and_merge_candidates<G: GoalKind<D>>(
786807
&mut self,
787808
proven_via: Option<TraitGoalProvenVia>,
788-
candidates: Vec<Candidate<I>>,
809+
goal: Goal<I, G>,
789810
inject_normalize_to_rigid_candidate: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
790811
) -> QueryResult<I> {
791812
let Some(proven_via) = proven_via else {
792813
// We don't care about overflow. If proving the trait goal overflowed, then
793814
// it's enough to report an overflow error for that, we don't also have to
794815
// overflow during normalization.
795-
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Ambiguity));
816+
//
817+
// We use `forced_ambiguity` here over `make_ambiguous_response_no_constraints`
818+
// because the former will also record a built-in candidate in the inspector.
819+
return self.forced_ambiguity(MaybeCause::Ambiguity).map(|cand| cand.result);
796820
};
797821

798822
match proven_via {
799823
TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => {
800-
let mut considered_candidates = Vec::new();
801-
considered_candidates.extend(
802-
candidates
803-
.iter()
804-
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
805-
.map(|c| c.result),
806-
);
807-
808824
// Even when a trait bound has been proven using a where-bound, we
809825
// still need to consider alias-bounds for normalization, see
810-
// tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
811-
//
826+
// `tests/ui/next-solver/alias-bound-shadowed-by-env.rs`.
827+
let candidates_from_env_and_bounds: Vec<_> = self
828+
.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::EnvAndBounds);
829+
812830
// We still need to prefer where-bounds over alias-bounds however.
813-
// See tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs.
814-
//
815-
// FIXME(const_trait_impl): should this behavior also be used by
816-
// constness checking. Doing so is *at least theoretically* breaking,
817-
// see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754
818-
if considered_candidates.is_empty() {
819-
considered_candidates.extend(
820-
candidates
821-
.iter()
822-
.filter(|c| matches!(c.source, CandidateSource::AliasBound))
823-
.map(|c| c.result),
824-
);
825-
}
831+
// See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`.
832+
let mut considered_candidates: Vec<_> = if candidates_from_env_and_bounds
833+
.iter()
834+
.any(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
835+
{
836+
candidates_from_env_and_bounds
837+
.into_iter()
838+
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
839+
.map(|c| c.result)
840+
.collect()
841+
} else {
842+
candidates_from_env_and_bounds.into_iter().map(|c| c.result).collect()
843+
};
826844

827845
// If the trait goal has been proven by using the environment, we want to treat
828846
// aliases as rigid if there are no applicable projection bounds in the environment.
@@ -839,6 +857,9 @@ where
839857
}
840858
}
841859
TraitGoalProvenVia::Misc => {
860+
let candidates =
861+
self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
862+
842863
// Prefer "orphaned" param-env normalization predicates, which are used
843864
// (for example, and ideally only) when proving item bounds for an impl.
844865
let candidates_from_env: Vec<_> = candidates

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,11 @@ where
399399
&mut self,
400400
goal: Goal<I, ty::HostEffectPredicate<I>>,
401401
) -> QueryResult<I> {
402-
let candidates = self.assemble_and_evaluate_candidates(goal);
403402
let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
404403
let trait_goal: Goal<I, ty::TraitPredicate<I>> =
405404
goal.with(ecx.cx(), goal.predicate.trait_ref);
406405
ecx.compute_trait_goal(trait_goal)
407406
})?;
408-
self.merge_candidates(proven_via, candidates, |_ecx| Err(NoSolution))
407+
self.assemble_and_merge_candidates(proven_via, goal, |_ecx| Err(NoSolution))
409408
}
410409
}

0 commit comments

Comments
 (0)