Skip to content

Commit 3b4d6e0

Browse files
committed
Auto merge of #108339 - GuillaumeGomez:rollup-4z02kas, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #108110 (Move some `InferCtxt` methods to `EvalCtxt` in new solver) - #108168 (Fix ICE on type alias in recursion) - #108230 (Convert a hard-warning about named static lifetimes into lint "unused_lifetimes") - #108239 (Fix overlapping spans in removing extra arguments) - #108246 (Add an InstCombine for redundant casts) - #108264 (no-fail-fast support for tool testsuites) - #108310 (rustdoc: Fix duplicated attributes for first reexport) - #108318 (Remove unused FileDesc::get_cloexec) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents bd4a96a + 0d0de49 commit 3b4d6e0

Some content is hidden

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

47 files changed

+562
-400
lines changed

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_middle::bug;
1818
use rustc_middle::hir::nested_filter;
1919
use rustc_middle::middle::resolve_bound_vars::*;
2020
use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable};
21+
use rustc_session::lint;
2122
use rustc_span::def_id::DefId;
2223
use rustc_span::symbol::{sym, Ident};
2324
use rustc_span::Span;
@@ -923,17 +924,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
923924
origin,
924925
..
925926
}) => {
926-
927927
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
928928
bound_generic_params
929-
.iter()
930-
.enumerate()
931-
.map(|(late_bound_idx, param)| {
932-
let pair = ResolvedArg::late(late_bound_idx as u32, param);
933-
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
934-
(pair, r)
935-
})
936-
.unzip();
929+
.iter()
930+
.enumerate()
931+
.map(|(late_bound_idx, param)| {
932+
let pair = ResolvedArg::late(late_bound_idx as u32, param);
933+
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
934+
(pair, r)
935+
})
936+
.unzip();
937937
this.record_late_bound_vars(hir_id, binders.clone());
938938
// Even if there are no lifetimes defined here, we still wrap it in a binder
939939
// scope. If there happens to be a nested poly trait ref (an error), that
@@ -968,20 +968,22 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
968968
continue;
969969
}
970970
this.insert_lifetime(lt, ResolvedArg::StaticLifetime);
971-
this.tcx
972-
.sess
973-
.struct_span_warn(
974-
lifetime.ident.span,
975-
&format!(
976-
"unnecessary lifetime parameter `{}`",
971+
this.tcx.struct_span_lint_hir(
972+
lint::builtin::UNUSED_LIFETIMES,
973+
lifetime.hir_id,
974+
lifetime.ident.span,
975+
format!(
976+
"unnecessary lifetime parameter `{}`",
977+
lifetime.ident
978+
),
979+
|lint| {
980+
let help = &format!(
981+
"you can use the `'static` lifetime directly, in place of `{}`",
977982
lifetime.ident,
978-
),
979-
)
980-
.help(&format!(
981-
"you can use the `'static` lifetime directly, in place of `{}`",
982-
lifetime.ident,
983-
))
984-
.emit();
983+
);
984+
lint.help(help)
985+
},
986+
);
985987
}
986988
}
987989
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -932,25 +932,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
932932
labels
933933
.push((provided_span, format!("unexpected argument{}", provided_ty_name)));
934934
let mut span = provided_span;
935-
if arg_idx.index() > 0
935+
if span.can_be_used_for_suggestions() {
936+
if arg_idx.index() > 0
936937
&& let Some((_, prev)) = provided_arg_tys
937938
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
938939
) {
939940
// Include previous comma
940-
span = span.with_lo(prev.hi());
941-
} else if let Some((_, next)) = provided_arg_tys.get(
942-
ProvidedIdx::from_usize(arg_idx.index() + 1),
943-
) {
944-
// Include next comma
945-
span = span.until(*next);
941+
span = prev.shrink_to_hi().to(span);
946942
}
947-
suggestions.push((span, String::new()));
943+
suggestions.push((span, String::new()));
948944

949-
suggestion_text = match suggestion_text {
950-
SuggestionText::None => SuggestionText::Remove(false),
951-
SuggestionText::Remove(_) => SuggestionText::Remove(true),
952-
_ => SuggestionText::DidYouMean,
953-
};
945+
suggestion_text = match suggestion_text {
946+
SuggestionText::None => SuggestionText::Remove(false),
947+
SuggestionText::Remove(_) => SuggestionText::Remove(true),
948+
_ => SuggestionText::DidYouMean,
949+
};
950+
}
954951
}
955952
Error::Missing(expected_idx) => {
956953
// If there are multiple missing arguments adjacent to each other,

compiler/rustc_middle/src/values.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::dep_graph::DepKind;
22
use rustc_data_structures::fx::FxHashSet;
33
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
44
use rustc_hir as hir;
5-
use rustc_hir::def::DefKind;
5+
use rustc_hir::def::{DefKind, Res};
66
use rustc_middle::ty::Representability;
77
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
88
use rustc_query_system::query::QueryInfo;
@@ -199,7 +199,8 @@ fn find_item_ty_spans(
199199
) {
200200
match ty.kind {
201201
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
202-
if let Some(def_id) = path.res.opt_def_id() {
202+
if let Res::Def(kind, def_id) = path.res
203+
&& kind != DefKind::TyAlias {
203204
let check_params = def_id.as_local().map_or(true, |def_id| {
204205
if def_id == needle {
205206
spans.push(ty.span);

compiler/rustc_mir_transform/src/instcombine.rs

+9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
3030
ctx.combine_bool_cmp(&statement.source_info, rvalue);
3131
ctx.combine_ref_deref(&statement.source_info, rvalue);
3232
ctx.combine_len(&statement.source_info, rvalue);
33+
ctx.combine_cast(&statement.source_info, rvalue);
3334
}
3435
_ => {}
3536
}
@@ -142,6 +143,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
142143
}
143144
}
144145

146+
fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
147+
if let Rvalue::Cast(_kind, operand, ty) = rvalue {
148+
if operand.ty(self.local_decls, self.tcx) == *ty {
149+
*rvalue = Rvalue::Use(operand.clone());
150+
}
151+
}
152+
}
153+
145154
fn combine_primitive_clone(
146155
&self,
147156
terminator: &mut Terminator<'tcx>,

compiler/rustc_trait_selection/src/solve/assembly.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
3-
use super::infcx_ext::InferCtxtExt;
43
#[cfg(doc)]
54
use super::trait_goals::structural_traits::*;
65
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
@@ -206,7 +205,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
206205
&mut self,
207206
goal: Goal<'tcx, G>,
208207
) -> Vec<Candidate<'tcx>> {
209-
debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal));
208+
debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
210209

211210
// HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
212211
// object bound, alias bound, etc. We are unable to determine this until we can at
@@ -250,25 +249,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
250249
let &ty::Alias(ty::Projection, projection_ty) = goal.predicate.self_ty().kind() else {
251250
return
252251
};
253-
self.infcx.probe(|_| {
254-
let normalized_ty = self.infcx.next_ty_infer();
252+
self.probe(|this| {
253+
let normalized_ty = this.next_ty_infer();
255254
let normalizes_to_goal = goal.with(
256255
tcx,
257256
ty::Binder::dummy(ty::ProjectionPredicate {
258257
projection_ty,
259258
term: normalized_ty.into(),
260259
}),
261260
);
262-
let normalization_certainty = match self.evaluate_goal(normalizes_to_goal) {
261+
let normalization_certainty = match this.evaluate_goal(normalizes_to_goal) {
263262
Ok((_, certainty)) => certainty,
264263
Err(NoSolution) => return,
265264
};
266-
let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty);
265+
let normalized_ty = this.resolve_vars_if_possible(normalized_ty);
267266

268267
// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
269268
// This doesn't work as long as we use `CandidateSource` in winnowing.
270269
let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
271-
let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
270+
let normalized_candidates = this.assemble_and_evaluate_candidates(goal);
272271
for mut normalized_candidate in normalized_candidates {
273272
normalized_candidate.result =
274273
normalized_candidate.result.unchecked_map(|mut response| {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
use rustc_hir::def_id::DefId;
2+
use rustc_infer::infer::at::ToTrace;
3+
use rustc_infer::infer::canonical::CanonicalVarValues;
4+
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
5+
use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
6+
use rustc_infer::traits::query::NoSolution;
7+
use rustc_infer::traits::ObligationCause;
8+
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
9+
use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable};
10+
use rustc_span::DUMMY_SP;
11+
use std::ops::ControlFlow;
12+
13+
use super::search_graph::SearchGraph;
14+
use super::Goal;
15+
16+
pub struct EvalCtxt<'a, 'tcx> {
17+
// FIXME: should be private.
18+
pub(super) infcx: &'a InferCtxt<'tcx>,
19+
20+
pub(super) var_values: CanonicalVarValues<'tcx>,
21+
22+
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
23+
24+
/// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
25+
/// see the comment in that method for more details.
26+
pub in_projection_eq_hack: bool,
27+
}
28+
29+
impl<'tcx> EvalCtxt<'_, 'tcx> {
30+
pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T {
31+
self.infcx.probe(|_| f(self))
32+
}
33+
34+
pub(super) fn tcx(&self) -> TyCtxt<'tcx> {
35+
self.infcx.tcx
36+
}
37+
38+
pub(super) fn next_ty_infer(&self) -> Ty<'tcx> {
39+
self.infcx.next_ty_var(TypeVariableOrigin {
40+
kind: TypeVariableOriginKind::MiscVariable,
41+
span: DUMMY_SP,
42+
})
43+
}
44+
45+
pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
46+
self.infcx.next_const_var(
47+
ty,
48+
ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
49+
)
50+
}
51+
52+
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
53+
///
54+
/// This is the case if the `term` is an inference variable in the innermost universe
55+
/// and does not occur in any other part of the predicate.
56+
pub(super) fn term_is_fully_unconstrained(
57+
&self,
58+
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
59+
) -> bool {
60+
let term_is_infer = match goal.predicate.term.unpack() {
61+
ty::TermKind::Ty(ty) => {
62+
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
63+
match self.infcx.probe_ty_var(vid) {
64+
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
65+
Err(universe) => universe == self.universe(),
66+
}
67+
} else {
68+
false
69+
}
70+
}
71+
ty::TermKind::Const(ct) => {
72+
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
73+
match self.infcx.probe_const_var(vid) {
74+
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
75+
Err(universe) => universe == self.universe(),
76+
}
77+
} else {
78+
false
79+
}
80+
}
81+
};
82+
83+
// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
84+
struct ContainsTerm<'tcx> {
85+
term: ty::Term<'tcx>,
86+
}
87+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
88+
type BreakTy = ();
89+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
90+
if t.needs_infer() {
91+
if ty::Term::from(t) == self.term {
92+
ControlFlow::Break(())
93+
} else {
94+
t.super_visit_with(self)
95+
}
96+
} else {
97+
ControlFlow::Continue(())
98+
}
99+
}
100+
101+
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
102+
if c.needs_infer() {
103+
if ty::Term::from(c) == self.term {
104+
ControlFlow::Break(())
105+
} else {
106+
c.super_visit_with(self)
107+
}
108+
} else {
109+
ControlFlow::Continue(())
110+
}
111+
}
112+
}
113+
114+
let mut visitor = ContainsTerm { term: goal.predicate.term };
115+
116+
term_is_infer
117+
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
118+
&& goal.param_env.visit_with(&mut visitor).is_continue()
119+
}
120+
121+
#[instrument(level = "debug", skip(self, param_env), ret)]
122+
pub(super) fn eq<T: ToTrace<'tcx>>(
123+
&self,
124+
param_env: ty::ParamEnv<'tcx>,
125+
lhs: T,
126+
rhs: T,
127+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
128+
self.infcx
129+
.at(&ObligationCause::dummy(), param_env)
130+
.eq(lhs, rhs)
131+
.map(|InferOk { value: (), obligations }| {
132+
obligations.into_iter().map(|o| o.into()).collect()
133+
})
134+
.map_err(|e| {
135+
debug!(?e, "failed to equate");
136+
NoSolution
137+
})
138+
}
139+
140+
pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>(
141+
&self,
142+
value: ty::Binder<'tcx, T>,
143+
) -> T {
144+
self.infcx.instantiate_binder_with_fresh_vars(
145+
DUMMY_SP,
146+
LateBoundRegionConversionTime::HigherRankedType,
147+
value,
148+
)
149+
}
150+
151+
pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<'tcx> + Copy>(
152+
&self,
153+
value: ty::Binder<'tcx, T>,
154+
) -> T {
155+
self.infcx.instantiate_binder_with_placeholders(value)
156+
}
157+
158+
pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
159+
where
160+
T: TypeFoldable<'tcx>,
161+
{
162+
self.infcx.resolve_vars_if_possible(value)
163+
}
164+
165+
pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> {
166+
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
167+
}
168+
169+
pub(super) fn universe(&self) -> ty::UniverseIndex {
170+
self.infcx.universe()
171+
}
172+
}

0 commit comments

Comments
 (0)