Skip to content

Rollup of 14 pull requests #141041

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
14662fa
docs(library/core/src/pin): fix typo "necessarily" -> "necessary"
ruancomelli Apr 13, 2025
6f23f16
docs(library/core/src/pin): rewrite for clarity
ruancomelli Apr 13, 2025
80758c3
add rdg push git config entry for git protocol pushers
tshepang May 1, 2025
53459ff
Simplify `Vec::as_non_null` implementation and make it `const`
viliml May 5, 2025
6e966d7
avoid duplicating commands
tshepang May 6, 2025
046bfb3
Preparing for merge from rustc
invalid-email-address May 8, 2025
659f0b6
Merge from rustc
invalid-email-address May 8, 2025
b2de3f4
Merge pull request #2374 from rust-lang/rustc-pull
tshepang May 8, 2025
47cd0e7
Fix minor typo in serialization.md
smanilov May 8, 2025
f52e1be
Merge pull request #2375 from smanilov/patch-4
tshepang May 8, 2025
d87763d
Remark test naming exception
smanilov May 8, 2025
f31bf4a
Merge pull request #2323 from smanilov/patch-2
BoxyUwU May 8, 2025
a07c71d
Fix minor typo in installation.md
smanilov May 8, 2025
079e0b4
Merge pull request #2377 from smanilov/patch-6
tshepang May 8, 2025
31ebe11
normalization: avoid incompletely constraining GAT args
lcnr May 6, 2025
0185484
refactor `probe_and_consider_param_env_candidate`
lcnr May 8, 2025
9eac7a3
move (and remove) impl Trait tests
lcnr May 9, 2025
3052683
Fix minor typo in rustdoc-internals.md
smanilov May 8, 2025
6831638
Merge pull request #2376 from smanilov/patch-5
tshepang May 9, 2025
0533ff7
more moved tests
lcnr May 9, 2025
90ec9da
Merge pull request #2369 from rust-lang/tshepang-patch-1
tshepang May 10, 2025
c1de624
link to chapter referred to
tshepang May 10, 2025
8c6c97d
use the right case
tshepang May 10, 2025
4e684a9
make more clear what is meant
tshepang May 10, 2025
9f07c1e
make more readable
tshepang May 10, 2025
2efa4e6
sembr
tshepang May 10, 2025
eb6749c
is a question
tshepang May 10, 2025
a82a329
fix broken links
tshepang May 10, 2025
5d8e19f
reduce clutter when reading source
tshepang May 10, 2025
7b9d7fc
sembr
tshepang May 10, 2025
f1d1ebc
last updated a year ago
tshepang May 10, 2025
52e4b4a
add missing word
tshepang May 10, 2025
927343e
no point versioning these
tshepang May 10, 2025
a9d6551
bump edition
tshepang May 10, 2025
63b3bf9
"cargo fmt"
tshepang May 10, 2025
58fa975
we are a collective
tshepang May 10, 2025
5a406be
noise
tshepang May 10, 2025
53ef2e0
Add LLDB providers for BTreeMap and BTreeSet
ede1998 Apr 21, 2025
aeea472
Remove `stable` attribute from wasi fs (read_exact|write_all)_at
paolobarbolini May 10, 2025
2a0c72e
Remove obsolete reference to `unsized_tuple_coercion`
Zalathar May 12, 2025
53572cf
Merge pull request #2382 from Zalathar/no-tuple-unsize
JohnTitor May 12, 2025
436c363
Remove n.b. about parser refactoring
smanilov May 9, 2025
e983642
Merge pull request #2378 from smanilov/patch-7
jieyouxu May 12, 2025
df1da67
Flush errors before deep normalize in dropck_outlives
compiler-errors May 12, 2025
b255ae2
remove dangling references
tshepang May 12, 2025
a508011
Expect deep norm to fail if query norm failed
compiler-errors May 12, 2025
a1ea0ce
[win] Use a dash instead of slash for linker to avoid breaking lld
dpaoliello May 13, 2025
79b2794
Remove #![feature(let_chains)] from library and src/librustdoc
est31 May 13, 2025
e1f1878
Fix set_name for vxworks. Length of name should be truncated to VX_TA…
biabbas May 14, 2025
544c8ce
Fix settimes for vxworks
biabbas May 14, 2025
1267333
Improve ternary operator recovery
jamie-osec May 14, 2025
ac1df15
Improve `dangerous_implicit_aurorefs` diagnostic output
Urgau May 7, 2025
e0b6363
wire up startupinfo methods
federico-terzi May 14, 2025
9b3abe7
Use more subdiagnostics and reword the overloaded deref note
Urgau May 14, 2025
032f738
Merge pull request #2383 from rust-lang/tshepang-unused
tshepang May 14, 2025
b805dcb
Merge pull request #2380 from rust-lang/tshepang-crate-cleaning
tshepang May 14, 2025
30b54ad
Merge pull request #2379 from rust-lang/tshepang-which-chapter
tshepang May 14, 2025
05e7ce9
Merge pull request #2373 from rust-lang/tshepang-patch-2
tshepang May 14, 2025
5e3aa16
avoid upstream pull conflict
tshepang May 15, 2025
d016ed8
Merge pull request #2387 from rust-lang/tshepang-avoid-conflict
tshepang May 15, 2025
4adff2f
Preparing for merge from rustc
invalid-email-address May 15, 2025
1fd536c
Merge from rustc
invalid-email-address May 15, 2025
a3ce646
Merge pull request #2388 from rust-lang/rustc-pull
tshepang May 15, 2025
6ee49ab
Rollup merge of #139749 - ruancomelli:docs/library/core/src/pin/fix-t…
compiler-errors May 15, 2025
56df335
Rollup merge of #140130 - ede1998:add-lldb-btree-providers, r=Mark-Si…
compiler-errors May 15, 2025
fc11361
Rollup merge of #140685 - viliml:patch-1, r=Mark-Simulacrum
compiler-errors May 15, 2025
53fa4d7
Rollup merge of #140712 - lcnr:normalization-gat-args, r=compiler-errors
compiler-errors May 15, 2025
d23a82e
Rollup merge of #140768 - Urgau:improv_autorefs-lint, r=fmease
compiler-errors May 15, 2025
0ee8f1e
Rollup merge of #140834 - lcnr:apit-folder, r=compiler-errors
compiler-errors May 15, 2025
80b5da5
Rollup merge of #140910 - paolobarbolini:wasi-fs-incorrect-stabilizat…
compiler-errors May 15, 2025
0904424
Rollup merge of #140947 - compiler-errors:pending-norm, r=lcnr
compiler-errors May 15, 2025
b81bdbc
Rollup merge of #140966 - est31:let_chains_library, r=tgross35
compiler-errors May 15, 2025
a933842
Rollup merge of #140977 - dpaoliello:dash, r=jieyouxu
compiler-errors May 15, 2025
2686217
Rollup merge of #140990 - biabbas:vxworks, r=tgross35
compiler-errors May 15, 2025
c39fdc4
Rollup merge of #141003 - clubby789:ternary-improve, r=compiler-errors
compiler-errors May 15, 2025
996cb38
Rollup merge of #141013 - federico-terzi:feat/command_startupinfo_win…
compiler-errors May 15, 2025
b9f2cfa
Rollup merge of #141026 - tshepang:rust-push, r=jieyouxu
compiler-errors May 15, 2025
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: 1 addition & 7 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,13 +621,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
&ocx, op, span,
) {
Ok(_) => ocx.select_all_or_error(),
Err(e) => {
if e.is_empty() {
ocx.select_all_or_error()
} else {
e
}
}
Err(e) => e,
};

// Could have no errors if a type lowering error, say, caused the query
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ lint_impl_trait_redundant_captures = all possible in-scope parameters are alread

lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
.raw_ptr = this raw pointer has type `{$raw_ptr_ty}`
.autoref = autoref is being applied to this expression, resulting in: `{$autoref_ty}`
.overloaded_deref = references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
.method_def = method calls to `{$method_name}` require a reference
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit

lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
Expand Down
42 changes: 29 additions & 13 deletions compiler/rustc_lint/src/autorefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDer
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;

use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
use crate::lints::{
ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin,
ImplicitUnsafeAutorefsSuggestion,
};
use crate::{LateContext, LateLintPass, LintContext};

declare_lint! {
Expand Down Expand Up @@ -92,25 +95,37 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
&& let adjustments = peel_derefs_adjustments(&**adjustments)
// 3. An automatically inserted reference (might come from a deref).
&& let [adjustment] = adjustments
&& let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
&& let Some((borrow_mutbl, through_overloaded_deref)) = has_implicit_borrow(adjustment)
&& let ExprKind::Unary(UnOp::Deref, dereferenced) =
// 2. Any number of place projections.
peel_place_mappers(inner).kind
// 1. Deref of a raw pointer.
&& typeck.expr_ty(dereferenced).is_raw_ptr()
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
&& match expr.kind {
ExprKind::MethodCall(..) => matches!(
cx.typeck_results().type_dependent_def_id(expr.hir_id),
Some(def_id) if cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs)
),
_ => true,
&& let method_did = match expr.kind {
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
_ => None,
}
&& method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true)
{
cx.emit_span_lint(
DANGEROUS_IMPLICIT_AUTOREFS,
expr.span.source_callsite(),
ImplicitUnsafeAutorefsDiag {
raw_ptr_span: dereferenced.span,
raw_ptr_ty: typeck.expr_ty(dereferenced),
origin: if through_overloaded_deref {
ImplicitUnsafeAutorefsOrigin::OverloadedDeref
} else {
ImplicitUnsafeAutorefsOrigin::Autoref {
autoref_span: inner.span,
autoref_ty: typeck.expr_ty_adjusted(inner),
}
},
method: method_did.map(|did| ImplicitUnsafeAutorefsMethodNote {
def_span: cx.tcx.def_span(did),
method_name: cx.tcx.item_name(did),
}),
suggestion: ImplicitUnsafeAutorefsSuggestion {
mutbl: borrow_mutbl.ref_prefix_str(),
deref: if is_coming_from_deref { "*" } else { "" },
Expand Down Expand Up @@ -146,11 +161,12 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen

/// Test if some adjustment has some implicit borrow.
///
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
/// Returns `Some((mutability, was_an_overloaded_deref))` if the argument adjustment is
/// an implicit borrow (or has an implicit borrow via an overloaded deref).
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Mutability, bool)> {
match kind {
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some((mutbl, true)),
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some((mutbl.into(), false)),
Adjust::NeverToAny
| Adjust::Pointer(..)
| Adjust::ReborrowPin(..)
Expand Down
29 changes: 28 additions & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,38 @@ pub(crate) enum ShadowedIntoIterDiagSub {
#[derive(LintDiagnostic)]
#[diag(lint_implicit_unsafe_autorefs)]
#[note]
pub(crate) struct ImplicitUnsafeAutorefsDiag {
pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> {
#[label(lint_raw_ptr)]
pub raw_ptr_span: Span,
pub raw_ptr_ty: Ty<'a>,
#[subdiagnostic]
pub origin: ImplicitUnsafeAutorefsOrigin<'a>,
#[subdiagnostic]
pub method: Option<ImplicitUnsafeAutorefsMethodNote>,
#[subdiagnostic]
pub suggestion: ImplicitUnsafeAutorefsSuggestion,
}

#[derive(Subdiagnostic)]
pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> {
#[note(lint_autoref)]
Autoref {
#[primary_span]
autoref_span: Span,
autoref_ty: Ty<'a>,
},
#[note(lint_overloaded_deref)]
OverloadedDeref,
}

#[derive(Subdiagnostic)]
#[note(lint_method_def)]
pub(crate) struct ImplicitUnsafeAutorefsMethodNote {
#[primary_span]
pub def_span: Span,
pub method_name: Symbol,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct ImplicitUnsafeAutorefsSuggestion {
Expand Down
38 changes: 19 additions & 19 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub(super) mod structural_traits;

use std::cell::Cell;
use std::ops::ControlFlow;

use derive_where::derive_where;
Expand Down Expand Up @@ -117,24 +118,24 @@ where
) -> Result<Candidate<I>, NoSolution> {
Self::fast_reject_assumption(ecx, goal, assumption)?;

ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
Ok(candidate) => inspect::ProbeKind::TraitCandidate {
source: candidate.source,
result: Ok(candidate.result),
},
Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
source: CandidateSource::ParamEnv(ParamEnvSource::Global),
result: Err(NoSolution),
},
// Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily
// check whether the candidate is global while considering normalization.
//
// We need to write into `source` inside of `match_assumption`, but need to access it
// in `probe` even if the candidate does not apply before we get there. We handle this
// by using a `Cell` here. We only ever write into it inside of `match_assumption`.
let source = Cell::new(CandidateSource::ParamEnv(ParamEnvSource::Global));
ecx.probe(|result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
source: source.get(),
result: *result,
})
.enter(|ecx| {
Self::match_assumption(ecx, goal, assumption)?;
let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
Ok(Candidate {
source,
result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
Self::match_assumption(ecx, goal, assumption, |ecx| {
source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
})
.map(|result| Candidate { source: source.get(), result })
}

/// Try equating an assumption predicate against a goal's predicate. If it
Expand All @@ -150,10 +151,8 @@ where
) -> Result<Candidate<I>, NoSolution> {
Self::fast_reject_assumption(ecx, goal, assumption)?;

ecx.probe_trait_candidate(source).enter(|ecx| {
Self::match_assumption(ecx, goal, assumption)?;
then(ecx)
})
ecx.probe_trait_candidate(source)
.enter(|ecx| Self::match_assumption(ecx, goal, assumption, then))
}

/// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
Expand All @@ -169,7 +168,8 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution>;
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I>;

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let host_clause = assumption.as_host_effect_clause().unwrap();

let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;

Ok(())
then(ecx)
}

/// Register additional assumptions for aliases corresponding to `~const` item bounds.
Expand Down
38 changes: 35 additions & 3 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,40 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let cx = ecx.cx();
// FIXME(generic_associated_types): Addresses aggressive inference in #92917.
//
// If this type is a GAT with currently unconstrained arguments, we do not
// want to normalize it via a candidate which only applies for a specific
// instantiation. We could otherwise keep the GAT as rigid and succeed this way.
// See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs.
//
// This only avoids normalization if the GAT arguments are fully unconstrained.
// This is quite arbitrary but fixing it causes some ambiguity, see #125196.
match goal.predicate.alias.kind(cx) {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
for arg in goal.predicate.alias.own_args(cx).iter() {
let Some(term) = arg.as_term() else {
continue;
};
let term = ecx.structurally_normalize_term(goal.param_env, term)?;
if term.is_infer() {
return ecx.evaluate_added_goals_and_make_canonical_response(
Certainty::AMBIGUOUS,
);
}
}
}
ty::AliasTermKind::OpaqueTy
| ty::AliasTermKind::InherentTy
| ty::AliasTermKind::InherentConst
| ty::AliasTermKind::FreeTy
| ty::AliasTermKind::FreeConst
| ty::AliasTermKind::UnevaluatedConst => {}
}

let projection_pred = assumption.as_projection_clause().unwrap();

let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
Expand All @@ -139,15 +172,14 @@ where

// Add GAT where clauses from the trait's definition
// FIXME: We don't need these, since these are the type's own WF obligations.
let cx = ecx.cx();
ecx.add_goals(
GoalSource::AliasWellFormed,
cx.own_predicates_of(goal.predicate.def_id())
.iter_instantiated(cx, goal.predicate.alias.args)
.map(|pred| goal.with(cx, pred)),
);

Ok(())
then(ecx)
}

fn consider_additional_alias_assumptions(
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
NoSolution, ParamEnvSource,
NoSolution, ParamEnvSource, QueryResult,
};

impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
Expand Down Expand Up @@ -150,13 +150,14 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let trait_clause = assumption.as_trait_clause().unwrap();

let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;

Ok(())
then(ecx)
}

fn consider_auto_trait_candidate(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,6 @@ parse_switch_ref_box_order = switch the order of `ref` and `box`
.suggestion = swap them

parse_ternary_operator = Rust has no ternary operator
.help = use an `if-else` expression instead

parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
.suggestion = use `!` to perform bitwise not
Expand Down Expand Up @@ -963,6 +962,8 @@ parse_use_empty_block_not_semi = expected { "`{}`" }, found `;`
parse_use_eq_instead = unexpected `==`
.suggestion = try using `=` instead

parse_use_if_else = use an `if-else` expression instead

parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable

Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,28 @@ pub(crate) enum IfExpressionMissingThenBlockSub {

#[derive(Diagnostic)]
#[diag(parse_ternary_operator)]
#[help]
pub(crate) struct TernaryOperator {
#[primary_span]
pub span: Span,
/// If we have a span for the condition expression, suggest the if/else
#[subdiagnostic]
pub sugg: Option<TernaryOperatorSuggestion>,
/// Otherwise, just print the suggestion message
#[help(parse_use_if_else)]
pub no_sugg: bool,
}

#[derive(Subdiagnostic, Copy, Clone)]
#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")]
pub(crate) struct TernaryOperatorSuggestion {
#[suggestion_part(code = "if ")]
pub before_cond: Span,
#[suggestion_part(code = "{{")]
pub question: Span,
#[suggestion_part(code = "}} else {{")]
pub colon: Span,
#[suggestion_part(code = " }}")]
pub end: Span,
}

#[derive(Subdiagnostic)]
Expand Down
Loading
Loading