From 8759f00c73641d44b3ab7a2290e3c58168d3e30f Mon Sep 17 00:00:00 2001 From: kadmin Date: Thu, 6 May 2021 15:33:44 +0000 Subject: [PATCH] Actually infer args in visitors --- compiler/rustc_ast/src/ast.rs | 2 + compiler/rustc_ast_lowering/src/lib.rs | 10 ++-- compiler/rustc_feature/src/active.rs | 3 ++ compiler/rustc_hir/src/hir.rs | 49 +++++++++++++------ compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 7 +++ compiler/rustc_resolve/src/late/lifetimes.rs | 4 +- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/astconv/generics.rs | 27 +++++----- compiler/rustc_typeck/src/astconv/mod.rs | 6 ++- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 5 +- .../rustc_typeck/src/check/method/confirm.rs | 5 +- compiler/rustc_typeck/src/collect/type_of.rs | 3 ++ .../ui/const-generics/issues/issue-62878.rs | 2 +- .../min_const_generics/inferred_const.rs | 1 + ...ature-gate-generic_arg_infer.normal.stderr | 12 +++++ .../feature-gate-generic_arg_infer.rs | 13 +++++ src/test/ui/inference/infer-arg-test.rs | 24 +++++++++ src/test/ui/inference/infer-arg-test.stderr | 36 ++++++++++++++ .../ui/object-lifetime-default-inferred.rs | 35 +++++++++++++ .../ui/parser/issue-14303-fncall.full.stderr | 9 ++++ ... => issue-14303-fncall.generic_arg.stderr} | 2 +- src/test/ui/parser/issue-14303-fncall.rs | 8 ++- .../associated-item-privacy-trait.stderr | 2 +- ...e-42234-unknown-receiver-type.full.stderr} | 4 +- ...4-unknown-receiver-type.generic_arg.stderr | 21 ++++++++ .../span/issue-42234-unknown-receiver-type.rs | 3 ++ src/tools/clippy/clippy_lints/src/use_self.rs | 48 +----------------- .../clippy/clippy_utils/src/hir_utils.rs | 6 +-- .../tests/ui/transmute_ptr_to_ref.stderr | 4 +- 30 files changed, 257 insertions(+), 97 deletions(-) create mode 100644 src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs create mode 100644 src/test/ui/inference/infer-arg-test.rs create mode 100644 src/test/ui/inference/infer-arg-test.stderr create mode 100644 src/test/ui/object-lifetime-default-inferred.rs create mode 100644 src/test/ui/parser/issue-14303-fncall.full.stderr rename src/test/ui/parser/{issue-14303-fncall.stderr => issue-14303-fncall.generic_arg.stderr} (86%) rename src/test/ui/span/{issue-42234-unknown-receiver-type.stderr => issue-42234-unknown-receiver-type.full.stderr} (85%) create mode 100644 src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5bffc94364d9d..8cab83707dcbc 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -336,6 +336,8 @@ pub enum ParamKindOrd { // is active. Specifically, if it's only `min_const_generics`, it will still require // ordering consts after types. Const { unordered: bool }, + // `Infer` is not actually constructed directly from the AST, but is implicitly constructed + // during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last. Infer, } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c7a477fedc604..a19a2fbbe74f9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -51,7 +51,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::intravisit; -use rustc_hir::{ConstArg, GenericArg, ParamName}; +use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName}; use rustc_index::vec::{Idx, IndexVec}; use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI}; use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; @@ -1219,9 +1219,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), ast::GenericArg::Type(ty) => { match ty.kind { - TyKind::Infer => { + TyKind::Infer if self.sess.features_untracked().generic_arg_infer => { let hir_id = self.lower_node_id(ty.id); - return GenericArg::Infer(hir::InferArg { hir_id, span: ty.span }); + return GenericArg::Infer(hir::InferArg { + hir_id, + span: ty.span, + kind: InferKind::Type, + }); } // We parse const arguments as path types as we cannot distinguish them during // parsing. We try to resolve that ambiguity by attempting resolution in both the diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index a3e40daf6bf6d..46bf49d640f25 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -684,6 +684,9 @@ declare_features! ( /// Allows `cfg(target_abi = "...")`. (active, cfg_target_abi, "1.55.0", Some(80970), None), + /// Infer generic args for both consts and types. + (active, generic_arg_infer, "1.55.0", Some(85077), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 140219287b1c0..4914280f5c87f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -253,9 +253,23 @@ pub struct ConstArg { pub span: Span, } +#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)] +pub enum InferKind { + Const, + Type, +} + +impl InferKind { + #[inline] + pub fn is_type(self) -> bool { + matches!(self, InferKind::Type) + } +} + #[derive(Encodable, Debug, HashStable_Generic)] pub struct InferArg { pub hir_id: HirId, + pub kind: InferKind, pub span: Span, } @@ -365,22 +379,29 @@ impl GenericArgs<'_> { panic!("GenericArgs::inputs: not a `Fn(T) -> U`"); } - pub fn own_counts(&self) -> GenericParamCount { - // We could cache this as a property of `GenericParamCount`, but - // the aim is to refactor this away entirely eventually and the - // presence of this method will be a constant reminder. - let mut own_counts: GenericParamCount = Default::default(); + #[inline] + pub fn has_type_params(&self) -> bool { + self.args.iter().any(|arg| matches!(arg, GenericArg::Type(_))) + } - for arg in self.args { - match arg { - GenericArg::Lifetime(_) => own_counts.lifetimes += 1, - GenericArg::Type(_) => own_counts.types += 1, - GenericArg::Const(_) => own_counts.consts += 1, - GenericArg::Infer(_) => own_counts.infer += 1, - }; - } + #[inline] + pub fn num_type_params(&self) -> usize { + self.args.iter().filter(|arg| matches!(arg, GenericArg::Type(_))).count() + } + + #[inline] + pub fn num_lifetime_params(&self) -> usize { + self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count() + } - own_counts + #[inline] + pub fn has_lifetime_params(&self) -> bool { + self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))) + } + + #[inline] + pub fn num_generic_params(&self) -> usize { + self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count() } /// The span encompassing the text inside the surrounding brackets. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d47bef4379c32..94dd2116e166b 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -103,7 +103,7 @@ impl<'a> State<'a> { Node::TraitRef(a) => self.print_trait_ref(&a), Node::Binding(a) | Node::Pat(a) => self.print_pat(&a), Node::Arm(a) => self.print_arm(&a), - Node::Infer(_) => self.print_string("_", ast::StrStyle::Cooked), + Node::Infer(_) => self.s.word("_"), Node::Block(a) => { // Containing cbox, will be closed by print-block at `}`. self.cbox(INDENT_UNIT); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e77bda7d4ab03..cd91ecdf2bad3 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1224,6 +1224,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { } } } else { + let local_id = self.tcx.hir().local_def_id(inf.hir_id); + if let Some(did) = self.tcx.opt_const_param_of(local_id) { + if self.visit_def_id(did, "inferred", &"").is_break() { + return; + } + } + // FIXME see above note for same issue. if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() { return; diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 26e2efc255200..bf6d5542f62f8 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2559,7 +2559,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } GenericArg::Infer(inf) => { self.visit_id(inf.hir_id); - i += 1; + if inf.kind.is_type() { + i += 1; + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c0f63f40853da..536ebdef426b8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -622,6 +622,7 @@ symbols! { generator, generator_state, generators, + generic_arg_infer, generic_associated_types, generic_param_attrs, get_context, diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index dd15d2d65b993..eb6265dec89c0 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -39,11 +39,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); if let GenericParamDefKind::Const { .. } = param.kind { - if matches!( - arg, - GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. }) | GenericArg::Infer(_) - ) { + if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. })) { err.help("const arguments cannot yet be inferred with `_`"); + if sess.is_nightly_build() { + err.help( + "add `#![feature(generic_arg_infer)]` to the crate attributes to enable", + ); + } } } @@ -458,8 +460,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let default_counts = gen_params.own_defaults(); let param_counts = gen_params.own_counts(); let named_type_param_count = param_counts.types - has_self as usize; - let arg_counts = gen_args.own_counts(); - let infer_lifetimes = gen_pos != GenericArgPosition::Type && arg_counts.lifetimes == 0; + let infer_lifetimes = + gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params(); if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() { Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span); @@ -517,7 +519,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes }; let max_expected_lifetime_args = param_counts.lifetimes; - let num_provided_lifetime_args = arg_counts.lifetimes; + let num_provided_lifetime_args = gen_args.num_lifetime_params(); let lifetimes_correct = check_lifetime_args( min_expected_lifetime_args, @@ -588,14 +590,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { - default_counts.consts }; debug!("expected_min: {:?}", expected_min); - debug!("arg_counts.lifetimes: {:?}", arg_counts.lifetimes); + debug!("arg_counts.lifetimes: {:?}", gen_args.num_lifetime_params()); check_types_and_consts( expected_min, param_counts.consts + named_type_param_count, - arg_counts.consts + arg_counts.types + arg_counts.infer, + gen_args.num_generic_params(), param_counts.lifetimes + has_self as usize, - arg_counts.lifetimes, + gen_args.num_lifetime_params(), ) }; @@ -673,8 +675,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { position: GenericArgPosition, ) -> ExplicitLateBound { let param_counts = def.own_counts(); - let arg_counts = args.own_counts(); - let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0; + let infer_lifetimes = position != GenericArgPosition::Type && !args.has_lifetime_params(); if infer_lifetimes { return ExplicitLateBound::No; @@ -687,7 +688,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let span = args.args[0].span(); if position == GenericArgPosition::Value - && arg_counts.lifetimes != param_counts.lifetimes + && args.num_lifetime_params() != param_counts.lifetimes { let mut err = tcx.sess.struct_span_err(span, msg); err.span_note(span_late, note); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 58ad086f2259b..03c4c5dfa0c02 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -463,8 +463,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } (&GenericParamDefKind::Const { has_default }, hir::GenericArg::Infer(inf)) => { if has_default { - // FIXME(const_generics): Actually infer parameter here? tcx.const_param_default(param.def_id).into() + } else if self.astconv.allow_ty_infer() { + // FIXME(const_generics): Actually infer parameter here? + todo!() } else { self.inferred_params.push(inf.span); tcx.ty_error().into() @@ -1963,7 +1965,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } has_err = true; err_for_ty = true; - (inf.span, "inferred") + (inf.span, "generic") } }; let mut err = struct_span_err!( diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 310517339cd67..f5776ae7cf66a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1480,10 +1480,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.const_arg_to_const(&ct.value, param.def_id).into() } (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { - self.fcx.to_ty(&inf.to_ty()).into() + self.fcx.ty_infer(Some(param), inf.span).into() } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { - self.fcx.var_for_def(inf.span, param) + let tcx = self.fcx.tcx(); + self.fcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into() } _ => unreachable!(), } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 3224fe362cb1f..3aceaba882d6c 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -367,10 +367,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.cfcx.const_arg_to_const(&ct.value, param.def_id).into() } (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { - self.cfcx.to_ty(&inf.to_ty()).into() + self.cfcx.ty_infer(Some(param), inf.span).into() } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { - self.cfcx.var_for_def(inf.span, param) + let tcx = self.cfcx.tcx(); + self.cfcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into() } _ => unreachable!(), } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 50e4ba4fe6c3e..96b3fa9aa0143 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -20,6 +20,9 @@ use super::{bad_placeholder_type, is_suggestable_infer_ty}; /// /// This should be called using the query `tcx.opt_const_param_of`. pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { + // FIXME(generic_arg_infer): allow for returning DefIds of inference of + // GenericArg::Infer below. This may require a change where GenericArg::Infer has some flag + // for const or type. use hir::*; let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs index fae57b37773bb..fb6257696b96d 100644 --- a/src/test/ui/const-generics/issues/issue-62878.rs +++ b/src/test/ui/const-generics/issues/issue-62878.rs @@ -1,5 +1,5 @@ // revisions: full min -#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, feature(const_generics, generic_arg_infer))] #![cfg_attr(full, allow(incomplete_features))] fn foo() {} diff --git a/src/test/ui/const-generics/min_const_generics/inferred_const.rs b/src/test/ui/const-generics/min_const_generics/inferred_const.rs index f5800d1097120..57d6941587a43 100644 --- a/src/test/ui/const-generics/min_const_generics/inferred_const.rs +++ b/src/test/ui/const-generics/min_const_generics/inferred_const.rs @@ -1,3 +1,4 @@ +#![feature(generic_arg_infer)] // run-pass fn foo(_data: [u32; N]) -> [u32; K] { diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr new file mode 100644 index 0000000000000..c17f02d58f325 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr @@ -0,0 +1,12 @@ +error[E0747]: type provided when a constant was expected + --> $DIR/feature-gate-generic_arg_infer.rs:11:20 + | +LL | let _x = foo::<_>([1,2]); + | ^ + | + = help: const arguments cannot yet be inferred with `_` + = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs new file mode 100644 index 0000000000000..4729773b12ef0 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs @@ -0,0 +1,13 @@ +// [feature] run-pass +// revisions: normal feature + +#![cfg_attr(feature, feature(generic_arg_infer))] + +fn foo(_: [u8; N]) -> [u8; N] { + [0; N] +} + +fn main() { + let _x = foo::<_>([1,2]); + //[normal]~^ ERROR: type provided when a constant was expected +} diff --git a/src/test/ui/inference/infer-arg-test.rs b/src/test/ui/inference/infer-arg-test.rs new file mode 100644 index 0000000000000..1b67ccd6c4337 --- /dev/null +++ b/src/test/ui/inference/infer-arg-test.rs @@ -0,0 +1,24 @@ +#![feature(generic_arg_infer)] + +struct All<'a, T, const N: usize> { + v: &'a T, +} + +struct BadInfer<_>; +//~^ ERROR expected identifier +//~| ERROR parameter `_` is never used + +fn all_fn<'a, T, const N: usize>() {} + +fn bad_infer_fn<_>() {} +//~^ ERROR expected identifier + + +fn main() { + let a: All<_, _, _>; + all_fn(); + let v: [u8; _]; + //~^ ERROR in expressions + let v: [u8; 10] = [0; _]; + //~^ ERROR in expressions +} diff --git a/src/test/ui/inference/infer-arg-test.stderr b/src/test/ui/inference/infer-arg-test.stderr new file mode 100644 index 0000000000000..30e171eac2121 --- /dev/null +++ b/src/test/ui/inference/infer-arg-test.stderr @@ -0,0 +1,36 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/infer-arg-test.rs:7:17 + | +LL | struct BadInfer<_>; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/infer-arg-test.rs:13:17 + | +LL | fn bad_infer_fn<_>() {} + | ^ expected identifier, found reserved identifier + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/infer-arg-test.rs:20:15 + | +LL | let v: [u8; _]; + | ^ `_` not allowed here + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/infer-arg-test.rs:22:25 + | +LL | let v: [u8; 10] = [0; _]; + | ^ `_` not allowed here + +error[E0392]: parameter `_` is never used + --> $DIR/infer-arg-test.rs:7:17 + | +LL | struct BadInfer<_>; + | ^ unused parameter + | + = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `_` to be a const parameter, use `const _: usize` instead + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/object-lifetime-default-inferred.rs b/src/test/ui/object-lifetime-default-inferred.rs new file mode 100644 index 0000000000000..8a1156b8fc8ad --- /dev/null +++ b/src/test/ui/object-lifetime-default-inferred.rs @@ -0,0 +1,35 @@ +// run-pass +// Test that even with prior inferred parameters, object lifetimes of objects after are still +// valid. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] +#![feature(generic_arg_infer)] + +trait Test { + fn foo(&self) { } +} + +struct Foo; +impl Test for Foo {} + +struct SomeStruct<'a> { + t: &'a dyn Test, + u: &'a (dyn Test+'a), +} + +fn a<'a, const N: usize>(_: [u8; N], t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a, T>(_: T, t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn main() { + // Inside a function body, we can just infer both + // lifetimes, to allow &'tmp (Display+'static). + a::<_>([], &Foo as &dyn Test, SomeStruct{t:&Foo,u:&Foo}); + b::<_>(0u8, &Foo as &dyn Test, SomeStruct{t:&Foo,u:&Foo}); +} diff --git a/src/test/ui/parser/issue-14303-fncall.full.stderr b/src/test/ui/parser/issue-14303-fncall.full.stderr new file mode 100644 index 0000000000000..02af61e853967 --- /dev/null +++ b/src/test/ui/parser/issue-14303-fncall.full.stderr @@ -0,0 +1,9 @@ +error[E0747]: type provided when a lifetime was expected + --> $DIR/issue-14303-fncall.rs:16:26 + | +LL | .collect::>>(); + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.generic_arg.stderr similarity index 86% rename from src/test/ui/parser/issue-14303-fncall.stderr rename to src/test/ui/parser/issue-14303-fncall.generic_arg.stderr index a039eca0bfdf4..9f3359b3f68a9 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.generic_arg.stderr @@ -1,5 +1,5 @@ error[E0747]: inferred provided when a lifetime was expected - --> $DIR/issue-14303-fncall.rs:13:26 + --> $DIR/issue-14303-fncall.rs:16:26 | LL | .collect::>>(); | ^ diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index 1757baec70f2b..976a79a59b1f8 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -1,6 +1,9 @@ -// can't run rustfix because it doesn't handle multipart suggestions correctly +// revisions: full generic_arg // compile-flags: -Zborrowck=mir +// can't run rustfix because it doesn't handle multipart suggestions correctly // we need the above to avoid ast borrowck failure in recovered code +#![cfg_attr(generic_arg, feature(generic_arg_infer))] + struct S<'a, T> { a: &'a T, @@ -11,7 +14,8 @@ fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { let _x = (*start..*end) .map(|x| S { a: start, b: end }) .collect::>>(); - //~^ ERROR inferred provided when a lifetime was expected + //[generic_arg]~^ ERROR inferred provided when a lifetime was expected + //[full]~^^ ERROR type provided when a lifetime was expected } fn main() {} diff --git a/src/test/ui/privacy/associated-item-privacy-trait.stderr b/src/test/ui/privacy/associated-item-privacy-trait.stderr index 85db42e9c13a4..3a42415e4746c 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.stderr +++ b/src/test/ui/privacy/associated-item-privacy-trait.stderr @@ -282,7 +282,7 @@ LL | let _: >::AssocTy; LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:119:17 diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr similarity index 85% rename from src/test/ui/span/issue-42234-unknown-receiver-type.stderr rename to src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr index c64c5b1c28f41..278d049224401 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed for `Option<_>` - --> $DIR/issue-42234-unknown-receiver-type.rs:7:7 + --> $DIR/issue-42234-unknown-receiver-type.rs:10:7 | LL | let x: Option<_> = None; | - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified @@ -9,7 +9,7 @@ LL | x.unwrap().method_that_could_exist_on_some_type(); = note: type must be known at this point error[E0282]: type annotations needed - --> $DIR/issue-42234-unknown-receiver-type.rs:13:10 + --> $DIR/issue-42234-unknown-receiver-type.rs:16:10 | LL | .sum::<_>() | ^^^ cannot infer type diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr new file mode 100644 index 0000000000000..8d4ed4aea6a6c --- /dev/null +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr @@ -0,0 +1,21 @@ +error[E0282]: type annotations needed for `Option<_>` + --> $DIR/issue-42234-unknown-receiver-type.rs:10:7 + | +LL | let x: Option<_> = None; + | - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified +LL | x.unwrap().method_that_could_exist_on_some_type(); + | ^^^^^^ cannot infer type for type parameter `T` + | + = note: type must be known at this point + +error[E0282]: type annotations needed + --> $DIR/issue-42234-unknown-receiver-type.rs:16:16 + | +LL | .sum::<_>() + | ^ cannot infer type for type parameter `S` declared on the associated function `sum` + | + = note: type must be known at this point + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs index d3292bbecbaaa..15b00de44b933 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.rs +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs @@ -1,3 +1,6 @@ +// revisions: full generic_arg +#![cfg_attr(generic_arg, feature(generic_arg_infer))] + // When the type of a method call's receiver is unknown, the span should point // to the receiver (and not the entire call, as was previously the case before // the fix of which this tests). diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index c8cdf1a5d2c9c..d5ee717accd26 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -9,7 +9,7 @@ use rustc_hir::{ def::{CtorOf, DefKind, Res}, def_id::LocalDefId, intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -280,52 +280,6 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector { } } -<<<<<<< HEAD -======= -struct LintTyCollector<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - self_ty: Ty<'tcx>, - types_to_lint: Vec, - types_to_skip: Vec, -} - -impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) { - if_chain! { - if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id); - if should_lint_ty(hir_ty, ty, self.self_ty); - then { - self.types_to_lint.push(hir_ty.hir_id); - } else { - self.types_to_skip.push(hir_ty.hir_id); - } - } - - walk_ty(self, hir_ty); - } - - fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { - if_chain! { - if let Some(ty) = self.cx.typeck_results().node_type_opt(inf.hir_id); - if should_lint_ty(&inf.to_ty(), ty, self.self_ty); - then { - self.types_to_lint.push(inf.hir_id); - } else { - self.types_to_skip.push(inf.hir_id); - } - } - - walk_inf(self, inf) - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - ->>>>>>> Add inferred args to typeck fn span_lint(cx: &LateContext<'_>, span: Span) { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index e636038b6e1a5..6ea360a88a63e 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { mut_ty.mutbl.hash(&mut self.s); }, TyKind::Rptr(lifetime, ref mut_ty) => { - self.hash_lifetime(lifetime); + self.hash_lifetime(*lifetime); self.hash_ty(mut_ty.ty); mut_ty.mutbl.hash(&mut self.s); }, @@ -924,7 +924,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { bfn.decl.c_variadic.hash(&mut self.s); }, TyKind::Tup(ty_list) => { - for ty in ty_list { + for ty in *ty_list { self.hash_ty(ty); } }, @@ -933,7 +933,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_generic_args(arg_list); }, TyKind::TraitObject(_, lifetime, _) => { - self.hash_lifetime(lifetime); + self.hash_lifetime(*lifetime); }, TyKind::Typeof(anon_const) => { self.hash_body(anon_const.body); diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr index 54ab04f8c5d38..df0598a58cd36 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr @@ -46,13 +46,13 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&issue --> $DIR/transmute_ptr_to_ref.rs:32:32 | LL | let _: &Foo = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<_>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`) --> $DIR/transmute_ptr_to_ref.rs:34:33 | LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<&u8>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<&_>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) --> $DIR/transmute_ptr_to_ref.rs:38:14