Skip to content

Commit 59c2ff5

Browse files
authored
Rollup merge of #97703 - lcnr:post-89862, r=estebank
some additional `need_type_info.rs` cleanup also fixes #97698, fixes #97806 cc `@estebank`
2 parents f1f44b9 + d6b28f3 commit 59c2ff5

18 files changed

+249
-138
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+10-46
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,8 @@ use rustc_hir::{Item, ItemKind, Node};
6767
use rustc_middle::dep_graph::DepContext;
6868
use rustc_middle::ty::print::with_no_trimmed_paths;
6969
use rustc_middle::ty::{
70-
self,
71-
error::TypeError,
72-
subst::{GenericArgKind, Subst, SubstsRef},
73-
Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
70+
self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable,
71+
TypeSuperFoldable,
7472
};
7573
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
7674
use rustc_target::spec::abi;
@@ -926,10 +924,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
926924
mut t1_out: &mut DiagnosticStyledString,
927925
mut t2_out: &mut DiagnosticStyledString,
928926
path: String,
929-
sub: ty::subst::SubstsRef<'tcx>,
927+
sub: &'tcx [ty::GenericArg<'tcx>],
930928
other_path: String,
931929
other_ty: Ty<'tcx>,
932930
) -> Option<()> {
931+
// FIXME/HACK: Go back to `SubstsRef` to use its inherent methods,
932+
// ideally that shouldn't be necessary.
933+
let sub = self.tcx.intern_substs(sub);
933934
for (i, ta) in sub.types().enumerate() {
934935
if ta == other_ty {
935936
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
@@ -960,45 +961,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
960961
}
961962
}
962963

963-
/// For generic types with parameters with defaults, remove the parameters corresponding to
964-
/// the defaults. This repeats a lot of the logic found in `ty::print::pretty`.
965-
fn strip_generic_default_params(
966-
&self,
967-
def_id: DefId,
968-
substs: ty::subst::SubstsRef<'tcx>,
969-
) -> SubstsRef<'tcx> {
970-
let generics = self.tcx.generics_of(def_id);
971-
let mut num_supplied_defaults = 0;
972-
973-
let default_params = generics.params.iter().rev().filter_map(|param| match param.kind {
974-
ty::GenericParamDefKind::Type { has_default: true, .. } => Some(param.def_id),
975-
ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id),
976-
_ => None,
977-
});
978-
for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) {
979-
match actual.unpack() {
980-
GenericArgKind::Const(c) => {
981-
if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs)
982-
!= c
983-
{
984-
break;
985-
}
986-
}
987-
GenericArgKind::Type(ty) => {
988-
if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty {
989-
break;
990-
}
991-
}
992-
_ => break,
993-
}
994-
num_supplied_defaults += 1;
995-
}
996-
let len = generics.params.len();
997-
let mut generics = generics.clone();
998-
generics.params.truncate(len - num_supplied_defaults);
999-
substs.truncate_to(self.tcx, &generics)
1000-
}
1001-
1002964
/// Given two `fn` signatures highlight only sub-parts that are different.
1003965
fn cmp_fn_sig(
1004966
&self,
@@ -1156,8 +1118,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11561118
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
11571119
let did1 = def1.did();
11581120
let did2 = def2.did();
1159-
let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1);
1160-
let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2);
1121+
let sub_no_defaults_1 =
1122+
self.tcx.generics_of(did1).own_substs_no_defaults(self.tcx, sub1);
1123+
let sub_no_defaults_2 =
1124+
self.tcx.generics_of(did2).own_substs_no_defaults(self.tcx, sub2);
11611125
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
11621126
let path1 = self.tcx.def_path_str(did1);
11631127
let path2 = self.tcx.def_path_str(did2);

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+21-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::infer::type_variable::TypeVariableOriginKind;
22
use crate::infer::InferCtxt;
33
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
44
use rustc_hir as hir;
5+
use rustc_hir::def::Res;
56
use rustc_hir::def::{CtorOf, DefKind, Namespace};
67
use rustc_hir::def_id::DefId;
78
use rustc_hir::intravisit::{self, Visitor};
@@ -11,7 +12,7 @@ use rustc_middle::infer::unify_key::ConstVariableOriginKind;
1112
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
1213
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
1314
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
14-
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst};
15+
use rustc_middle::ty::{self, DefIdTree, InferConst};
1516
use rustc_middle::ty::{Ty, TyCtxt, TypeckResults};
1617
use rustc_span::symbol::{kw, Ident};
1718
use rustc_span::{BytePos, Span};
@@ -853,12 +854,23 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
853854
hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
854855
) => {
855856
if tcx.res_generics_def_id(path.res) != Some(def.did()) {
856-
bug!(
857-
"unexpected path: def={:?} substs={:?} path={:?}",
858-
def,
859-
substs,
860-
path,
861-
);
857+
match path.res {
858+
Res::Def(DefKind::TyAlias, _) => {
859+
// FIXME: Ideally we should support this. For that
860+
// we have to map back from the self type to the
861+
// type alias though. That's difficult.
862+
//
863+
// See the `need_type_info/type-alias.rs` test for
864+
// some examples.
865+
}
866+
// There cannot be inference variables in the self type,
867+
// so there's nothing for us to do here.
868+
Res::SelfTy { .. } => {}
869+
_ => warn!(
870+
"unexpected path: def={:?} substs={:?} path={:?}",
871+
def, substs, path,
872+
),
873+
}
862874
} else {
863875
return Box::new(
864876
self.resolved_path_inferred_subst_iter(path, substs)
@@ -958,26 +970,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
958970
generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
959971
{
960972
let substs = self.infcx.resolve_vars_if_possible(substs);
961-
let num_args = generics
962-
.params
963-
.iter()
964-
.rev()
965-
.filter(|&p| !matches!(p.kind, GenericParamDefKind::Lifetime))
966-
.skip_while(|&param| {
967-
if let Some(default) = param.default_value(tcx) {
968-
// FIXME: Using structural comparisions has a bunch of false negatives.
969-
//
970-
// We should instead try to replace inference variables with placeholders and
971-
// then use `infcx.can_eq`. That probably should be a separate method
972-
// generally used during error reporting.
973-
default.subst(tcx, substs) == substs[param.index as usize]
974-
} else {
975-
false
976-
}
977-
})
978-
.count();
979-
let generic_args =
980-
&generics.own_substs(substs)[generics.own_counts().lifetimes..][..num_args];
973+
let generic_args = &generics.own_substs_no_defaults(tcx, substs)
974+
[generics.own_counts().lifetimes..];
981975
let span = match expr.kind {
982976
ExprKind::MethodCall(path, _, _) => path.ident.span,
983977
_ => expr.span,

compiler/rustc_middle/src/ty/generics.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,47 @@ impl<'tcx> Generics {
228228
})
229229
}
230230

231+
/// Returns the substs corresponding to the generic parameters
232+
/// of this item, excluding `Self`.
233+
///
234+
/// **This should only be used for diagnostics purposes.**
235+
pub fn own_substs_no_defaults(
236+
&'tcx self,
237+
tcx: TyCtxt<'tcx>,
238+
substs: &'tcx [ty::GenericArg<'tcx>],
239+
) -> &'tcx [ty::GenericArg<'tcx>] {
240+
let mut own_params = self.parent_count..self.count();
241+
if self.has_self && self.parent.is_none() {
242+
own_params.start = 1;
243+
}
244+
245+
// Filter the default arguments.
246+
//
247+
// This currently uses structural equality instead
248+
// of semantic equivalance. While not ideal, that's
249+
// good enough for now as this should only be used
250+
// for diagnostics anyways.
251+
own_params.end -= self
252+
.params
253+
.iter()
254+
.rev()
255+
.take_while(|param| {
256+
param.default_value(tcx).map_or(false, |default| {
257+
default.subst(tcx, substs) == substs[param.index as usize]
258+
})
259+
})
260+
.count();
261+
262+
&substs[own_params]
263+
}
264+
231265
/// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
232-
pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
266+
///
267+
/// **This should only be used for diagnostics purposes.**
268+
pub fn own_substs(
269+
&'tcx self,
270+
substs: &'tcx [ty::GenericArg<'tcx>],
271+
) -> &'tcx [ty::GenericArg<'tcx>] {
233272
let own = &substs[self.parent_count..][..self.params.len()];
234273
if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
235274
}

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use crate::mir::{Body, GeneratorLayout};
2222
use crate::traits::{self, Reveal};
2323
use crate::ty;
2424
use crate::ty::fast_reject::SimplifiedType;
25-
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
2625
use crate::ty::util::Discr;
2726
pub use adt::*;
2827
pub use assoc::*;
@@ -44,6 +43,7 @@ use rustc_session::cstore::CrateStoreDyn;
4443
use rustc_span::symbol::{kw, sym, Ident, Symbol};
4544
use rustc_span::Span;
4645
use rustc_target::abi::Align;
46+
pub use subst::*;
4747
pub use vtable::*;
4848

4949
use std::fmt::Debug;

compiler/rustc_middle/src/ty/print/mod.rs

+1-38
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub trait Printer<'tcx>: Sized {
149149
// on top of the same path, but without its own generics.
150150
_ => {
151151
if !generics.params.is_empty() && substs.len() >= generics.count() {
152-
let args = self.generic_args_to_print(generics, substs);
152+
let args = generics.own_substs_no_defaults(self.tcx(), substs);
153153
return self.path_generic_args(
154154
|cx| cx.print_def_path(def_id, parent_substs),
155155
args,
@@ -184,43 +184,6 @@ pub trait Printer<'tcx>: Sized {
184184
}
185185
}
186186

187-
fn generic_args_to_print(
188-
&self,
189-
generics: &'tcx ty::Generics,
190-
substs: &'tcx [GenericArg<'tcx>],
191-
) -> &'tcx [GenericArg<'tcx>] {
192-
let mut own_params = generics.parent_count..generics.count();
193-
194-
// Don't print args for `Self` parameters (of traits).
195-
if generics.has_self && own_params.start == 0 {
196-
own_params.start = 1;
197-
}
198-
199-
// Don't print args that are the defaults of their respective parameters.
200-
own_params.end -= generics
201-
.params
202-
.iter()
203-
.rev()
204-
.take_while(|param| match param.kind {
205-
ty::GenericParamDefKind::Lifetime => false,
206-
ty::GenericParamDefKind::Type { has_default, .. } => {
207-
has_default
208-
&& substs[param.index as usize]
209-
== GenericArg::from(
210-
self.tcx().bound_type_of(param.def_id).subst(self.tcx(), substs),
211-
)
212-
}
213-
ty::GenericParamDefKind::Const { has_default } => {
214-
has_default
215-
&& substs[param.index as usize]
216-
== GenericArg::from(self.tcx().const_param_default(param.def_id))
217-
}
218-
})
219-
.count();
220-
221-
&substs[own_params]
222-
}
223-
224187
fn default_print_impl_path(
225188
self,
226189
impl_def_id: DefId,

compiler/rustc_middle/src/ty/print/pretty.rs

+12-15
Original file line numberDiff line numberDiff line change
@@ -825,12 +825,11 @@ pub trait PrettyPrinter<'tcx>:
825825

826826
for (fn_once_trait_ref, entry) in fn_traits {
827827
// Get the (single) generic ty (the args) of this FnOnce trait ref.
828-
let generics = self.generic_args_to_print(
829-
self.tcx().generics_of(fn_once_trait_ref.def_id()),
830-
fn_once_trait_ref.skip_binder().substs,
831-
);
828+
let generics = self.tcx().generics_of(fn_once_trait_ref.def_id());
829+
let args =
830+
generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs);
832831

833-
match (entry.return_ty, generics[0].expect_ty()) {
832+
match (entry.return_ty, args[0].expect_ty()) {
834833
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
835834
// a return type.
836835
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
@@ -892,15 +891,13 @@ pub trait PrettyPrinter<'tcx>:
892891
print(trait_ref.skip_binder().print_only_trait_name())
893892
);
894893

895-
let generics = self.generic_args_to_print(
896-
self.tcx().generics_of(trait_ref.def_id()),
897-
trait_ref.skip_binder().substs,
898-
);
894+
let generics = self.tcx().generics_of(trait_ref.def_id());
895+
let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs);
899896

900-
if !generics.is_empty() || !assoc_items.is_empty() {
897+
if !args.is_empty() || !assoc_items.is_empty() {
901898
let mut first = true;
902899

903-
for ty in generics {
900+
for ty in args {
904901
if first {
905902
p!("<");
906903
first = false;
@@ -1071,10 +1068,10 @@ pub trait PrettyPrinter<'tcx>:
10711068
let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0));
10721069
let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
10731070

1074-
let args = cx.generic_args_to_print(
1075-
cx.tcx().generics_of(principal.def_id),
1076-
principal.substs,
1077-
);
1071+
let args = cx
1072+
.tcx()
1073+
.generics_of(principal.def_id)
1074+
.own_substs_no_defaults(cx.tcx(), principal.substs);
10781075

10791076
// Don't print `'_` if there's no unerased regions.
10801077
let print_regions = args.iter().any(|arg| match arg.unpack() {

src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ impl Traitor<1, 2> for u64 {}
1515

1616

1717
fn uwu<const N: u8>() -> impl Traitor<N> {
18-
//~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied
18+
//~^ error: the trait bound `u32: Traitor<N>` is not satisfied
1919
1_u32
2020
}
2121

2222
fn owo() -> impl Traitor {
23-
//~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
23+
//~^ error: the trait bound `u64: Traitor` is not satisfied
2424
1_u64
2525
}
2626

src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ LL | fn rawr() -> impl Trait {
66
|
77
= help: the trait `Trait` is implemented for `Uwu<N>`
88

9-
error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
9+
error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied
1010
--> $DIR/rp_impl_trait_fail.rs:17:26
1111
|
1212
LL | fn uwu<const N: u8>() -> impl Traitor<N> {
13-
| ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
13+
| ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32`
1414
|
1515
= help: the following other types implement trait `Traitor<N, M>`:
1616
<u32 as Traitor<N, 2_u8>>
1717
<u64 as Traitor<1_u8, 2_u8>>
1818

19-
error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
19+
error[E0277]: the trait bound `u64: Traitor` is not satisfied
2020
--> $DIR/rp_impl_trait_fail.rs:22:13
2121
|
2222
LL | fn owo() -> impl Traitor {
23-
| ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
23+
| ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64`
2424
|
2525
= help: the following other types implement trait `Traitor<N, M>`:
2626
<u32 as Traitor<N, 2_u8>>

src/test/ui/const-generics/defaults/trait_objects_fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ fn main() {
2626
foo(&10_u32);
2727
//~^ error: the trait bound `u32: Trait` is not satisfied
2828
bar(&true);
29-
//~^ error: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
29+
//~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
3030
}

0 commit comments

Comments
 (0)