Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 622f000

Browse filesBrowse files
committed
Auto merge of rust-lang#141041 - compiler-errors:rollup-tz4bpbf, r=compiler-errors
Rollup of 14 pull requests Successful merges: - rust-lang#139749 (docs(library/core/src/pin): fix typo "necessarily" -> "necessary") - rust-lang#140130 (Add LLDB providers for BTreeMap and BTreeSet) - rust-lang#140685 (Simplify `Vec::as_non_null` implementation and make it `const`) - rust-lang#140712 (normalization: avoid incompletely constraining GAT args) - rust-lang#140768 (Improve `dangerous_implicit_aurorefs` diagnostic output) - rust-lang#140834 (move (or remove) some impl Trait tests) - rust-lang#140910 (Remove `stable` attribute from wasi fs (read_exact|write_all)_at) - rust-lang#140947 (Flush errors before deep normalize in `dropck_outlives`) - rust-lang#140966 (Remove #![feature(let_chains)] from library and src/librustdoc) - rust-lang#140977 ([win] Use a dash instead of slash for linker to avoid breaking lld) - rust-lang#140990 (VxWorks: updates from recent libc versions) - rust-lang#141003 (Improve ternary operator recovery) - rust-lang#141013 (Implement methods to set STARTUPINFO flags for Command API on Windows) - rust-lang#141026 (rustc-dev-guide subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c4e05e5 + b9f2cfa commit 622f000
Copy full SHA for 622f000

File tree

Expand file treeCollapse file tree

128 files changed

+1069
-356
lines changed
Filter options

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

128 files changed

+1069
-356
lines changed

‎compiler/rustc_borrowck/src/type_check/liveness/trace.rs

Copy file name to clipboardExpand all lines: compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+1-7Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -621,13 +621,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
621621
&ocx, op, span,
622622
) {
623623
Ok(_) => ocx.select_all_or_error(),
624-
Err(e) => {
625-
if e.is_empty() {
626-
ocx.select_all_or_error()
627-
} else {
628-
e
629-
}
630-
}
624+
Err(e) => e,
631625
};
632626

633627
// Could have no errors if a type lowering error, say, caused the query

‎compiler/rustc_lint/messages.ftl

Copy file name to clipboardExpand all lines: compiler/rustc_lint/messages.ftl
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ lint_impl_trait_redundant_captures = all possible in-scope parameters are alread
362362
363363
lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
364364
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
365+
.raw_ptr = this raw pointer has type `{$raw_ptr_ty}`
366+
.autoref = autoref is being applied to this expression, resulting in: `{$autoref_ty}`
367+
.overloaded_deref = references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
368+
.method_def = method calls to `{$method_name}` require a reference
365369
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit
366370
367371
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe

‎compiler/rustc_lint/src/autorefs.rs

Copy file name to clipboardExpand all lines: compiler/rustc_lint/src/autorefs.rs
+29-13Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDer
44
use rustc_session::{declare_lint, declare_lint_pass};
55
use rustc_span::sym;
66

7-
use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
7+
use crate::lints::{
8+
ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin,
9+
ImplicitUnsafeAutorefsSuggestion,
10+
};
811
use crate::{LateContext, LateLintPass, LintContext};
912

1013
declare_lint! {
@@ -92,25 +95,37 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
9295
&& let adjustments = peel_derefs_adjustments(&**adjustments)
9396
// 3. An automatically inserted reference (might come from a deref).
9497
&& let [adjustment] = adjustments
95-
&& let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
98+
&& let Some((borrow_mutbl, through_overloaded_deref)) = has_implicit_borrow(adjustment)
9699
&& let ExprKind::Unary(UnOp::Deref, dereferenced) =
97100
// 2. Any number of place projections.
98101
peel_place_mappers(inner).kind
99102
// 1. Deref of a raw pointer.
100103
&& typeck.expr_ty(dereferenced).is_raw_ptr()
101-
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
102-
&& match expr.kind {
103-
ExprKind::MethodCall(..) => matches!(
104-
cx.typeck_results().type_dependent_def_id(expr.hir_id),
105-
Some(def_id) if cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs)
106-
),
107-
_ => true,
104+
&& let method_did = match expr.kind {
105+
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
106+
ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
107+
_ => None,
108108
}
109+
&& method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true)
109110
{
110111
cx.emit_span_lint(
111112
DANGEROUS_IMPLICIT_AUTOREFS,
112113
expr.span.source_callsite(),
113114
ImplicitUnsafeAutorefsDiag {
115+
raw_ptr_span: dereferenced.span,
116+
raw_ptr_ty: typeck.expr_ty(dereferenced),
117+
origin: if through_overloaded_deref {
118+
ImplicitUnsafeAutorefsOrigin::OverloadedDeref
119+
} else {
120+
ImplicitUnsafeAutorefsOrigin::Autoref {
121+
autoref_span: inner.span,
122+
autoref_ty: typeck.expr_ty_adjusted(inner),
123+
}
124+
},
125+
method: method_did.map(|did| ImplicitUnsafeAutorefsMethodNote {
126+
def_span: cx.tcx.def_span(did),
127+
method_name: cx.tcx.item_name(did),
128+
}),
114129
suggestion: ImplicitUnsafeAutorefsSuggestion {
115130
mutbl: borrow_mutbl.ref_prefix_str(),
116131
deref: if is_coming_from_deref { "*" } else { "" },
@@ -146,11 +161,12 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
146161

147162
/// Test if some adjustment has some implicit borrow.
148163
///
149-
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
150-
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
164+
/// Returns `Some((mutability, was_an_overloaded_deref))` if the argument adjustment is
165+
/// an implicit borrow (or has an implicit borrow via an overloaded deref).
166+
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Mutability, bool)> {
151167
match kind {
152-
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
153-
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
168+
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some((mutbl, true)),
169+
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some((mutbl.into(), false)),
154170
Adjust::NeverToAny
155171
| Adjust::Pointer(..)
156172
| Adjust::ReborrowPin(..)

‎compiler/rustc_lint/src/lints.rs

Copy file name to clipboardExpand all lines: compiler/rustc_lint/src/lints.rs
+28-1Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,38 @@ pub(crate) enum ShadowedIntoIterDiagSub {
5959
#[derive(LintDiagnostic)]
6060
#[diag(lint_implicit_unsafe_autorefs)]
6161
#[note]
62-
pub(crate) struct ImplicitUnsafeAutorefsDiag {
62+
pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> {
63+
#[label(lint_raw_ptr)]
64+
pub raw_ptr_span: Span,
65+
pub raw_ptr_ty: Ty<'a>,
66+
#[subdiagnostic]
67+
pub origin: ImplicitUnsafeAutorefsOrigin<'a>,
68+
#[subdiagnostic]
69+
pub method: Option<ImplicitUnsafeAutorefsMethodNote>,
6370
#[subdiagnostic]
6471
pub suggestion: ImplicitUnsafeAutorefsSuggestion,
6572
}
6673

74+
#[derive(Subdiagnostic)]
75+
pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> {
76+
#[note(lint_autoref)]
77+
Autoref {
78+
#[primary_span]
79+
autoref_span: Span,
80+
autoref_ty: Ty<'a>,
81+
},
82+
#[note(lint_overloaded_deref)]
83+
OverloadedDeref,
84+
}
85+
86+
#[derive(Subdiagnostic)]
87+
#[note(lint_method_def)]
88+
pub(crate) struct ImplicitUnsafeAutorefsMethodNote {
89+
#[primary_span]
90+
pub def_span: Span,
91+
pub method_name: Symbol,
92+
}
93+
6794
#[derive(Subdiagnostic)]
6895
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
6996
pub(crate) struct ImplicitUnsafeAutorefsSuggestion {

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

Copy file name to clipboardExpand all lines: compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+19-19Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
pub(super) mod structural_traits;
44

5+
use std::cell::Cell;
56
use std::ops::ControlFlow;
67

78
use derive_where::derive_where;
@@ -117,24 +118,24 @@ where
117118
) -> Result<Candidate<I>, NoSolution> {
118119
Self::fast_reject_assumption(ecx, goal, assumption)?;
119120

120-
ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
121-
Ok(candidate) => inspect::ProbeKind::TraitCandidate {
122-
source: candidate.source,
123-
result: Ok(candidate.result),
124-
},
125-
Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
126-
source: CandidateSource::ParamEnv(ParamEnvSource::Global),
127-
result: Err(NoSolution),
128-
},
121+
// Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily
122+
// check whether the candidate is global while considering normalization.
123+
//
124+
// We need to write into `source` inside of `match_assumption`, but need to access it
125+
// in `probe` even if the candidate does not apply before we get there. We handle this
126+
// by using a `Cell` here. We only ever write into it inside of `match_assumption`.
127+
let source = Cell::new(CandidateSource::ParamEnv(ParamEnvSource::Global));
128+
ecx.probe(|result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
129+
source: source.get(),
130+
result: *result,
129131
})
130132
.enter(|ecx| {
131-
Self::match_assumption(ecx, goal, assumption)?;
132-
let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
133-
Ok(Candidate {
134-
source,
135-
result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
133+
Self::match_assumption(ecx, goal, assumption, |ecx| {
134+
source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?);
135+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
136136
})
137137
})
138+
.map(|result| Candidate { source: source.get(), result })
138139
}
139140

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

153-
ecx.probe_trait_candidate(source).enter(|ecx| {
154-
Self::match_assumption(ecx, goal, assumption)?;
155-
then(ecx)
156-
})
154+
ecx.probe_trait_candidate(source)
155+
.enter(|ecx| Self::match_assumption(ecx, goal, assumption, then))
157156
}
158157

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

174174
fn consider_impl_candidate(
175175
ecx: &mut EvalCtxt<'_, D>,

‎compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Copy file name to clipboardExpand all lines: compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ where
6161
ecx: &mut EvalCtxt<'_, D>,
6262
goal: Goal<I, Self>,
6363
assumption: I::Clause,
64-
) -> Result<(), NoSolution> {
64+
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
65+
) -> QueryResult<I> {
6566
let host_clause = assumption.as_host_effect_clause().unwrap();
6667

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

70-
Ok(())
71+
then(ecx)
7172
}
7273

7374
/// Register additional assumptions for aliases corresponding to `~const` item bounds.

‎compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Copy file name to clipboardExpand all lines: compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+35-3Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,40 @@ where
129129
ecx: &mut EvalCtxt<'_, D>,
130130
goal: Goal<I, Self>,
131131
assumption: I::Clause,
132-
) -> Result<(), NoSolution> {
132+
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
133+
) -> QueryResult<I> {
134+
let cx = ecx.cx();
135+
// FIXME(generic_associated_types): Addresses aggressive inference in #92917.
136+
//
137+
// If this type is a GAT with currently unconstrained arguments, we do not
138+
// want to normalize it via a candidate which only applies for a specific
139+
// instantiation. We could otherwise keep the GAT as rigid and succeed this way.
140+
// See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs.
141+
//
142+
// This only avoids normalization if the GAT arguments are fully unconstrained.
143+
// This is quite arbitrary but fixing it causes some ambiguity, see #125196.
144+
match goal.predicate.alias.kind(cx) {
145+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
146+
for arg in goal.predicate.alias.own_args(cx).iter() {
147+
let Some(term) = arg.as_term() else {
148+
continue;
149+
};
150+
let term = ecx.structurally_normalize_term(goal.param_env, term)?;
151+
if term.is_infer() {
152+
return ecx.evaluate_added_goals_and_make_canonical_response(
153+
Certainty::AMBIGUOUS,
154+
);
155+
}
156+
}
157+
}
158+
ty::AliasTermKind::OpaqueTy
159+
| ty::AliasTermKind::InherentTy
160+
| ty::AliasTermKind::InherentConst
161+
| ty::AliasTermKind::FreeTy
162+
| ty::AliasTermKind::FreeConst
163+
| ty::AliasTermKind::UnevaluatedConst => {}
164+
}
165+
133166
let projection_pred = assumption.as_projection_clause().unwrap();
134167

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

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

150-
Ok(())
182+
then(ecx)
151183
}
152184

153185
fn consider_additional_alias_assumptions(

‎compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Copy file name to clipboardExpand all lines: compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
1717
use crate::solve::inspect::ProbeKind;
1818
use crate::solve::{
1919
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
20-
NoSolution, ParamEnvSource,
20+
NoSolution, ParamEnvSource, QueryResult,
2121
};
2222

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

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

159-
Ok(())
160+
then(ecx)
160161
}
161162

162163
fn consider_auto_trait_candidate(

‎compiler/rustc_parse/messages.ftl

Copy file name to clipboardExpand all lines: compiler/rustc_parse/messages.ftl
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,6 @@ parse_switch_ref_box_order = switch the order of `ref` and `box`
815815
.suggestion = swap them
816816
817817
parse_ternary_operator = Rust has no ternary operator
818-
.help = use an `if-else` expression instead
819818
820819
parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
821820
.suggestion = use `!` to perform bitwise not
@@ -963,6 +962,8 @@ parse_use_empty_block_not_semi = expected { "`{}`" }, found `;`
963962
parse_use_eq_instead = unexpected `==`
964963
.suggestion = try using `=` instead
965964
965+
parse_use_if_else = use an `if-else` expression instead
966+
966967
parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
967968
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable
968969

‎compiler/rustc_parse/src/errors.rs

Copy file name to clipboardExpand all lines: compiler/rustc_parse/src/errors.rs
+19-1Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,28 @@ pub(crate) enum IfExpressionMissingThenBlockSub {
436436

437437
#[derive(Diagnostic)]
438438
#[diag(parse_ternary_operator)]
439-
#[help]
440439
pub(crate) struct TernaryOperator {
441440
#[primary_span]
442441
pub span: Span,
442+
/// If we have a span for the condition expression, suggest the if/else
443+
#[subdiagnostic]
444+
pub sugg: Option<TernaryOperatorSuggestion>,
445+
/// Otherwise, just print the suggestion message
446+
#[help(parse_use_if_else)]
447+
pub no_sugg: bool,
448+
}
449+
450+
#[derive(Subdiagnostic, Copy, Clone)]
451+
#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")]
452+
pub(crate) struct TernaryOperatorSuggestion {
453+
#[suggestion_part(code = "if ")]
454+
pub before_cond: Span,
455+
#[suggestion_part(code = "{{")]
456+
pub question: Span,
457+
#[suggestion_part(code = "}} else {{")]
458+
pub colon: Span,
459+
#[suggestion_part(code = " }}")]
460+
pub end: Span,
443461
}
444462

445463
#[derive(Subdiagnostic)]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.