diff options
| author | bors <bors@rust-lang.org> | 2021-01-05 03:06:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-01-05 03:06:32 +0000 |
| commit | f412fb56b8d11c168e7ee49ee74e79c4ab2e5637 (patch) | |
| tree | d18afc92b3a1abecb5bd1c21444e7c6996a7ab28 /compiler | |
| parent | 9919ad6e9ed113557c68c430de2e0f434e4f5b6e (diff) | |
| parent | 9daac58ee9a7be95f14f29b44d0a256669b0419e (diff) | |
| download | rust-f412fb56b8d11c168e7ee49ee74e79c4ab2e5637.tar.gz rust-f412fb56b8d11c168e7ee49ee74e79c4ab2e5637.zip | |
Auto merge of #80708 - JohnTitor:rollup-6esk027, r=JohnTitor
Rollup of 12 pull requests Successful merges: - #80442 (Mention Arc::make_mut and Rc::make_mut in the documentation of Cow) - #80533 (bootstrap: clippy fixes) - #80538 (Add check for `[T;N]`/`usize` mismatch in astconv) - #80612 (Remove reverted change from relnotes) - #80627 (Builder: Warn if test file does not exist) - #80637 (Use Option::filter instead of open-coding it) - #80643 (Move variable into the only branch where it is relevant) - #80656 (Fixed documentation error for `std::hint::spin_loop`) - #80666 (Fix missing link for "fully qualified syntax") - #80672 (./x.py clippy: allow the most noisy lints) - #80677 (doc -- list edit for consistency) - #80696 (make sure that promoteds which fail to evaluate in dead const code behave correctly) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/generics.rs | 92 |
6 files changed, 85 insertions, 68 deletions
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index b24c208c76a..c14165454ed 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -9,6 +9,7 @@ doctest = false [dependencies] rustc_target = { path = "../rustc_target" } +rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ead39d70263..acd254ae85c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -290,6 +290,14 @@ impl GenericArg<'_> { GenericArg::Const(_) => "const", } } + + pub fn to_ord(&self, feats: &rustc_feature::Features) -> ast::ParamKindOrd { + match self { + GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime, + GenericArg::Type(_) => ast::ParamKindOrd::Type, + GenericArg::Const(_) => ast::ParamKindOrd::Const { unordered: feats.const_generics }, + } + } } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 373f0a602c0..e097264ec8a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -43,22 +43,18 @@ impl<'a, 'tcx> FindHirNodeVisitor<'a, 'tcx> { } fn node_ty_contains_target(&mut self, hir_id: HirId) -> Option<Ty<'tcx>> { - let ty_opt = self - .infcx + self.infcx .in_progress_typeck_results - .and_then(|typeck_results| typeck_results.borrow().node_type_opt(hir_id)); - match ty_opt { - Some(ty) => { - let ty = self.infcx.resolve_vars_if_possible(ty); - if ty.walk().any(|inner| { + .and_then(|typeck_results| typeck_results.borrow().node_type_opt(hir_id)) + .map(|ty| self.infcx.resolve_vars_if_possible(ty)) + .filter(|ty| { + ty.walk().any(|inner| { inner == self.target || match (inner.unpack(), self.target.unpack()) { (GenericArgKind::Type(inner_ty), GenericArgKind::Type(target_ty)) => { + use ty::{Infer, TyVar}; match (inner_ty.kind(), target_ty.kind()) { - ( - &ty::Infer(ty::TyVar(a_vid)), - &ty::Infer(ty::TyVar(b_vid)), - ) => self + (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => self .infcx .inner .borrow_mut() @@ -69,14 +65,8 @@ impl<'a, 'tcx> FindHirNodeVisitor<'a, 'tcx> { } _ => false, } - }) { - Some(ty) - } else { - None - } - } - None => None, - } + }) + }) } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index c94893bb3a2..6e381fd2965 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1341,15 +1341,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { return &[]; } - // Do a reverse lookup beforehand to avoid touching the crate_num - // hash map in the loop below. - let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) { - Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)), - Some(None) => return &[], - None => None, - }; + if let Some(def_id) = filter { + // Do a reverse lookup beforehand to avoid touching the crate_num + // hash map in the loop below. + let filter = match self.reverse_translate_def_id(def_id) { + Some(def_id) => (def_id.krate.as_u32(), def_id.index), + None => return &[], + }; - if let Some(filter) = filter { if let Some(impls) = self.trait_impls.get(&filter) { tcx.arena.alloc_from_iter( impls.decode(self).map(|(idx, simplified_self_ty)| { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1fe1400fabe..59a3ac94634 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -801,6 +801,15 @@ impl GenericParamDefKind { GenericParamDefKind::Const => "constant", } } + pub fn to_ord(&self, tcx: TyCtxt<'_>) -> ast::ParamKindOrd { + match self { + GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime, + GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type, + GenericParamDefKind::Const => { + ast::ParamKindOrd::Const { unordered: tcx.features().const_generics } + } + } + } } #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index a3a2b8967c6..1100401ed12 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -11,7 +11,7 @@ use rustc_hir::GenericArg; use rustc_middle::ty::{ self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt, }; -use rustc_session::{lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS, Session}; +use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; use rustc_span::{symbol::kw, MultiSpan, Span}; use smallvec::SmallVec; @@ -20,62 +20,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// Report an error that a generic argument did not match the generic parameter that was /// expected. fn generic_arg_mismatch_err( - sess: &Session, + tcx: TyCtxt<'_>, arg: &GenericArg<'_>, - kind: &'static str, + param: &GenericParamDef, possible_ordering_error: bool, help: Option<&str>, ) { + let sess = tcx.sess; let mut err = struct_span_err!( sess, arg.span(), E0747, "{} provided when a {} was expected", arg.descr(), - kind, + param.kind.descr(), ); - let unordered = sess.features_untracked().const_generics; - let kind_ord = match kind { - "lifetime" => ParamKindOrd::Lifetime, - "type" => ParamKindOrd::Type, - "constant" => ParamKindOrd::Const { unordered }, - // It's more concise to match on the string representation, though it means - // the match is non-exhaustive. - _ => bug!("invalid generic parameter kind {}", kind), - }; - - if let ParamKindOrd::Const { .. } = kind_ord { + if let GenericParamDefKind::Const { .. } = param.kind { if let GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. }) = arg { err.help("const arguments cannot yet be inferred with `_`"); } } - let arg_ord = match arg { - GenericArg::Lifetime(_) => ParamKindOrd::Lifetime, - GenericArg::Type(_) => ParamKindOrd::Type, - GenericArg::Const(_) => ParamKindOrd::Const { unordered }, - }; - - if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })) - && matches!(kind_ord, ParamKindOrd::Const { .. }) - { - let suggestions = vec![ - (arg.span().shrink_to_lo(), String::from("{ ")), - (arg.span().shrink_to_hi(), String::from(" }")), - ]; - err.multipart_suggestion( - "if this generic argument was intended as a const parameter, \ + // Specific suggestion set for diagnostics + match (arg, ¶m.kind) { + ( + GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. }), + GenericParamDefKind::Const { .. }, + ) => { + let suggestions = vec![ + (arg.span().shrink_to_lo(), String::from("{ ")), + (arg.span().shrink_to_hi(), String::from(" }")), + ]; + err.multipart_suggestion( + "if this generic argument was intended as a const parameter, \ try surrounding it with braces:", - suggestions, - Applicability::MaybeIncorrect, - ); + suggestions, + Applicability::MaybeIncorrect, + ); + } + ( + GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }), + GenericParamDefKind::Const { .. }, + ) if tcx.type_of(param.def_id) == tcx.types.usize => { + let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id)); + if let Ok(snippet) = snippet { + err.span_suggestion( + arg.span(), + "array type provided where a `usize` was expected, try", + format!("{{ {} }}", snippet), + Applicability::MaybeIncorrect, + ); + } + } + _ => {} } + let kind_ord = param.kind.to_ord(tcx); + let arg_ord = arg.to_ord(&tcx.features()); + // This note is only true when generic parameters are strictly ordered by their kind. if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal { - let (first, last) = - if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) }; + let (first, last) = if kind_ord < arg_ord { + (param.kind.descr(), arg.descr()) + } else { + (arg.descr(), param.kind.descr()) + }; err.note(&format!("{} arguments must be provided before {} arguments", first, last)); if let Some(help) = help { err.help(help); @@ -203,7 +213,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // We expected a lifetime argument, but got a type or const // argument. That means we're inferring the lifetimes. substs.push(ctx.inferred_kind(None, param, infer_args)); - force_infer_lt = Some(arg); + force_infer_lt = Some((arg, param)); params.next(); } (GenericArg::Lifetime(_), _, ExplicitLateBound::Yes) => { @@ -213,7 +223,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // ignore it. args.next(); } - (_, kind, _) => { + (_, _, _) => { // We expected one kind of parameter, but the user provided // another. This is an error. However, if we already know that // the arguments don't match up with the parameters, we won't issue @@ -256,9 +266,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { param_types_present.dedup(); Self::generic_arg_mismatch_err( - tcx.sess, + tcx, arg, - kind.descr(), + param, !args_iter.clone().is_sorted_by_key(|arg| match arg { GenericArg::Lifetime(_) => ParamKindOrd::Lifetime, GenericArg::Type(_) => ParamKindOrd::Type, @@ -315,9 +325,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { let kind = arg.descr(); assert_eq!(kind, "lifetime"); - let provided = + let (provided_arg, param) = force_infer_lt.expect("lifetimes ought to have been inferred"); - Self::generic_arg_mismatch_err(tcx.sess, provided, kind, false, None); + Self::generic_arg_mismatch_err(tcx, provided_arg, param, false, None); } break; |
