mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 22:46:50 +00:00
Rollup merge of #97703 - lcnr:post-89862, r=estebank
some additional `need_type_info.rs` cleanup also fixes #97698, fixes #97806 cc `@estebank`
This commit is contained in:
commit
59c2ff532d
@ -67,10 +67,8 @@ use rustc_hir::{Item, ItemKind, Node};
|
||||
use rustc_middle::dep_graph::DepContext;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
error::TypeError,
|
||||
subst::{GenericArgKind, Subst, SubstsRef},
|
||||
Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
|
||||
self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable,
|
||||
TypeSuperFoldable,
|
||||
};
|
||||
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
|
||||
use rustc_target::spec::abi;
|
||||
@ -926,10 +924,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
mut t1_out: &mut DiagnosticStyledString,
|
||||
mut t2_out: &mut DiagnosticStyledString,
|
||||
path: String,
|
||||
sub: ty::subst::SubstsRef<'tcx>,
|
||||
sub: &'tcx [ty::GenericArg<'tcx>],
|
||||
other_path: String,
|
||||
other_ty: Ty<'tcx>,
|
||||
) -> Option<()> {
|
||||
// FIXME/HACK: Go back to `SubstsRef` to use its inherent methods,
|
||||
// ideally that shouldn't be necessary.
|
||||
let sub = self.tcx.intern_substs(sub);
|
||||
for (i, ta) in sub.types().enumerate() {
|
||||
if ta == other_ty {
|
||||
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
|
||||
@ -960,45 +961,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// For generic types with parameters with defaults, remove the parameters corresponding to
|
||||
/// the defaults. This repeats a lot of the logic found in `ty::print::pretty`.
|
||||
fn strip_generic_default_params(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
substs: ty::subst::SubstsRef<'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let mut num_supplied_defaults = 0;
|
||||
|
||||
let default_params = generics.params.iter().rev().filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Type { has_default: true, .. } => Some(param.def_id),
|
||||
ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id),
|
||||
_ => None,
|
||||
});
|
||||
for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) {
|
||||
match actual.unpack() {
|
||||
GenericArgKind::Const(c) => {
|
||||
if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs)
|
||||
!= c
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
num_supplied_defaults += 1;
|
||||
}
|
||||
let len = generics.params.len();
|
||||
let mut generics = generics.clone();
|
||||
generics.params.truncate(len - num_supplied_defaults);
|
||||
substs.truncate_to(self.tcx, &generics)
|
||||
}
|
||||
|
||||
/// Given two `fn` signatures highlight only sub-parts that are different.
|
||||
fn cmp_fn_sig(
|
||||
&self,
|
||||
@ -1156,8 +1118,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
|
||||
let did1 = def1.did();
|
||||
let did2 = def2.did();
|
||||
let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1);
|
||||
let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2);
|
||||
let sub_no_defaults_1 =
|
||||
self.tcx.generics_of(did1).own_substs_no_defaults(self.tcx, sub1);
|
||||
let sub_no_defaults_2 =
|
||||
self.tcx.generics_of(did2).own_substs_no_defaults(self.tcx, sub2);
|
||||
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
|
||||
let path1 = self.tcx.def_path_str(did1);
|
||||
let path2 = self.tcx.def_path_str(did2);
|
||||
|
@ -2,6 +2,7 @@ use crate::infer::type_variable::TypeVariableOriginKind;
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Namespace};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
@ -11,7 +12,7 @@ use rustc_middle::infer::unify_key::ConstVariableOriginKind;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst};
|
||||
use rustc_middle::ty::{self, DefIdTree, InferConst};
|
||||
use rustc_middle::ty::{Ty, TyCtxt, TypeckResults};
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{BytePos, Span};
|
||||
@ -853,12 +854,23 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
|
||||
) => {
|
||||
if tcx.res_generics_def_id(path.res) != Some(def.did()) {
|
||||
bug!(
|
||||
"unexpected path: def={:?} substs={:?} path={:?}",
|
||||
def,
|
||||
substs,
|
||||
path,
|
||||
);
|
||||
match path.res {
|
||||
Res::Def(DefKind::TyAlias, _) => {
|
||||
// FIXME: Ideally we should support this. For that
|
||||
// we have to map back from the self type to the
|
||||
// type alias though. That's difficult.
|
||||
//
|
||||
// See the `need_type_info/type-alias.rs` test for
|
||||
// some examples.
|
||||
}
|
||||
// There cannot be inference variables in the self type,
|
||||
// so there's nothing for us to do here.
|
||||
Res::SelfTy { .. } => {}
|
||||
_ => warn!(
|
||||
"unexpected path: def={:?} substs={:?} path={:?}",
|
||||
def, substs, path,
|
||||
),
|
||||
}
|
||||
} else {
|
||||
return Box::new(
|
||||
self.resolved_path_inferred_subst_iter(path, substs)
|
||||
@ -958,26 +970,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
|
||||
generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
|
||||
{
|
||||
let substs = self.infcx.resolve_vars_if_possible(substs);
|
||||
let num_args = generics
|
||||
.params
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|&p| !matches!(p.kind, GenericParamDefKind::Lifetime))
|
||||
.skip_while(|¶m| {
|
||||
if let Some(default) = param.default_value(tcx) {
|
||||
// FIXME: Using structural comparisions has a bunch of false negatives.
|
||||
//
|
||||
// We should instead try to replace inference variables with placeholders and
|
||||
// then use `infcx.can_eq`. That probably should be a separate method
|
||||
// generally used during error reporting.
|
||||
default.subst(tcx, substs) == substs[param.index as usize]
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.count();
|
||||
let generic_args =
|
||||
&generics.own_substs(substs)[generics.own_counts().lifetimes..][..num_args];
|
||||
let generic_args = &generics.own_substs_no_defaults(tcx, substs)
|
||||
[generics.own_counts().lifetimes..];
|
||||
let span = match expr.kind {
|
||||
ExprKind::MethodCall(path, _, _) => path.ident.span,
|
||||
_ => expr.span,
|
||||
|
@ -228,8 +228,47 @@ impl<'tcx> Generics {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the substs corresponding to the generic parameters
|
||||
/// of this item, excluding `Self`.
|
||||
///
|
||||
/// **This should only be used for diagnostics purposes.**
|
||||
pub fn own_substs_no_defaults(
|
||||
&'tcx self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'tcx [ty::GenericArg<'tcx>],
|
||||
) -> &'tcx [ty::GenericArg<'tcx>] {
|
||||
let mut own_params = self.parent_count..self.count();
|
||||
if self.has_self && self.parent.is_none() {
|
||||
own_params.start = 1;
|
||||
}
|
||||
|
||||
// Filter the default arguments.
|
||||
//
|
||||
// This currently uses structural equality instead
|
||||
// of semantic equivalance. While not ideal, that's
|
||||
// good enough for now as this should only be used
|
||||
// for diagnostics anyways.
|
||||
own_params.end -= self
|
||||
.params
|
||||
.iter()
|
||||
.rev()
|
||||
.take_while(|param| {
|
||||
param.default_value(tcx).map_or(false, |default| {
|
||||
default.subst(tcx, substs) == substs[param.index as usize]
|
||||
})
|
||||
})
|
||||
.count();
|
||||
|
||||
&substs[own_params]
|
||||
}
|
||||
|
||||
/// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
|
||||
pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
|
||||
///
|
||||
/// **This should only be used for diagnostics purposes.**
|
||||
pub fn own_substs(
|
||||
&'tcx self,
|
||||
substs: &'tcx [ty::GenericArg<'tcx>],
|
||||
) -> &'tcx [ty::GenericArg<'tcx>] {
|
||||
let own = &substs[self.parent_count..][..self.params.len()];
|
||||
if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use crate::mir::{Body, GeneratorLayout};
|
||||
use crate::traits::{self, Reveal};
|
||||
use crate::ty;
|
||||
use crate::ty::fast_reject::SimplifiedType;
|
||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::util::Discr;
|
||||
pub use adt::*;
|
||||
pub use assoc::*;
|
||||
@ -44,6 +43,7 @@ use rustc_session::cstore::CrateStoreDyn;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::Align;
|
||||
pub use subst::*;
|
||||
pub use vtable::*;
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
@ -149,7 +149,7 @@ pub trait Printer<'tcx>: Sized {
|
||||
// on top of the same path, but without its own generics.
|
||||
_ => {
|
||||
if !generics.params.is_empty() && substs.len() >= generics.count() {
|
||||
let args = self.generic_args_to_print(generics, substs);
|
||||
let args = generics.own_substs_no_defaults(self.tcx(), substs);
|
||||
return self.path_generic_args(
|
||||
|cx| cx.print_def_path(def_id, parent_substs),
|
||||
args,
|
||||
@ -184,43 +184,6 @@ pub trait Printer<'tcx>: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
fn generic_args_to_print(
|
||||
&self,
|
||||
generics: &'tcx ty::Generics,
|
||||
substs: &'tcx [GenericArg<'tcx>],
|
||||
) -> &'tcx [GenericArg<'tcx>] {
|
||||
let mut own_params = generics.parent_count..generics.count();
|
||||
|
||||
// Don't print args for `Self` parameters (of traits).
|
||||
if generics.has_self && own_params.start == 0 {
|
||||
own_params.start = 1;
|
||||
}
|
||||
|
||||
// Don't print args that are the defaults of their respective parameters.
|
||||
own_params.end -= generics
|
||||
.params
|
||||
.iter()
|
||||
.rev()
|
||||
.take_while(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => false,
|
||||
ty::GenericParamDefKind::Type { has_default, .. } => {
|
||||
has_default
|
||||
&& substs[param.index as usize]
|
||||
== GenericArg::from(
|
||||
self.tcx().bound_type_of(param.def_id).subst(self.tcx(), substs),
|
||||
)
|
||||
}
|
||||
ty::GenericParamDefKind::Const { has_default } => {
|
||||
has_default
|
||||
&& substs[param.index as usize]
|
||||
== GenericArg::from(self.tcx().const_param_default(param.def_id))
|
||||
}
|
||||
})
|
||||
.count();
|
||||
|
||||
&substs[own_params]
|
||||
}
|
||||
|
||||
fn default_print_impl_path(
|
||||
self,
|
||||
impl_def_id: DefId,
|
||||
|
@ -825,12 +825,11 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
for (fn_once_trait_ref, entry) in fn_traits {
|
||||
// Get the (single) generic ty (the args) of this FnOnce trait ref.
|
||||
let generics = self.generic_args_to_print(
|
||||
self.tcx().generics_of(fn_once_trait_ref.def_id()),
|
||||
fn_once_trait_ref.skip_binder().substs,
|
||||
);
|
||||
let generics = self.tcx().generics_of(fn_once_trait_ref.def_id());
|
||||
let args =
|
||||
generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs);
|
||||
|
||||
match (entry.return_ty, generics[0].expect_ty()) {
|
||||
match (entry.return_ty, args[0].expect_ty()) {
|
||||
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
|
||||
// a return type.
|
||||
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
|
||||
@ -892,15 +891,13 @@ pub trait PrettyPrinter<'tcx>:
|
||||
print(trait_ref.skip_binder().print_only_trait_name())
|
||||
);
|
||||
|
||||
let generics = self.generic_args_to_print(
|
||||
self.tcx().generics_of(trait_ref.def_id()),
|
||||
trait_ref.skip_binder().substs,
|
||||
);
|
||||
let generics = self.tcx().generics_of(trait_ref.def_id());
|
||||
let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs);
|
||||
|
||||
if !generics.is_empty() || !assoc_items.is_empty() {
|
||||
if !args.is_empty() || !assoc_items.is_empty() {
|
||||
let mut first = true;
|
||||
|
||||
for ty in generics {
|
||||
for ty in args {
|
||||
if first {
|
||||
p!("<");
|
||||
first = false;
|
||||
@ -1071,10 +1068,10 @@ pub trait PrettyPrinter<'tcx>:
|
||||
let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0));
|
||||
let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
|
||||
|
||||
let args = cx.generic_args_to_print(
|
||||
cx.tcx().generics_of(principal.def_id),
|
||||
principal.substs,
|
||||
);
|
||||
let args = cx
|
||||
.tcx()
|
||||
.generics_of(principal.def_id)
|
||||
.own_substs_no_defaults(cx.tcx(), principal.substs);
|
||||
|
||||
// Don't print `'_` if there's no unerased regions.
|
||||
let print_regions = args.iter().any(|arg| match arg.unpack() {
|
||||
|
@ -15,12 +15,12 @@ impl Traitor<1, 2> for u64 {}
|
||||
|
||||
|
||||
fn uwu<const N: u8>() -> impl Traitor<N> {
|
||||
//~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied
|
||||
//~^ error: the trait bound `u32: Traitor<N>` is not satisfied
|
||||
1_u32
|
||||
}
|
||||
|
||||
fn owo() -> impl Traitor {
|
||||
//~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
|
||||
//~^ error: the trait bound `u64: Traitor` is not satisfied
|
||||
1_u64
|
||||
}
|
||||
|
||||
|
@ -6,21 +6,21 @@ LL | fn rawr() -> impl Trait {
|
||||
|
|
||||
= help: the trait `Trait` is implemented for `Uwu<N>`
|
||||
|
||||
error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
|
||||
error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied
|
||||
--> $DIR/rp_impl_trait_fail.rs:17:26
|
||||
|
|
||||
LL | fn uwu<const N: u8>() -> impl Traitor<N> {
|
||||
| ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
|
||||
| ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32`
|
||||
|
|
||||
= help: the following other types implement trait `Traitor<N, M>`:
|
||||
<u32 as Traitor<N, 2_u8>>
|
||||
<u64 as Traitor<1_u8, 2_u8>>
|
||||
|
||||
error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
|
||||
error[E0277]: the trait bound `u64: Traitor` is not satisfied
|
||||
--> $DIR/rp_impl_trait_fail.rs:22:13
|
||||
|
|
||||
LL | fn owo() -> impl Traitor {
|
||||
| ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
|
||||
| ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64`
|
||||
|
|
||||
= help: the following other types implement trait `Traitor<N, M>`:
|
||||
<u32 as Traitor<N, 2_u8>>
|
||||
|
@ -26,5 +26,5 @@ fn main() {
|
||||
foo(&10_u32);
|
||||
//~^ error: the trait bound `u32: Trait` is not satisfied
|
||||
bar(&true);
|
||||
//~^ error: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
|
||||
//~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ LL | foo(&10_u32);
|
||||
= help: the trait `Trait<2_u8>` is implemented for `u32`
|
||||
= note: required for the cast to the object type `dyn Trait`
|
||||
|
||||
error[E0277]: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
|
||||
error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
|
||||
--> $DIR/trait_objects_fail.rs:28:9
|
||||
|
|
||||
LL | bar(&true);
|
||||
| --- ^^^^^ the trait `Traitor<{_: u8}, {_: u8}>` is not implemented for `bool`
|
||||
| --- ^^^^^ the trait `Traitor<{_: u8}>` is not implemented for `bool`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool`
|
||||
= note: required for the cast to the object type `dyn Traitor<{_: u8}, {_: u8}>`
|
||||
= note: required for the cast to the object type `dyn Traitor<{_: u8}>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
16
src/test/ui/inference/need_type_info/concrete-impl.rs
Normal file
16
src/test/ui/inference/need_type_info/concrete-impl.rs
Normal file
@ -0,0 +1,16 @@
|
||||
trait Ambiguous<A> {
|
||||
fn method() {}
|
||||
}
|
||||
|
||||
struct One;
|
||||
struct Two;
|
||||
struct Struct;
|
||||
|
||||
impl Ambiguous<One> for Struct {}
|
||||
impl Ambiguous<Two> for Struct {}
|
||||
|
||||
fn main() {
|
||||
<Struct as Ambiguous<_>>::method();
|
||||
//~^ ERROR type annotations needed
|
||||
//~| ERROR type annotations needed
|
||||
}
|
33
src/test/ui/inference/need_type_info/concrete-impl.stderr
Normal file
33
src/test/ui/inference/need_type_info/concrete-impl.stderr
Normal file
@ -0,0 +1,33 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/concrete-impl.rs:13:5
|
||||
|
|
||||
LL | <Struct as Ambiguous<_>>::method();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | <Struct as Ambiguous::<_>>::method();
|
||||
| ~~~~~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/concrete-impl.rs:13:5
|
||||
|
|
||||
LL | <Struct as Ambiguous<_>>::method();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
|
||||
|
|
||||
note: multiple `impl`s satisfying `Struct: Ambiguous<_>` found
|
||||
--> $DIR/concrete-impl.rs:9:1
|
||||
|
|
||||
LL | impl Ambiguous<One> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl Ambiguous<Two> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | <Struct as Ambiguous::<_>>::method();
|
||||
| ~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0283.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
13
src/test/ui/inference/need_type_info/self-ty-in-path.rs
Normal file
13
src/test/ui/inference/need_type_info/self-ty-in-path.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Test that we don't ICE when encountering a `Self` in a path.
|
||||
struct TestErr<T>(T);
|
||||
|
||||
impl<T> TestErr<T> {
|
||||
fn func_a<U>() {}
|
||||
|
||||
fn func_b() {
|
||||
Self::func_a();
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/inference/need_type_info/self-ty-in-path.stderr
Normal file
14
src/test/ui/inference/need_type_info/self-ty-in-path.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/self-ty-in-path.rs:8:9
|
||||
|
|
||||
LL | Self::func_a();
|
||||
| ^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the associated function `func_a`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | Self::func_a::<U>();
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
18
src/test/ui/inference/need_type_info/type-alias-indirect.rs
Normal file
18
src/test/ui/inference/need_type_info/type-alias-indirect.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// An addition to the `type-alias.rs` test,
|
||||
// see the FIXME in that file for why this test
|
||||
// exists.
|
||||
//
|
||||
// If there is none, feel free to remove this test
|
||||
// again.
|
||||
struct Ty<T>(T);
|
||||
impl<T> Ty<T> {
|
||||
fn new() {}
|
||||
}
|
||||
|
||||
type IndirectAlias<T> = Ty<Box<T>>;
|
||||
fn indirect_alias() {
|
||||
IndirectAlias::new();
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/type-alias-indirect.rs:14:5
|
||||
|
|
||||
LL | IndirectAlias::new();
|
||||
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
36
src/test/ui/inference/need_type_info/type-alias.rs
Normal file
36
src/test/ui/inference/need_type_info/type-alias.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// Test the inference errors in case the relevant path
|
||||
// uses a type alias.
|
||||
//
|
||||
// Regression test for #97698.
|
||||
struct Ty<T>(T);
|
||||
impl<T> Ty<T> {
|
||||
fn new() {}
|
||||
}
|
||||
|
||||
type DirectAlias<T> = Ty<T>;
|
||||
fn direct_alias() {
|
||||
DirectAlias::new()
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
type IndirectAlias<T> = Ty<Box<T>>;
|
||||
fn indirect_alias() {
|
||||
IndirectAlias::new();
|
||||
// FIXME: This should also emit an error.
|
||||
//
|
||||
// Added it separately as `type-alias-indirect.rs`
|
||||
// where it does error.
|
||||
}
|
||||
|
||||
struct TyDefault<T, U = u32>(T, U);
|
||||
impl<T> TyDefault<T> {
|
||||
fn new() {}
|
||||
}
|
||||
|
||||
type DirectButWithDefaultAlias<T> = TyDefault<T>;
|
||||
fn direct_but_with_default_alias() {
|
||||
DirectButWithDefaultAlias::new();
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/inference/need_type_info/type-alias.stderr
Normal file
15
src/test/ui/inference/need_type_info/type-alias.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/type-alias.rs:12:5
|
||||
|
|
||||
LL | DirectAlias::new()
|
||||
| ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/type-alias.rs:32:5
|
||||
|
|
||||
LL | DirectButWithDefaultAlias::new();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
Loading…
Reference in New Issue
Block a user