Skip to content

Commit 985d931

Browse files
committed
Auto merge of rust-lang#141040 - matthiaskrgr:rollup-rym8mkn, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#139749 (docs(library/core/src/pin): fix typo "necessarily" -> "necessary") - 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#140947 (Flush errors before deep normalize in `dropck_outlives`) - rust-lang#140966 (Remove #![feature(let_chains)] from library and src/librustdoc) - rust-lang#140990 (VxWorks: updates from recent libc versions) - rust-lang#141027 (remove `RustfmtState` to reduce `initial_rustfmt` complexity) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c4e05e5 + da78e8d commit 985d931

File tree

34 files changed

+537
-151
lines changed

34 files changed

+537
-151
lines changed

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

+1-7
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

+4
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

+29-13
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

+28-1
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

+19-19
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

+3-2
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

+35-3
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

+4-3
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_pattern_analysis/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#![allow(rustc::diagnostic_outside_of_impl)]
77
#![allow(rustc::untranslatable_diagnostic)]
88
#![allow(unused_crate_dependencies)]
9-
#![cfg_attr(all(feature = "rustc", bootstrap), feature(let_chains))]
109
// tidy-alphabetical-end
1110

1211
pub mod constructor;

compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,31 @@ where
196196
debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
197197
ty
198198
} else {
199-
ocx.deeply_normalize(&cause, param_env, ty)?;
199+
// Flush errors b/c `deeply_normalize` doesn't expect pending
200+
// obligations, and we may have pending obligations from the
201+
// branch above (from other types).
202+
let errors = ocx.select_all_or_error();
203+
if !errors.is_empty() {
204+
return Err(errors);
205+
}
200206

201-
let errors = ocx.select_where_possible();
202-
debug!("normalize errors: {ty} ~> {errors:#?}");
203-
return Err(errors);
207+
// When query normalization fails, we don't get back an interesting
208+
// reason that we could use to report an error in borrowck. In order to turn
209+
// this into a reportable error, we deeply normalize again. We don't expect
210+
// this to succeed, so delay a bug if it does.
211+
match ocx.deeply_normalize(&cause, param_env, ty) {
212+
Ok(_) => {
213+
tcx.dcx().span_delayed_bug(
214+
span,
215+
format!(
216+
"query normalize succeeded of {ty}, \
217+
but deep normalize failed",
218+
),
219+
);
220+
ty
221+
}
222+
Err(errors) => return Err(errors),
223+
}
204224
};
205225

206226
match ty.kind() {

compiler/rustc_trait_selection/src/traits/select/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1760,12 +1760,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17601760

17611761
if is_match {
17621762
let generics = self.tcx().generics_of(obligation.predicate.def_id);
1763-
// FIXME(generic-associated-types): Addresses aggressive inference in #92917.
1763+
// FIXME(generic_associated_types): Addresses aggressive inference in #92917.
17641764
// If this type is a GAT, and of the GAT args resolve to something new,
17651765
// that means that we must have newly inferred something about the GAT.
17661766
// We should give up in that case.
1767-
// FIXME(generic-associated-types): This only detects one layer of inference,
1768-
// which is probably not what we actually want, but fixing it causes some ambiguity:
1767+
//
1768+
// This only detects one layer of inference, which is probably not what we actually
1769+
// want, but fixing it causes some ambiguity:
17691770
// <https://github.com/rust-lang/rust/issues/125196>.
17701771
if !generics.is_own_empty()
17711772
&& obligation.predicate.args[generics.parent_count..].iter().any(|&p| {

compiler/rustc_type_ir/src/inherent.rs

+8
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,14 @@ pub trait GenericArg<I: Interner<GenericArg = Self>>:
298298
+ From<I::Region>
299299
+ From<I::Const>
300300
{
301+
fn as_term(&self) -> Option<I::Term> {
302+
match self.kind() {
303+
ty::GenericArgKind::Lifetime(_) => None,
304+
ty::GenericArgKind::Type(ty) => Some(ty.into()),
305+
ty::GenericArgKind::Const(ct) => Some(ct.into()),
306+
}
307+
}
308+
301309
fn as_type(&self) -> Option<I::Ty> {
302310
if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None }
303311
}

0 commit comments

Comments
 (0)