Skip to content

Commit

Permalink
Auto merge of #103426 - matthiaskrgr:rollup-n6dqdy8, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #103123 (Introduce `subst_iter` and `subst_iter_copied` on `EarlyBinder` )
 - #103328 (Do not suggest trivially false const predicates)
 - #103354 (Escape string literals when fixing overlong char literal)
 - #103355 (Handle return-position `impl Trait` in traits properly in `register_hidden_type`)
 - #103368 (Delay ambiguity span bug in normalize query iff not rustdoc)
 - #103388 (rustdoc: remove unused CSS class `.result-description`)
 - #103399 (Change `unknown_lint` applicability to `MaybeIncorrect`)
 - #103401 (Use functions for headings rustdoc GUI test)
 - #103412 (Fix typo in docs of `String::leak`.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 23, 2022
2 parents 6c9c2d8 + 25e02d6 commit faab68e
Show file tree
Hide file tree
Showing 45 changed files with 471 additions and 252 deletions.
16 changes: 4 additions & 12 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,10 +664,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
});
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
// Recurse into bounds
for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
let pred_span = pred.0.1;

let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx(), proj.substs);
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) {
let pred = pred.fold_with(self);
let pred = self.ocx.normalize(
ObligationCause::misc(self.span, self.body_id),
Expand Down Expand Up @@ -1752,15 +1749,10 @@ pub fn check_type_bounds<'tcx>(

let obligations = tcx
.bound_explicit_item_bounds(trait_ty.def_id)
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.map(|(bound, span)| {
debug!(?bound);
// this is where opaque type is found
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
.subst_iter_copied(tcx, rebased_substs)
.map(|(concrete_ty_bound, span)| {
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);

traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound)
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
})
.collect();
debug!("check_type_bounds: item_bounds={:?}", obligations);
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

for ty in [first_ty, second_ty] {
for pred in self.tcx.bound_explicit_item_bounds(rpit_def_id).transpose_iter() {
let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx, substs);
for (pred, _) in self
.tcx
.bound_explicit_item_bounds(rpit_def_id)
.subst_iter_copied(self.tcx, substs)
{
let pred = match pred.kind().skip_binder() {
ty::PredicateKind::Trait(mut trait_pred) => {
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
Expand Down
31 changes: 14 additions & 17 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,24 +176,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match *expected_ty.kind() {
ty::Opaque(def_id, substs) => {
let bounds = self.tcx.bound_explicit_item_bounds(def_id);
let sig = bounds
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(pred, span)| match pred.0.kind().skip_binder() {
let sig =
bounds.subst_iter_copied(self.tcx, substs).find_map(|(pred, span)| match pred
.kind()
.skip_binder()
{
ty::PredicateKind::Projection(proj_predicate) => self
.deduce_sig_from_projection(
Some(span.0),
pred.0
.kind()
.rebind(pred.rebind(proj_predicate).subst(self.tcx, substs)),
Some(span),
pred.kind().rebind(proj_predicate),
),
_ => None,
});

let kind = bounds
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.filter_map(|(pred, _)| match pred.0.kind().skip_binder() {
.0
.iter()
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::Trait(tp) => {
self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
}
Expand Down Expand Up @@ -697,18 +696,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Opaque(def_id, substs) => self
.tcx
.bound_explicit_item_bounds(def_id)
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
.subst_iter_copied(self.tcx, substs)
.find_map(|(p, s)| get_future_output(p, s))?,
ty::Error(_) => return None,
ty::Projection(proj)
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder =>
{
self.tcx
.bound_explicit_item_bounds(proj.item_def_id)
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, proj.substs), s.0))?
.subst_iter_copied(self.tcx, proj.substs)
.find_map(|(p, s)| get_future_output(p, s))?
}
_ => span_bug!(
self.tcx.def_span(expr_def_id),
Expand Down
26 changes: 22 additions & 4 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ impl<'tcx> InferCtxt<'tcx> {

let bounds = self.tcx.bound_explicit_item_bounds(*def_id);

for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
let predicate = predicate.subst(self.tcx, substs);
for (predicate, _) in bounds.subst_iter_copied(self.tcx, substs) {
let output = predicate
.kind()
.map_bound(|kind| match kind {
Expand Down Expand Up @@ -2272,6 +2271,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
}
FailureCode::Error0308(failure_str) => {
fn escape_literal(s: &str) -> String {
let mut escaped = String::with_capacity(s.len());
let mut chrs = s.chars().peekable();
while let Some(first) = chrs.next() {
match (first, chrs.peek()) {
('\\', Some(&delim @ '"') | Some(&delim @ '\'')) => {
escaped.push('\\');
escaped.push(delim);
chrs.next();
}
('"' | '\'', _) => {
escaped.push('\\');
escaped.push(first)
}
(c, _) => escaped.push(c),
};
}
escaped
}
let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
if let Some((expected, found)) = trace.values.ty() {
match (expected.kind(), found.kind()) {
Expand All @@ -2293,7 +2311,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.span_suggestion(
span,
"if you meant to write a `char` literal, use single quotes",
format!("'{}'", code),
format!("'{}'", escape_literal(code)),
Applicability::MachineApplicable,
);
}
Expand All @@ -2308,7 +2326,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.span_suggestion(
span,
"if you meant to write a `str` literal, use double quotes",
format!("\"{}\"", code),
format!("\"{}\"", escape_literal(code)),
Applicability::MachineApplicable,
);
}
Expand Down
19 changes: 14 additions & 5 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::errors::OpaqueHiddenTypeDiag;
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
use crate::traits;
use hir::def::DefKind;
use hir::def_id::{DefId, LocalDefId};
use hir::{HirId, OpaqueTyOrigin};
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -543,16 +544,18 @@ impl<'tcx> InferCtxt<'tcx> {

let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());

for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
debug!(?predicate);
let predicate = predicate.subst(tcx, substs);

for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match *ty.kind() {
// We can't normalize associated types from `rustc_infer`,
// but we can eagerly register inference variables for them.
ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => {
// FIXME(RPITIT): Don't replace RPITITs with inference vars.
ty::Projection(projection_ty)
if !projection_ty.has_escaping_bound_vars()
&& tcx.def_kind(projection_ty.item_def_id)
!= DefKind::ImplTraitPlaceholder =>
{
self.infer_projection(
param_env,
projection_ty,
Expand All @@ -568,6 +571,12 @@ impl<'tcx> InferCtxt<'tcx> {
{
hidden_ty
}
// FIXME(RPITIT): This can go away when we move to associated types
ty::Projection(proj)
if def_id.to_def_id() == proj.item_def_id && substs == proj.substs =>
{
hidden_ty
}
_ => ty,
},
lt_op: |lt| lt,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
sp,
"did you mean",
suggestion,
Applicability::MachineApplicable,
Applicability::MaybeIncorrect,
);
}
lint
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,12 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
// e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
// with `impl Send: OtherTrait`.
for assoc_pred_and_span in
cx.tcx.bound_explicit_item_bounds(proj.projection_ty.item_def_id).transpose_iter()
for (assoc_pred, assoc_pred_span) in cx
.tcx
.bound_explicit_item_bounds(proj.projection_ty.item_def_id)
.subst_iter_copied(cx.tcx, &proj.projection_ty.substs)
{
let assoc_pred_span = assoc_pred_and_span.0.1;
let assoc_pred = assoc_pred_and_span
.map_bound(|(pred, _)| *pred)
.subst(cx.tcx, &proj.projection_ty.substs)
.fold_with(proj_replacer);
let assoc_pred = assoc_pred.fold_with(proj_replacer);
let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else {
continue;
};
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,7 @@ pub trait PrettyPrinter<'tcx>:
let mut fn_traits = FxIndexMap::default();
let mut is_sized = false;

for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
let predicate = predicate.subst(tcx, substs);
for (predicate, _) in bounds.subst_iter_copied(tcx, substs) {
let bound_predicate = predicate.kind();

match bound_predicate.skip_binder() {
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_middle/src/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
use crate::ty::visit::{TypeVisitable, TypeVisitor};
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};

use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::{Interned, WithStableHash};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
Expand Down Expand Up @@ -558,6 +559,28 @@ impl<T, U> EarlyBinder<(T, U)> {
}
}

impl<'tcx, 's, T: IntoIterator<Item = I>, I: TypeFoldable<'tcx>> EarlyBinder<T> {
pub fn subst_iter(
self,
tcx: TyCtxt<'tcx>,
substs: &'s [GenericArg<'tcx>],
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> {
self.0.into_iter().map(move |t| EarlyBinder(t).subst(tcx, substs))
}
}

impl<'tcx, 's, 'a, T: IntoIterator<Item = &'a I>, I: Copy + TypeFoldable<'tcx> + 'a>
EarlyBinder<T>
{
pub fn subst_iter_copied(
self,
tcx: TyCtxt<'tcx>,
substs: &'s [GenericArg<'tcx>],
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> + Captures<'a> {
self.0.into_iter().map(move |t| EarlyBinder(*t).subst(tcx, substs))
}
}

pub struct EarlyBinderIter<T> {
t: T,
}
Expand Down
19 changes: 17 additions & 2 deletions compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,26 @@ pub(crate) fn emit_unescape_error(
} else {
("", "if you meant to write a `str` literal, use double quotes")
};

let mut escaped = String::with_capacity(lit.len());
let mut chrs = lit.chars().peekable();
while let Some(first) = chrs.next() {
match (first, chrs.peek()) {
('\\', Some('"')) => {
escaped.push('\\');
escaped.push('"');
chrs.next();
}
('"', _) => {
escaped.push('\\');
escaped.push('"')
}
(c, _) => escaped.push(c),
};
}
handler.span_suggestion(
span_with_quotes,
msg,
format!("{}\"{}\"", prefix, lit),
format!("{prefix}\"{escaped}\""),
Applicability::MachineApplicable,
);
}
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
}

let mut unsatisfied_const = false;
if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
let non_const_predicate = trait_ref.without_const();
let non_const_obligation = Obligation {
Expand All @@ -773,6 +774,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
recursion_depth: obligation.recursion_depth,
};
if self.predicate_may_hold(&non_const_obligation) {
unsatisfied_const = true;
err.span_note(
span,
&format!(
Expand Down Expand Up @@ -924,7 +926,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
} else if !trait_ref.has_non_region_infer()
&& self.predicate_can_apply(obligation.param_env, trait_ref)
&& self.predicate_can_apply(obligation.param_env, trait_predicate)
{
// If a where-clause may be useful, remind the
// user that they can add it.
Expand All @@ -939,7 +941,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
None,
obligation.cause.body_id,
);
} else if !suggested {
} else if !suggested && !unsatisfied_const {
// Can't show anything else useful, try to find similar impls.
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
if !self.report_similar_impl_candidates(
Expand Down Expand Up @@ -1436,7 +1438,7 @@ trait InferCtxtPrivExt<'tcx> {
fn predicate_can_apply(
&self,
param_env: ty::ParamEnv<'tcx>,
pred: ty::PolyTraitRef<'tcx>,
pred: ty::PolyTraitPredicate<'tcx>,
) -> bool;

fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>);
Expand Down Expand Up @@ -2511,7 +2513,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn predicate_can_apply(
&self,
param_env: ty::ParamEnv<'tcx>,
pred: ty::PolyTraitRef<'tcx>,
pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
struct ParamToVarFolder<'a, 'tcx> {
infcx: &'a InferCtxt<'tcx>,
Expand Down Expand Up @@ -2555,7 +2557,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
cleaned_pred.without_const().to_predicate(selcx.tcx()),
cleaned_pred.to_predicate(selcx.tcx()),
);

self.predicate_may_hold(&obligation)
Expand Down
Loading

0 comments on commit faab68e

Please sign in to comment.