Skip to content

Commit

Permalink
Auto merge of rust-lang#108339 - GuillaumeGomez:rollup-4z02kas, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 8 pull requests

Successful merges:

 - rust-lang#108110 (Move some `InferCtxt` methods to `EvalCtxt` in new solver)
 - rust-lang#108168 (Fix ICE on type alias in recursion)
 - rust-lang#108230 (Convert a hard-warning about named static lifetimes into lint "unused_lifetimes")
 - rust-lang#108239 (Fix overlapping spans in removing extra arguments)
 - rust-lang#108246 (Add an InstCombine for redundant casts)
 - rust-lang#108264 (no-fail-fast support for tool testsuites)
 - rust-lang#108310 (rustdoc: Fix duplicated attributes for first reexport)
 - rust-lang#108318 (Remove unused FileDesc::get_cloexec)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 22, 2023
2 parents bd4a96a + 0d0de49 commit 3b4d6e0
Show file tree
Hide file tree
Showing 47 changed files with 562 additions and 400 deletions.
46 changes: 24 additions & 22 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
Expand Down Expand Up @@ -923,17 +924,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
origin,
..
}) => {

let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
bound_generic_params
.iter()
.enumerate()
.map(|(late_bound_idx, param)| {
let pair = ResolvedArg::late(late_bound_idx as u32, param);
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
(pair, r)
})
.unzip();
.iter()
.enumerate()
.map(|(late_bound_idx, param)| {
let pair = ResolvedArg::late(late_bound_idx as u32, param);
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
(pair, r)
})
.unzip();
this.record_late_bound_vars(hir_id, binders.clone());
// Even if there are no lifetimes defined here, we still wrap it in a binder
// scope. If there happens to be a nested poly trait ref (an error), that
Expand Down Expand Up @@ -968,20 +968,22 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
continue;
}
this.insert_lifetime(lt, ResolvedArg::StaticLifetime);
this.tcx
.sess
.struct_span_warn(
lifetime.ident.span,
&format!(
"unnecessary lifetime parameter `{}`",
this.tcx.struct_span_lint_hir(
lint::builtin::UNUSED_LIFETIMES,
lifetime.hir_id,
lifetime.ident.span,
format!(
"unnecessary lifetime parameter `{}`",
lifetime.ident
),
|lint| {
let help = &format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
),
)
.help(&format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
))
.emit();
);
lint.help(help)
},
);
}
}
}
Expand Down
23 changes: 10 additions & 13 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,25 +932,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
labels
.push((provided_span, format!("unexpected argument{}", provided_ty_name)));
let mut span = provided_span;
if arg_idx.index() > 0
if span.can_be_used_for_suggestions() {
if arg_idx.index() > 0
&& let Some((_, prev)) = provided_arg_tys
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
) {
// Include previous comma
span = span.with_lo(prev.hi());
} else if let Some((_, next)) = provided_arg_tys.get(
ProvidedIdx::from_usize(arg_idx.index() + 1),
) {
// Include next comma
span = span.until(*next);
span = prev.shrink_to_hi().to(span);
}
suggestions.push((span, String::new()));
suggestions.push((span, String::new()));

suggestion_text = match suggestion_text {
SuggestionText::None => SuggestionText::Remove(false),
SuggestionText::Remove(_) => SuggestionText::Remove(true),
_ => SuggestionText::DidYouMean,
};
suggestion_text = match suggestion_text {
SuggestionText::None => SuggestionText::Remove(false),
SuggestionText::Remove(_) => SuggestionText::Remove(true),
_ => SuggestionText::DidYouMean,
};
}
}
Error::Missing(expected_idx) => {
// If there are multiple missing arguments adjacent to each other,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::dep_graph::DepKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::Representability;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
use rustc_query_system::query::QueryInfo;
Expand Down Expand Up @@ -199,7 +199,8 @@ fn find_item_ty_spans(
) {
match ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
if let Some(def_id) = path.res.opt_def_id() {
if let Res::Def(kind, def_id) = path.res
&& kind != DefKind::TyAlias {
let check_params = def_id.as_local().map_or(true, |def_id| {
if def_id == needle {
spans.push(ty.span);
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_mir_transform/src/instcombine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
ctx.combine_bool_cmp(&statement.source_info, rvalue);
ctx.combine_ref_deref(&statement.source_info, rvalue);
ctx.combine_len(&statement.source_info, rvalue);
ctx.combine_cast(&statement.source_info, rvalue);
}
_ => {}
}
Expand Down Expand Up @@ -142,6 +143,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
}
}

fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
if let Rvalue::Cast(_kind, operand, ty) = rvalue {
if operand.ty(self.local_decls, self.tcx) == *ty {
*rvalue = Rvalue::Use(operand.clone());
}
}
}

fn combine_primitive_clone(
&self,
terminator: &mut Terminator<'tcx>,
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_trait_selection/src/solve/assembly.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Code shared by trait and projection goals for candidate assembly.

use super::infcx_ext::InferCtxtExt;
#[cfg(doc)]
use super::trait_goals::structural_traits::*;
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
Expand Down Expand Up @@ -206,7 +205,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
&mut self,
goal: Goal<'tcx, G>,
) -> Vec<Candidate<'tcx>> {
debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal));
debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));

// HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
// object bound, alias bound, etc. We are unable to determine this until we can at
Expand Down Expand Up @@ -250,25 +249,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let &ty::Alias(ty::Projection, projection_ty) = goal.predicate.self_ty().kind() else {
return
};
self.infcx.probe(|_| {
let normalized_ty = self.infcx.next_ty_infer();
self.probe(|this| {
let normalized_ty = this.next_ty_infer();
let normalizes_to_goal = goal.with(
tcx,
ty::Binder::dummy(ty::ProjectionPredicate {
projection_ty,
term: normalized_ty.into(),
}),
);
let normalization_certainty = match self.evaluate_goal(normalizes_to_goal) {
let normalization_certainty = match this.evaluate_goal(normalizes_to_goal) {
Ok((_, certainty)) => certainty,
Err(NoSolution) => return,
};
let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty);
let normalized_ty = this.resolve_vars_if_possible(normalized_ty);

// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
// This doesn't work as long as we use `CandidateSource` in winnowing.
let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
let normalized_candidates = this.assemble_and_evaluate_candidates(goal);
for mut normalized_candidate in normalized_candidates {
normalized_candidate.result =
normalized_candidate.result.unchecked_map(|mut response| {
Expand Down
172 changes: 172 additions & 0 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use rustc_hir::def_id::DefId;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::infer::canonical::CanonicalVarValues;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable};
use rustc_span::DUMMY_SP;
use std::ops::ControlFlow;

use super::search_graph::SearchGraph;
use super::Goal;

pub struct EvalCtxt<'a, 'tcx> {
// FIXME: should be private.
pub(super) infcx: &'a InferCtxt<'tcx>,

pub(super) var_values: CanonicalVarValues<'tcx>,

pub(super) search_graph: &'a mut SearchGraph<'tcx>,

/// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
/// see the comment in that method for more details.
pub in_projection_eq_hack: bool,
}

impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T {
self.infcx.probe(|_| f(self))
}

pub(super) fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}

pub(super) fn next_ty_infer(&self) -> Ty<'tcx> {
self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span: DUMMY_SP,
})
}

pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.infcx.next_const_var(
ty,
ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
)
}

/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
///
/// This is the case if the `term` is an inference variable in the innermost universe
/// and does not occur in any other part of the predicate.
pub(super) fn term_is_fully_unconstrained(
&self,
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
) -> bool {
let term_is_infer = match goal.predicate.term.unpack() {
ty::TermKind::Ty(ty) => {
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
match self.infcx.probe_ty_var(vid) {
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
Err(universe) => universe == self.universe(),
}
} else {
false
}
}
ty::TermKind::Const(ct) => {
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
match self.infcx.probe_const_var(vid) {
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
Err(universe) => universe == self.universe(),
}
} else {
false
}
}
};

// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
struct ContainsTerm<'tcx> {
term: ty::Term<'tcx>,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if t.needs_infer() {
if ty::Term::from(t) == self.term {
ControlFlow::Break(())
} else {
t.super_visit_with(self)
}
} else {
ControlFlow::Continue(())
}
}

fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if c.needs_infer() {
if ty::Term::from(c) == self.term {
ControlFlow::Break(())
} else {
c.super_visit_with(self)
}
} else {
ControlFlow::Continue(())
}
}
}

let mut visitor = ContainsTerm { term: goal.predicate.term };

term_is_infer
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
&& goal.param_env.visit_with(&mut visitor).is_continue()
}

#[instrument(level = "debug", skip(self, param_env), ret)]
pub(super) fn eq<T: ToTrace<'tcx>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.infcx
.at(&ObligationCause::dummy(), param_env)
.eq(lhs, rhs)
.map(|InferOk { value: (), obligations }| {
obligations.into_iter().map(|o| o.into()).collect()
})
.map_err(|e| {
debug!(?e, "failed to equate");
NoSolution
})
}

pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>(
&self,
value: ty::Binder<'tcx, T>,
) -> T {
self.infcx.instantiate_binder_with_fresh_vars(
DUMMY_SP,
LateBoundRegionConversionTime::HigherRankedType,
value,
)
}

pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<'tcx> + Copy>(
&self,
value: ty::Binder<'tcx, T>,
) -> T {
self.infcx.instantiate_binder_with_placeholders(value)
}

pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
where
T: TypeFoldable<'tcx>,
{
self.infcx.resolve_vars_if_possible(value)
}

pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> {
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
}

pub(super) fn universe(&self) -> ty::UniverseIndex {
self.infcx.universe()
}
}
Loading

0 comments on commit 3b4d6e0

Please sign in to comment.