Skip to content
10 changes: 2 additions & 8 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
use rustc_trait_selection::infer::InferCtxtExt;
Expand Down Expand Up @@ -954,14 +955,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// wrapping in parentheses. We find the statement or expression
// following the `match` (`&& true`) and see if it is something that
// can reasonably be interpreted as a binop following an expression.
err.multipart_suggestion(
"parentheses are required to parse this as an expression",
vec![
(expr.span.shrink_to_lo(), "(".to_string()),
(expr.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MachineApplicable,
);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(expr.span));
} else if expr.can_have_side_effects() {
self.suggest_semicolon_at_end(expr.span, err);
}
Expand Down
18 changes: 2 additions & 16 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,14 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::StmtKind::Expr(_) = stmt.kind
&& self.is_next_stmt_expr_continuation(stmt.hir_id)
{
err.multipart_suggestion(
"parentheses are required to parse this as an expression",
vec![
(stmt.span.shrink_to_lo(), "(".to_string()),
(stmt.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MachineApplicable,
);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(stmt.span));
} else {
err.span_suggestion(
expression.span.shrink_to_hi(),
Expand Down Expand Up @@ -843,14 +836,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// wrapping in parentheses. We find the statement or expression following the
// `if` (`&& true`) and see if it is something that can reasonably be
// interpreted as a binop following an expression.
err.multipart_suggestion(
"parentheses are required to parse this as an expression",
vec![
(stmt.span.shrink_to_lo(), "(".to_string()),
(stmt.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MachineApplicable,
);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(stmt.span));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::ty::{
impl IntoDiagArg for Ty<'_> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let ty = tcx.short_string(self, path);
let ty = tcx.short_string(tcx.lift(self), path);
DiagArgValue::Str(std::borrow::Cow::Owned(ty))
})
}
Expand All @@ -31,7 +31,7 @@ impl IntoDiagArg for Ty<'_> {
impl IntoDiagArg for Instance<'_> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let instance = tcx.short_string_namespace(self, path, Namespace::ValueNS);
let instance = tcx.short_string_namespace(tcx.lift(self), path, Namespace::ValueNS);
DiagArgValue::Str(std::borrow::Cow::Owned(instance))
})
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_macros::extension;
pub use rustc_type_ir::error::ExpectedFound;

use crate::ty::print::{FmtPrinter, Print, with_forced_trimmed_paths};
use crate::ty::{self, Lift, Ty, TyCtxt};
use crate::ty::{self, Ty, TyCtxt};

pub type TypeError<'tcx> = rustc_type_ir::error::TypeError<TyCtxt<'tcx>>;

Expand Down Expand Up @@ -220,10 +220,10 @@ impl<'tcx> Ty<'tcx> {
impl<'tcx> TyCtxt<'tcx> {
pub fn string_with_limit<T>(self, t: T, length_limit: usize, ns: hir::def::Namespace) -> String
where
T: Copy + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>,
T: Copy + for<'a> Print<FmtPrinter<'a, 'tcx>>,
{
let mut type_limit = 50;
let regular = FmtPrinter::print_string(self, ns, |p| self.lift(t).print(p))
let regular = FmtPrinter::print_string(self, ns, |p| t.print(p))
.expect("could not write to `String`");
if regular.len() <= length_limit {
return regular;
Expand All @@ -233,7 +233,7 @@ impl<'tcx> TyCtxt<'tcx> {
// Look for the longest properly trimmed path that still fits in length_limit.
short = with_forced_trimmed_paths!({
let mut p = FmtPrinter::new_with_limit(self, ns, Limit(type_limit));
self.lift(t).print(&mut p).expect("could not print type");
t.print(&mut p).expect("could not print type");
p.into_buffer()
});
if short.len() <= length_limit || type_limit == 0 {
Expand All @@ -250,7 +250,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// where we wrote the file to is only printed once. The path will use the type namespace.
pub fn short_string<T>(self, t: T, path: &mut Option<PathBuf>) -> String
where
T: Copy + Hash + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>,
T: Copy + Hash + for<'a> Print<FmtPrinter<'a, 'tcx>>,
{
self.short_string_namespace(t, path, hir::def::Namespace::TypeNS)
}
Expand All @@ -266,9 +266,9 @@ impl<'tcx> TyCtxt<'tcx> {
namespace: hir::def::Namespace,
) -> String
where
T: Copy + Hash + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>,
T: Copy + Hash + for<'a> Print<FmtPrinter<'a, 'tcx>>,
{
let regular = FmtPrinter::print_string(self, namespace, |p| self.lift(t).print(p))
let regular = FmtPrinter::print_string(self, namespace, |p| t.print(p))
.expect("could not write to `String`");

if !self.sess.opts.unstable_opts.write_long_types_to_disk || self.sess.opts.verbose {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl<'tcx> Predicate<'tcx> {
impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let pred = tcx.short_string(self, path);
let pred = tcx.short_string(tcx.lift(self), path);
rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred))
})
}
Expand All @@ -122,7 +122,7 @@ impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> {
impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let clause = tcx.short_string(self, path);
let clause = tcx.short_string(tcx.lift(self), path);
rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause))
})
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use super::Lift;

pub type PrintError = std::fmt::Error;

pub trait Print<'tcx, P> {
pub trait Print<P> {
fn print(&self, p: &mut P) -> Result<(), PrintError>;
}

Expand Down Expand Up @@ -350,19 +350,19 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
characteristic_def_id_of_type_cached(ty, &mut SsoHashSet::new())
}

impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> {
impl<'tcx, P: Printer<'tcx>> Print<P> for ty::Region<'tcx> {
fn print(&self, p: &mut P) -> Result<(), PrintError> {
p.print_region(*self)
}
}

impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
impl<'tcx, P: Printer<'tcx>> Print<P> for Ty<'tcx> {
fn print(&self, p: &mut P) -> Result<(), PrintError> {
p.print_type(*self)
}
}

impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print<'tcx, P> for ty::Instance<'tcx> {
impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print<P> for ty::Instance<'tcx> {
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
cx.print_def_path(self.def_id(), self.args)?;
match self.def {
Expand Down Expand Up @@ -399,21 +399,21 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print<'tcx, P> for ty::Instance<'
}
}

impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
impl<'tcx, P: Printer<'tcx>> Print<P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
fn print(&self, p: &mut P) -> Result<(), PrintError> {
p.print_dyn_existential(self)
}
}

impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
impl<'tcx, P: Printer<'tcx>> Print<P> for ty::Const<'tcx> {
fn print(&self, p: &mut P) -> Result<(), PrintError> {
p.print_const(*self)
}
}

impl<T> rustc_type_ir::ir_print::IrPrint<T> for TyCtxt<'_>
where
T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>>,
T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<FmtPrinter<'a, 'tcx>>>,
{
fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ty::tls::with(|tcx| {
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {

fn pretty_print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
where
T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
T: Print<Self> + TypeFoldable<TyCtxt<'tcx>>,
{
value.as_ref().skip_binder().print(self)
}
Expand All @@ -285,7 +285,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
/// Prints comma-separated elements.
fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
where
T: Print<'tcx, Self>,
T: Print<Self>,
{
if let Some(first) = elems.next() {
first.print(self)?;
Expand Down Expand Up @@ -2484,7 +2484,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {

fn pretty_print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
where
T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
T: Print<Self> + TypeFoldable<TyCtxt<'tcx>>,
{
self.wrap_binder(value, WrapBinderMode::ForAll, |new_value, this| new_value.print(this))
}
Expand Down Expand Up @@ -2940,18 +2940,18 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
}
}

impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<P> for ty::Binder<'tcx, T>
where
T: Print<'tcx, P> + TypeFoldable<TyCtxt<'tcx>>,
T: Print<P> + TypeFoldable<TyCtxt<'tcx>>,
{
fn print(&self, p: &mut P) -> Result<(), PrintError> {
p.pretty_print_in_binder(self)
}
}

impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<'tcx, T>
impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<P> for ty::OutlivesPredicate<'tcx, T>
where
T: Print<'tcx, P>,
T: Print<P>,
{
fn print(&self, p: &mut P) -> Result<(), PrintError> {
self.0.print(p)?;
Expand All @@ -2970,7 +2970,7 @@ pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintOnlyTraitPath<'tcx> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let trait_ref = tcx.short_string(self, path);
let trait_ref = tcx.short_string(tcx.lift(self), path);
rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref))
})
}
Expand All @@ -2990,7 +2990,7 @@ pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>);
impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintSugared<'tcx> {
fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
ty::tls::with(|tcx| {
let trait_ref = tcx.short_string(self, path);
let trait_ref = tcx.short_string(tcx.lift(self), path);
rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref))
})
}
Expand Down Expand Up @@ -3108,7 +3108,7 @@ macro_rules! forward_display_to_print {

macro_rules! define_print {
(($self:ident, $p:ident): $($ty:ty $print:block)+) => {
$(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
$(impl<'tcx, P: PrettyPrinter<'tcx>> Print<P> for $ty {
fn print(&$self, $p: &mut P) -> Result<(), PrintError> {
let _: () = $print;
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_symbol_mangling/src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ impl<'tcx> PrettyPrinter<'tcx> for LegacySymbolMangler<'tcx> {
// Identical to `PrettyPrinter::comma_sep` except there is no space after each comma.
fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
where
T: Print<'tcx, Self>,
T: Print<Self>,
{
if let Some(first) = elems.next() {
first.print(self)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(crate) struct Highlighted<'tcx, T> {

impl<'tcx, T> IntoDiagArg for Highlighted<'tcx, T>
where
T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
{
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
rustc_errors::DiagArgValue::Str(self.to_string().into())
Expand All @@ -43,7 +43,7 @@ impl<'tcx, T> Highlighted<'tcx, T> {

impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
where
T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut p = ty::print::FmtPrinter::new(self.tcx, self.ns);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
) -> Diag<'a> {
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
where
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
T: fmt::Display + for<'b> Print<FmtPrinter<'b, 'tcx>>,
{
let s = value.to_string();
if s.len() > 50 {
Expand Down
42 changes: 42 additions & 0 deletions tests/ui/traits/next-solver/alias-relate/transitive-inference.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver=globally
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass
// Regression test for trait-system-refactor-initiative#7. This test
// would error if we were to rely on lazy normalization here.
//
// We eagerly normalize the associated types, here, causing this to
// compile.

use std::marker::PhantomData;

#[derive(Default)]
struct Foo<T, U>(PhantomData<(T, U)>);

trait Trait {
type Assoc;

fn to_assoc(self) -> Self::Assoc;
}

impl Trait for Foo<u32, i32> {
type Assoc = Foo<u32, i32>;
fn to_assoc(self) -> Self::Assoc {
Foo(PhantomData)
}
}
impl Trait for Foo<i32, u32> {
type Assoc = Foo<i32, u32>;
fn to_assoc(self) -> Self::Assoc {
Foo(PhantomData)
}
}

#[allow(unused_assignments)]
fn main() {
let mut x: Foo<_, _> = Default::default();
let mut assoc = x.to_assoc();
assoc = Foo::<u32, _>(PhantomData);
assoc = Foo::<_, i32>(PhantomData);
x = assoc;
}
Loading