From 9d34bf5c2bb0576197824019e187bbddb187d531 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 24 Apr 2020 22:24:14 +0200 Subject: [PATCH 01/14] impl type_of for const args in ty dependent paths --- src/librustc_middle/query/mod.rs | 15 ++ src/librustc_typeck/collect.rs | 1 + src/librustc_typeck/collect/type_of.rs | 206 ++++++++++++++----------- 3 files changed, 134 insertions(+), 88 deletions(-) diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 2f51b98085b4e..d3511b758fedf 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -89,6 +89,21 @@ rustc_queries! { desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } } + /// Computes the `DefId` of the corresponding const parameter of a const argument. + /// Returns `None` if `def_id` is not a const argument. + /// + /// ```rust + /// let a = foo::<7>(); + /// ^ Calling `const_param_of` for this argument, + /// + /// fn foo() + /// ^ returns this `DefId`. + /// ``` + query const_param_of(key: DefId) -> Option { + cache_on_disk_if { key.is_local() } + desc { |tcx| "computing the const parameter of `{}`", tcx.def_path_str(key) } + } + /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 054165f2b0977..fb9e462893328 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -64,6 +64,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { + const_param_of: type_of::const_param_of, type_of: type_of::type_of, generics_of, predicates_of, diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 3dd9c9c5c39db..0b6a17eb8379d 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -17,6 +17,118 @@ use rustc_trait_selection::traits; use super::ItemCtxt; use super::{bad_placeholder_type, is_suggestable_infer_ty}; +pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + use hir::*; + + // We can just exit here, as `const_param_of` is called for + // all generic arguments, meaning that we would return `None` anyways + // if `const_param_of` is not cached + let hir_id = tcx.hir().as_local_hir_id(def_id.as_local()?); + + if let Node::AnonConst(_) = tcx.hir().get(hir_id) { + let parent_node_id = tcx.hir().get_parent_node(hir_id); + let parent_node = tcx.hir().get(parent_node_id); + + match parent_node { + Node::Expr(&Expr { + kind: + ExprKind::MethodCall(segment, ..) | ExprKind::Path(QPath::TypeRelative(_, segment)), + .. + }) => { + let body_owner = tcx.hir().get_parent_did(parent_node_id); + let tables = tcx.typeck_tables_of(body_owner.to_def_id()); + // This may fail in case the method/path does not actually exist. + // As there is no relevant param for `def_id`, we simply return + // `None` here. + let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?; + let idx = segment + .args + .and_then(|args| { + args.args + .iter() + .filter(|arg| arg.is_const()) + .position(|arg| arg.id() == hir_id) + }) + .unwrap_or_else(|| { + bug!("no arg matching AnonConst in segment"); + }); + + tcx.generics_of(type_dependent_def) + .params + .iter() + .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const)) + .nth(idx) + .map(|param| param.def_id) + } + + Node::Ty(&Ty { kind: TyKind::Path(_), .. }) + | Node::Expr(&Expr { kind: ExprKind::Struct(..), .. }) + | Node::Expr(&Expr { kind: ExprKind::Path(_), .. }) + | Node::TraitRef(..) => { + let path = match parent_node { + Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. }) + | Node::TraitRef(&TraitRef { path, .. }) => &*path, + Node::Expr(&Expr { + kind: + ExprKind::Path(QPath::Resolved(_, path)) + | ExprKind::Struct(&QPath::Resolved(_, path), ..), + .. + }) => { + let body_owner = tcx.hir().get_parent_did(parent_node_id); + let _tables = tcx.typeck_tables_of(body_owner.to_def_id()); + &*path + } + _ => span_bug!(DUMMY_SP, "unexpected const parent path {:?}", parent_node), + }; + + // We've encountered an `AnonConst` in some path, so we need to + // figure out which generic parameter it corresponds to and return + // the relevant type. + + let (arg_index, segment) = path + .segments + .iter() + .filter_map(|seg| seg.args.map(|args| (args.args, seg))) + .find_map(|(args, seg)| { + args.iter() + .filter(|arg| arg.is_const()) + .position(|arg| arg.id() == hir_id) + .map(|index| (index, seg)) + }) + .unwrap_or_else(|| { + bug!("no arg matching AnonConst in path"); + }); + + // Try to use the segment resolution if it is valid, otherwise we + // default to the path resolution. + let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); + let generics = match res { + Res::Def(DefKind::Ctor(..), def_id) => { + tcx.generics_of(tcx.parent(def_id).unwrap()) + } + Res::Def(_, def_id) => tcx.generics_of(def_id), + res => span_bug!( + DUMMY_SP, + "unexpected anon const res {:?} in path: {:?}", + res, + path, + ), + }; + + generics + .params + .iter() + .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const)) + .nth(arg_index) + .map(|param| param.def_id) + } + _ => return None, + } + } else { + None + } +} + pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { use rustc_hir::*; @@ -187,6 +299,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } Node::AnonConst(_) => { + if let Some(param) = tcx.const_param_of(def_id) { + // We defer to `type_of` of the corresponding parameter + // for generic arguments. + return tcx.type_of(param); + } + let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); match parent_node { Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) @@ -203,94 +321,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .discr_type() .to_ty(tcx), - Node::Ty(&Ty { kind: TyKind::Path(_), .. }) - | Node::Expr(&Expr { kind: ExprKind::Struct(..) | ExprKind::Path(_), .. }) - | Node::TraitRef(..) => { - let path = match parent_node { - Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. }) - | Node::Expr(&Expr { - kind: - ExprKind::Path(QPath::Resolved(_, path)) - | ExprKind::Struct(&QPath::Resolved(_, path), ..), - .. - }) - | Node::TraitRef(&TraitRef { path, .. }) => &*path, - _ => { - return tcx.ty_error_with_message( - DUMMY_SP, - &format!("unexpected const parent path {:?}", parent_node), - ); - } - }; - - // We've encountered an `AnonConst` in some path, so we need to - // figure out which generic parameter it corresponds to and return - // the relevant type. - - let (arg_index, segment) = path - .segments - .iter() - .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg))) - .find_map(|(args, seg)| { - args.iter() - .filter(|arg| arg.is_const()) - .enumerate() - .filter(|(_, arg)| arg.id() == hir_id) - .map(|(index, _)| (index, seg)) - .next() - }) - .unwrap_or_else(|| { - bug!("no arg matching AnonConst in path"); - }); - - // Try to use the segment resolution if it is valid, otherwise we - // default to the path resolution. - let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); - let generics = match res { - Res::Def(DefKind::Ctor(..), def_id) => { - tcx.generics_of(tcx.parent(def_id).unwrap()) - } - Res::Def(_, def_id) => tcx.generics_of(def_id), - res => { - return tcx.ty_error_with_message( - DUMMY_SP, - &format!( - "unexpected anon const res {:?} in path: {:?}", - res, path, - ), - ); - } - }; - - let ty = generics - .params - .iter() - .filter(|param| { - if let ty::GenericParamDefKind::Const = param.kind { - true - } else { - false - } - }) - .nth(arg_index) - .map(|param| tcx.type_of(param.def_id)); - - if let Some(ty) = ty { - ty - } else { - // This is no generic parameter associated with the arg. This is - // probably from an extra arg where one is not needed. - tcx.ty_error_with_message( - DUMMY_SP, - &format!( - "missing generic parameter for `AnonConst`, \ - parent: {:?}, res: {:?}", - parent_node, res - ), - ) - } - } - x => tcx.ty_error_with_message( DUMMY_SP, &format!("unexpected const parent in type_of_def_id(): {:?}", x), From 71866285d23dbc268c9c2e6b44a89fdbdfed0229 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 1 May 2020 16:04:55 +0200 Subject: [PATCH 02/14] add fn enclosing_body_owner to hir --- src/librustc_typeck/collect/type_of.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 0b6a17eb8379d..e9e6a0731282f 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -35,7 +35,7 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { ExprKind::MethodCall(segment, ..) | ExprKind::Path(QPath::TypeRelative(_, segment)), .. }) => { - let body_owner = tcx.hir().get_parent_did(parent_node_id); + let body_owner = tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id)); let tables = tcx.typeck_tables_of(body_owner.to_def_id()); // This may fail in case the method/path does not actually exist. // As there is no relevant param for `def_id`, we simply return @@ -74,7 +74,7 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { | ExprKind::Struct(&QPath::Resolved(_, path), ..), .. }) => { - let body_owner = tcx.hir().get_parent_did(parent_node_id); + let body_owner = tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id)); let _tables = tcx.typeck_tables_of(body_owner.to_def_id()); &*path } From c625d2c6a898428473d8a77e9a83e47b44d9b8ca Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 4 May 2020 11:23:55 +0200 Subject: [PATCH 03/14] propagate param def id during typeck --- .../debuginfo/metadata.rs | 2 +- .../back/symbol_export.rs | 2 +- src/librustc_codegen_ssa/mir/constant.rs | 4 +- src/librustc_infer/infer/mod.rs | 4 +- src/librustc_infer/traits/util.rs | 4 +- src/librustc_interface/passes.rs | 4 +- .../rmeta/decoder/cstore_impl.rs | 6 ++ src/librustc_metadata/rmeta/encoder.rs | 23 +++-- src/librustc_middle/dep_graph/dep_node.rs | 37 ++++++++ src/librustc_middle/mir/interpret/queries.rs | 4 +- src/librustc_middle/mir/mono.rs | 2 +- src/librustc_middle/query/mod.rs | 56 +++++------ src/librustc_middle/ty/instance.rs | 57 ++++++++--- src/librustc_middle/ty/mod.rs | 85 +++++++++++++++-- src/librustc_middle/ty/print/pretty.rs | 16 ++-- src/librustc_middle/ty/query/keys.rs | 32 +++++++ src/librustc_middle/ty/query/mod.rs | 2 +- src/librustc_middle/ty/relate.rs | 8 +- src/librustc_middle/ty/structural_impls.rs | 26 ++--- src/librustc_middle/ty/sty.rs | 27 ++++-- .../diagnostics/conflict_errors.rs | 19 ++-- .../borrow_check/diagnostics/mod.rs | 16 +++- .../diagnostics/mutability_errors.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 44 ++++----- src/librustc_mir/borrow_check/nll.rs | 8 +- .../borrow_check/type_check/input_output.rs | 3 +- .../borrow_check/type_check/mod.rs | 12 ++- .../borrow_check/universal_regions.rs | 49 +++++----- src/librustc_mir/const_eval/eval_queries.rs | 22 ++--- src/librustc_mir/const_eval/machine.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 31 +++--- src/librustc_mir/interpret/operand.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/interpret/validity.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 8 +- src/librustc_mir/monomorphize/partitioning.rs | 4 +- src/librustc_mir/shim.rs | 3 +- .../transform/check_consts/qualifs.rs | 6 +- .../transform/check_consts/validation.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 27 +++--- src/librustc_mir/transform/inline.rs | 4 +- src/librustc_mir/transform/mod.rs | 94 +++++++++++-------- src/librustc_mir/transform/promote_consts.rs | 16 ++-- src/librustc_mir/util/graphviz.rs | 2 +- src/librustc_mir/util/pretty.rs | 7 +- src/librustc_mir_build/build/mod.rs | 14 +-- src/librustc_mir_build/hair/cx/expr.rs | 16 ++-- src/librustc_mir_build/hair/cx/mod.rs | 22 +++-- src/librustc_mir_build/hair/pattern/mod.rs | 3 +- src/librustc_passes/intrinsicck.rs | 2 +- src/librustc_passes/liveness.rs | 2 +- src/librustc_privacy/lib.rs | 6 +- src/librustc_save_analysis/dump_visitor.rs | 2 +- .../traits/error_reporting/suggestions.rs | 4 +- .../traits/fulfill.rs | 8 +- .../traits/select/mod.rs | 14 +-- src/librustc_trait_selection/traits/wf.rs | 10 +- src/librustc_ty/instance.rs | 20 ++-- src/librustc_typeck/astconv.rs | 10 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/mod.rs | 45 +++++++-- src/librustc_typeck/check/wfcheck.rs | 7 +- src/librustc_typeck/collect.rs | 4 +- src/librustc_typeck/collect/type_of.rs | 29 ++++-- src/librustc_typeck/lib.rs | 2 + 65 files changed, 657 insertions(+), 355 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 8a957a729fb68..004747d2a222a 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1295,7 +1295,7 @@ fn generator_layout_and_saved_local_names( tcx: TyCtxt<'tcx>, def_id: DefId, ) -> (&'tcx GeneratorLayout<'tcx>, IndexVec>) { - let body = tcx.optimized_mir(def_id); + let body = tcx.optimized_mir(tcx.with_opt_param(def_id)); let generator_layout = body.generator_layout.as_ref().unwrap(); let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys); diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 217ad57ddc9c3..62442f0c87fcb 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -249,7 +249,7 @@ fn exported_symbols_provider_local( } match *mono_item { - MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => { + MonoItem::Fn(Instance { def: InstanceDef::Item(def_id, _), substs }) => { if substs.non_erasable_generics().next().is_some() { let symbol = ExportedSymbol::Generic(def_id, substs); symbols.push((symbol, SymbolExportLevel::Rust)); diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 11ec62f96ed38..4943e279c7e05 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match self.monomorphize(&constant.literal).val { - ty::ConstKind::Unevaluated(def_id, substs, promoted) => self + ty::ConstKind::Unevaluated(def, substs, promoted) => self .cx .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None) + .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) .map_err(|err| { if promoted.is_none() { self.cx diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index 8f8ce03d638c0..7b118baf014bb 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -1538,7 +1538,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - def_id: DefId, + def: ty::WithOptParam, substs: SubstsRef<'tcx>, promoted: Option, span: Option, @@ -1549,7 +1549,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (param_env, substs) = canonical.value; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. - self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span) + self.tcx.const_eval_resolve(param_env, def, substs, promoted, span) } /// If `typ` is a type variable of some kind, resolve it one level diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index 4ae7e417a8f67..233f478881cc8 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -40,8 +40,8 @@ pub fn anonymize_predicate<'tcx>( ty::PredicateKind::Subtype(tcx.anonymize_late_bound_regions(data)) } - &ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - ty::PredicateKind::ConstEvaluatable(def_id, substs) + &ty::PredicateKind::ConstEvaluatable(def, substs) => { + ty::PredicateKind::ConstEvaluatable(def, substs) } ty::PredicateKind::ConstEquate(c1, c2) => ty::PredicateKind::ConstEquate(c1, c2), diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index e9a4119f4a333..a6e43266f1d05 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -848,7 +848,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { }); sess.time("MIR_borrow_checking", || { - tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); + tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(tcx.with_opt_param(def_id))); }); sess.time("MIR_effect_checking", || { @@ -856,7 +856,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { mir::transform::check_unsafety::check_unsafety(tcx, def_id); if tcx.hir().body_const_context(def_id).is_some() { - tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); + tcx.ensure().mir_drops_elaborated_and_const_checked(tcx.with_opt_param(def_id)); } } }); diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 1b168bf01178c..b98e0de6f95cb 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -75,6 +75,12 @@ impl IntoArgs for DefId { } } +impl IntoArgs for ty::WithOptParam { + fn into_args(self) -> (DefId, DefId) { + (self.did, self.param_did.unwrap_or(self.did)) + } +} + impl IntoArgs for CrateNum { fn into_args(self) -> (DefId, DefId) { (self.as_def_id(), self.as_def_id()) diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index cdc8b5e90a642..dcad6933ee630 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -939,7 +939,8 @@ impl EncodeContext<'tcx> { record!(self.tables.kind[def_id] <- match impl_item.kind { ty::AssocKind::Const => { if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind { - let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id); + let tcx = self.tcx.at(ast_item.span); + let qualifs = tcx.mir_const_qualif(tcx.with_opt_param(def_id)); EntryKind::AssocConst( container, @@ -1021,14 +1022,18 @@ impl EncodeContext<'tcx> { fn encode_optimized_mir(&mut self, def_id: LocalDefId) { debug!("EntryBuilder::encode_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id)); + record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir( + self.tcx.with_opt_param(def_id.to_def_id()) + )); } } fn encode_promoted_mir(&mut self, def_id: LocalDefId) { debug!("EncodeContext::encode_promoted_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id)); + record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir( + self.tcx.with_opt_param(def_id.to_def_id()) + )); } } @@ -1086,7 +1091,8 @@ impl EncodeContext<'tcx> { hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic, hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic, hir::ItemKind::Const(_, body_id) => { - let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id); + let tcx = self.tcx.at(item.span); + let qualifs = tcx.mir_const_qualif(tcx.with_opt_param(def_id)); EntryKind::Const( qualifs, self.encode_rendered_const_for_body(body_id) @@ -1328,7 +1334,7 @@ impl EncodeContext<'tcx> { // NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic, // including on the signature, which is inferred in `typeck_tables_of. let hir_id = self.tcx.hir().as_local_hir_id(def_id); - let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id); + let ty = self.tcx.typeck_tables_of(self.tcx.with_opt_param(def_id)).node_type(hir_id); record!(self.tables.kind[def_id.to_def_id()] <- match ty.kind { ty::Generator(..) => { @@ -1357,7 +1363,7 @@ impl EncodeContext<'tcx> { let id = self.tcx.hir().as_local_hir_id(def_id); let body_id = self.tcx.hir().body_owned_by(id); let const_data = self.encode_rendered_const_for_body(body_id); - let qualifs = self.tcx.mir_const_qualif(def_id); + let qualifs = self.tcx.mir_const_qualif(self.tcx.with_opt_param(def_id.to_def_id())); record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data)); record!(self.tables.visibility[def_id.to_def_id()] <- ty::Visibility::Public); @@ -1744,8 +1750,9 @@ struct PrefetchVisitor<'tcx> { impl<'tcx> PrefetchVisitor<'tcx> { fn prefetch_mir(&self, def_id: LocalDefId) { if self.mir_keys.contains(&def_id) { - self.tcx.ensure().optimized_mir(def_id); - self.tcx.ensure().promoted_mir(def_id); + let def = self.tcx.with_opt_param(def_id).to_global(); + self.tcx.ensure().optimized_mir(def); + self.tcx.ensure().promoted_mir(def); } } } diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs index b14f17dee6060..2cbdb508e4d09 100644 --- a/src/librustc_middle/dep_graph/dep_node.rs +++ b/src/librustc_middle/dep_graph/dep_node.rs @@ -361,6 +361,43 @@ impl<'tcx> DepNodeParams> for CrateNum { } } +impl<'tcx> DepNodeParams> for ty::WithOptParam { + #[inline] + fn can_reconstruct_query_key() -> bool { + true + } + + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + tcx.def_path_hash(self.did).0 + } + + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + tcx.def_path_str(self.did) + } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|def_id| tcx.with_opt_param(def_id)) + } +} +impl<'tcx> DepNodeParams> for ty::WithOptParam { + #[inline] + fn can_reconstruct_query_key() -> bool { + true + } + + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + tcx.def_path_hash(self.did.to_def_id()).0 + } + + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + tcx.def_path_str(self.did.to_def_id()) + } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|def_id| tcx.with_opt_param(def_id.expect_local())) + } +} + impl<'tcx> DepNodeParams> for (DefId, DefId) { #[inline] fn can_reconstruct_query_key() -> bool { diff --git a/src/librustc_middle/mir/interpret/queries.rs b/src/librustc_middle/mir/interpret/queries.rs index a7953f0f900fb..bbaead535f6c7 100644 --- a/src/librustc_middle/mir/interpret/queries.rs +++ b/src/librustc_middle/mir/interpret/queries.rs @@ -34,12 +34,12 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_resolve( self, param_env: ty::ParamEnv<'tcx>, - def_id: DefId, + def: ty::WithOptParam, substs: SubstsRef<'tcx>, promoted: Option, span: Option, ) -> ConstEvalResult<'tcx> { - match ty::Instance::resolve(self, param_env, def_id, substs) { + match ty::Instance::resolve_const_arg(self, param_env, def, substs) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted }; self.const_eval_global_id(param_env, cid, span) diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index f1c1b962ab997..c1df5bef2467e 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -346,7 +346,7 @@ impl<'tcx> CodegenUnit<'tcx> { // instances into account. The others don't matter for // the codegen tests and can even make item order // unstable. - InstanceDef::Item(def_id) => { + InstanceDef::Item(def_id, _) => { def_id.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id)) } InstanceDef::VtableShim(..) diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index d3511b758fedf..14f9232169a57 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -94,10 +94,10 @@ rustc_queries! { /// /// ```rust /// let a = foo::<7>(); - /// ^ Calling `const_param_of` for this argument, + /// // ^ Calling `const_param_of` for this argument, /// /// fn foo() - /// ^ returns this `DefId`. + /// // ^ returns this `DefId`. /// ``` query const_param_of(key: DefId) -> Option { cache_on_disk_if { key.is_local() } @@ -200,50 +200,50 @@ rustc_queries! { /// Maps DefId's that have an associated `mir::Body` to the result /// of the MIR const-checking pass. This is the set of qualifs in /// the final value of a `const`. - query mir_const_qualif(key: DefId) -> mir::ConstQualifs { - desc { |tcx| "const checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + query mir_const_qualif(key: ty::WithOptParam) -> mir::ConstQualifs { + desc { |tcx| "const checking `{}`", tcx.def_path_str(key.did) } + cache_on_disk_if { key.did.is_local() } } /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. - query mir_built(key: LocalDefId) -> Steal> { + query mir_built(key: ty::WithOptParam) -> Steal> { storage(ArenaCacheSelector<'tcx>) - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } } /// Fetch the MIR for a given `DefId` up till the point where it is /// ready for const qualification. /// /// See the README for the `mir` module for details. - query mir_const(key: DefId) -> Steal> { - desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key) } + query mir_const(key: ty::WithOptParam) -> Steal> { + desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key.did) } storage(ArenaCacheSelector<'tcx>) no_hash } - query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> Steal> { + query mir_drops_elaborated_and_const_checked(key: ty::WithOptParam) -> Steal> { storage(ArenaCacheSelector<'tcx>) no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) } } - query mir_validated(key: LocalDefId) -> + query mir_validated(key: ty::WithOptParam) -> ( Steal>, Steal>> ) { storage(ArenaCacheSelector<'tcx>) no_hash - desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "processing `{}`", tcx.def_path_str(key.did.to_def_id()) } } /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - query optimized_mir(key: DefId) -> mir::Body<'tcx> { - desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) } + query optimized_mir(key: ty::WithOptParam) -> mir::Body<'tcx> { + desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key.did) } storage(ArenaCacheSelector<'tcx>) - cache_on_disk_if { key.is_local() } + cache_on_disk_if { key.did.is_local() } } query coverage_data(key: DefId) -> mir::CoverageData { @@ -252,10 +252,10 @@ rustc_queries! { cache_on_disk_if { key.is_local() } } - query promoted_mir(key: DefId) -> IndexVec> { - desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } + query promoted_mir(key: ty::WithOptParam) -> IndexVec> { + desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key.did) } storage(ArenaCacheSelector<'tcx>) - cache_on_disk_if { key.is_local() } + cache_on_disk_if { key.did.is_local() } } } @@ -465,8 +465,8 @@ rustc_queries! { TypeChecking { /// The result of unsafety-checking this `DefId`. - query unsafety_check_result(key: LocalDefId) -> mir::UnsafetyCheckResult { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + query unsafety_check_result(key: ty::WithOptParam) -> mir::UnsafetyCheckResult { + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.did.to_def_id()) } cache_on_disk_if { true } storage(ArenaCacheSelector<'tcx>) } @@ -546,8 +546,8 @@ rustc_queries! { desc { "type-checking all item bodies" } } - query typeck_tables_of(key: LocalDefId) -> &'tcx ty::TypeckTables<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + query typeck_tables_of(key: ty::WithOptParam) -> &'tcx ty::TypeckTables<'tcx> { + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.did.to_def_id()) } cache_on_disk_if { true } } query diagnostic_only_typeck_tables_of(key: LocalDefId) -> &'tcx ty::TypeckTables<'tcx> { @@ -583,11 +583,11 @@ rustc_queries! { BorrowChecking { /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. - query mir_borrowck(key: LocalDefId) -> mir::BorrowCheckResult<'tcx> { + query mir_borrowck(key: ty::WithOptParam) -> mir::BorrowCheckResult<'tcx> { storage(ArenaCacheSelector<'tcx>) - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.did.to_def_id()) } cache_on_disk_if(tcx, opt_result) { - tcx.is_closure(key.to_def_id()) + tcx.is_closure(key.did.to_def_id()) || opt_result.map_or(false, |r| !r.concrete_opaque_types.is_empty()) } } @@ -1449,9 +1449,9 @@ rustc_queries! { /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause query resolve_instance( - key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)> + key: ty::ParamEnvAnd<'tcx, (ty::WithOptParam, SubstsRef<'tcx>)> ) -> Result>, ErrorReported> { - desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } + desc { "resolving instance `{}`", ty::Instance::new(key.value.0.did, key.value.1) } } } } diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs index d628d6783d5b0..f7d6822037e2a 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/src/librustc_middle/ty/instance.rs @@ -29,7 +29,7 @@ pub enum InstanceDef<'tcx> { /// - `fn` items /// - closures /// - generators - Item(DefId), + Item(ty::WithOptParam), /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI). /// @@ -160,7 +160,7 @@ impl<'tcx> Instance<'tcx> { self.substs.non_erasable_generics().next()?; match self.def { - InstanceDef::Item(def_id) => tcx + InstanceDef::Item(def_id, _) => tcx .upstream_monomorphizations_for(def_id) .and_then(|monos| monos.get(&self.substs).cloned()), InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs), @@ -173,7 +173,7 @@ impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(&self) -> DefId { match *self { - InstanceDef::Item(def_id) + InstanceDef::Item(def_id, _) | InstanceDef::VtableShim(def_id) | InstanceDef::ReifyShim(def_id) | InstanceDef::FnPtrShim(def_id, _) @@ -185,6 +185,15 @@ impl<'tcx> InstanceDef<'tcx> { } } + #[inline] + pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { + ty::WithOptParam { + did: self.def_id(), + param_did: if let InstanceDef::Item(_, param_did) = *self { param_did } else { None } + .or_else(|| tcx.const_param_of(self.def_id())), + } + } + #[inline] pub fn attrs(&self, tcx: TyCtxt<'tcx>) -> ty::Attributes<'tcx> { tcx.get_attrs(self.def_id()) @@ -198,7 +207,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; let def_id = match *self { - ty::InstanceDef::Item(def_id) => def_id, + ty::InstanceDef::Item(def_id, _) => def_id, ty::InstanceDef::DropGlue(_, Some(_)) => return false, _ => return true, }; @@ -244,7 +253,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { - InstanceDef::Item(def_id) => { + InstanceDef::Item(def_id, _) => { tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } _ => false, @@ -262,7 +271,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { })?; match self.def { - InstanceDef::Item(_) => Ok(()), + InstanceDef::Item(_, _) => Ok(()), InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"), InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), @@ -276,14 +285,14 @@ impl<'tcx> fmt::Display for Instance<'tcx> { } impl<'tcx> Instance<'tcx> { - pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> { + pub fn new(did: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> { assert!( !substs.has_escaping_bound_vars(), "substs of instance {:?} not normalized for codegen: {:?}", - def_id, + did, substs ); - Instance { def: InstanceDef::Item(def_id), substs } + Instance { def: InstanceDef::Item(did, None), substs } } pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { @@ -295,6 +304,28 @@ impl<'tcx> Instance<'tcx> { self.def.def_id() } + #[inline] + pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { + self.def.with_opt_param(tcx) + } + + /// Identical to `resolve`, but may also take an optional `param_def_id` for + /// generic const arguments. + pub fn resolve_const_arg( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + def: ty::WithOptParam, + substs: SubstsRef<'tcx>, + ) -> Result>, ErrorReported> { + // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)` + // below is more likely to ignore the bounds in scope (e.g. if the only + // generic parameters mentioned by `substs` were lifetime ones). + let substs = tcx.erase_regions(&substs); + + // FIXME(eddyb) should this always use `param_env.with_reveal_all()`? + tcx.resolve_instance(tcx.erase_regions(¶m_env.and((def, substs)))) + } + /// Resolves a `(def_id, substs)` pair to an (optional) instance -- most commonly, /// this is used to find the precise code that will run for a trait method invocation, /// if known. @@ -333,7 +364,9 @@ impl<'tcx> Instance<'tcx> { let substs = tcx.erase_regions(&substs); // FIXME(eddyb) should this always use `param_env.with_reveal_all()`? - tcx.resolve_instance(tcx.erase_regions(¶m_env.and((def_id, substs)))) + tcx.resolve_instance( + tcx.erase_regions(¶m_env.and((tcx.with_opt_param(def_id), substs))), + ) } pub fn resolve_for_fn_ptr( @@ -345,7 +378,7 @@ impl<'tcx> Instance<'tcx> { debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| { match resolved.def { - InstanceDef::Item(def_id) if resolved.def.requires_caller_location(tcx) => { + InstanceDef::Item(def_id, _) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); resolved.def = InstanceDef::ReifyShim(def_id); } @@ -443,7 +476,7 @@ impl<'tcx> Instance<'tcx> { | InstanceDef::DropGlue(..) // FIXME(#69925): `FnPtrShim` should be in the other branch. | InstanceDef::FnPtrShim(..) - | InstanceDef::Item(_) + | InstanceDef::Item(_, _) | InstanceDef::Intrinsic(..) | InstanceDef::ReifyShim(..) | InstanceDef::Virtual(..) diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 6b7940ed7abcc..4d1e8ab33c7d0 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -14,6 +14,7 @@ use crate::mir::Body; use crate::mir::GeneratorLayout; use crate::traits::{self, Reveal}; use crate::ty; +use crate::ty::query::IntoQueryParam; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; use rustc_ast::ast; @@ -1094,7 +1095,7 @@ pub enum PredicateKind<'tcx> { Subtype(PolySubtypePredicate<'tcx>), /// Constant initializer must evaluate successfully. - ConstEvaluatable(DefId, SubstsRef<'tcx>), + ConstEvaluatable(ty::WithOptParam, SubstsRef<'tcx>), /// Constants must be equal. The first component is the const that is expected. ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>), @@ -1208,8 +1209,8 @@ impl<'tcx> Predicate<'tcx> { &PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { PredicateKind::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind) } - &PredicateKind::ConstEvaluatable(def_id, const_substs) => { - PredicateKind::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)) + &PredicateKind::ConstEvaluatable(def, const_substs) => { + PredicateKind::ConstEvaluatable(def, const_substs.subst(tcx, substs)) } PredicateKind::ConstEquate(c1, c2) => { PredicateKind::ConstEquate(c1.subst(tcx, substs), c2.subst(tcx, substs)) @@ -1565,6 +1566,78 @@ pub type PlaceholderType = Placeholder; pub type PlaceholderConst = Placeholder; +/// A `DefId` which is bundled with its corresponding generic parameter +/// in case `did` is a const argument. +/// +/// This is used to prevent cycle errors during typeck +/// as `type_of(const_arg)` depends on `typeck_tables_of(owning_body)` +/// which once again requires the type of its generic arguments. +/// +/// Luckily we only need to deal with const arguments once we +/// know their corresponding parameters. We (ab)use this by +/// calling `type_of(param_did)` for these arguments. +#[derive(Copy, Clone, Debug, Hash, HashStable, TypeFoldable, RustcEncodable, RustcDecodable)] +pub struct WithOptParam { + pub did: T, + /// The `DefId` of the corresponding generic paramter in case `did` is + /// a const argument. + /// + /// This must always be equal to `tcx.const_param_of(did)`. + pub param_did: Option, +} + +// We manually implement comparisions as the `param_did` can be ignored. +impl PartialEq for WithOptParam { + fn eq(&self, other: &Self) -> bool { + self.did == other.did + } +} + +impl Eq for WithOptParam {} + +impl PartialOrd for WithOptParam { + fn partial_cmp(&self, other: &Self) -> Option { + self.did.partial_cmp(&other.did) + } +} + +impl Ord for WithOptParam { + fn cmp(&self, other: &Self) -> Ordering { + self.did.cmp(&other.did) + } +} + +impl<'tcx> TyCtxt<'tcx> { + pub fn with_opt_param + Copy>(self, did: T) -> WithOptParam { + WithOptParam { did, param_did: self.const_param_of(did) } + } +} + +impl> WithOptParam { + pub fn ty_def_id(self) -> DefId { + self.param_did.unwrap_or(self.did.into_query_param()) + } +} + +impl WithOptParam { + #[inline] + pub fn as_local(self) -> Option> { + Some(WithOptParam { did: self.did.as_local()?, param_did: self.param_did }) + } + + #[inline] + pub fn expect_local(self) -> WithOptParam { + WithOptParam { did: self.did.expect_local(), param_did: self.param_did } + } +} + +impl WithOptParam { + #[inline] + pub fn to_global(self) -> WithOptParam { + WithOptParam { did: self.did.to_def_id(), param_did: self.param_did } + } +} + /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. @@ -2566,7 +2639,7 @@ pub enum ImplOverlapKind { impl<'tcx> TyCtxt<'tcx> { pub fn body_tables(self, body: hir::BodyId) -> &'tcx TypeckTables<'tcx> { - self.typeck_tables_of(self.hir().body_owner_def_id(body)) + self.typeck_tables_of(self.with_opt_param(self.hir().body_owner_def_id(body))) } /// Returns an iterator of the `DefId`s for all body-owners in this @@ -2737,7 +2810,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { match instance { - ty::InstanceDef::Item(did) => self.optimized_mir(did), + ty::InstanceDef::Item(_, _) => self.optimized_mir(instance.with_opt_param(self)), ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::Intrinsic(..) @@ -2769,7 +2842,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> { - self.optimized_mir(def_id).generator_layout.as_ref().unwrap() + self.optimized_mir(self.with_opt_param(def_id)).generator_layout.as_ref().unwrap() } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 1a08639a533d5..930f7dbd24085 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -884,18 +884,18 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(did, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs, promoted) => { if let Some(promoted) = promoted { - p!(print_value_path(did, substs)); + p!(print_value_path(def.did, substs)); p!(write("::{:?}", promoted)); } else { - match self.tcx().def_kind(did) { + match self.tcx().def_kind(def.did) { DefKind::Static | DefKind::Const | DefKind::AssocConst => { - p!(print_value_path(did, substs)) + p!(print_value_path(def.did, substs)) } _ => { - if did.is_local() { - let span = self.tcx().def_span(did); + if def.did.is_local() { + let span = self.tcx().def_span(def.did); if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { p!(write("{}", snip)) @@ -2049,9 +2049,9 @@ define_print_and_forward_display! { print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } - &ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + &ty::PredicateKind::ConstEvaluatable(def, substs) => { p!(write("the constant `"), - print_value_path(def_id, substs), + print_value_path(def.did, substs), write("` can be evaluated")) } ty::PredicateKind::ConstEquate(c1, c2) => { diff --git a/src/librustc_middle/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs index 4acf766f033d8..6b4bfadfb96cf 100644 --- a/src/librustc_middle/ty/query/keys.rs +++ b/src/librustc_middle/ty/query/keys.rs @@ -127,6 +127,27 @@ impl Key for (DefId, LocalDefId) { } } +impl Key for ty::WithOptParam { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + self.did.krate + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.did.default_span(tcx) + } +} +impl Key for ty::WithOptParam { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.did.default_span(tcx) + } +} + impl Key for (CrateNum, DefId) { type CacheSelector = DefaultCacheSelector; @@ -307,3 +328,14 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) { DUMMY_SP } } + +impl<'tcx> Key for (ty::WithOptParam, SubstsRef<'tcx>) { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + self.0.did.krate + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.0.did) + } +} diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs index 35d19b7603faf..f000ddadb20a5 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/src/librustc_middle/ty/query/mod.rs @@ -216,4 +216,4 @@ mod sealed { } } -use sealed::IntoQueryParam; +pub(crate) use sealed::IntoQueryParam; diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index 14cddd11c438d..1a51080d2deac 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -599,12 +599,12 @@ pub fn super_relate_consts>( // FIXME(const_generics): this is wrong, as it is a projection ( - ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted), - ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted), - ) if a_def_id == b_def_id && a_promoted == b_promoted => { + ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted), + ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted), + ) if a_def == b_def && a_promoted == b_promoted => { let substs = relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?; - Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted)) + Ok(ty::ConstKind::Unevaluated(a_def, &substs, a_promoted)) } _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), }; diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index f736037b5c15a..451a8a7760d05 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -243,8 +243,8 @@ impl fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + ty::PredicateKind::ConstEvaluatable(def, substs) => { + write!(f, "ConstEvaluatable({:?}, {:?})", def, substs) } ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), } @@ -501,8 +501,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { ty::PredicateKind::ObjectSafe(trait_def_id) => { Some(ty::PredicateKind::ObjectSafe(trait_def_id)) } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - tcx.lift(&substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs)) + ty::PredicateKind::ConstEvaluatable(def, substs) => { + tcx.lift(&substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def, substs)) } ty::PredicateKind::ConstEquate(c1, c2) => { tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) @@ -670,7 +670,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { type Lifted = ty::InstanceDef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)), + ty::InstanceDef::Item(did, param_did) => Some(ty::InstanceDef::Item(did, param_did)), ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)), ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)), ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), @@ -842,7 +842,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { Self { substs: self.substs.fold_with(folder), def: match self.def { - Item(did) => Item(did.fold_with(folder)), + // We don't fold the param `DefId` here, + // as it should only be used for `type_of`. + Item(did, param_did) => Item(did.fold_with(folder), param_did), VtableShim(did) => VtableShim(did.fold_with(folder)), ReifyShim(did) => ReifyShim(did.fold_with(folder)), Intrinsic(did) => Intrinsic(did.fold_with(folder)), @@ -861,9 +863,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { use crate::ty::InstanceDef::*; self.substs.visit_with(visitor) || match self.def { - Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { - did.visit_with(visitor) - } + Item(did, _) + | VtableShim(did) + | ReifyShim(did) + | Intrinsic(did) + | Virtual(did, _) => did.visit_with(visitor), FnPtrShim(did, ty) | CloneShim(did, ty) => { did.visit_with(visitor) || ty.visit_with(visitor) } @@ -1067,8 +1071,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(did, substs, promoted) => { - ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted) + ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs.fold_with(folder), promoted) } ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 1d680c3563675..fa67c9d051d32 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -2215,21 +2215,28 @@ impl<'tcx> Const<'tcx> { /// Literals and const generic parameters are eagerly converted to a constant, everything else /// becomes `Unevaluated`. pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self { - debug!("Const::from_anon_const(id={:?})", def_id); + Self::const_arg_from_anon_const(tcx, tcx.with_opt_param(def_id)) + } + + pub fn const_arg_from_anon_const( + tcx: TyCtxt<'tcx>, + def: ty::WithOptParam, + ) -> &'tcx Self { + debug!("Const::from_anon_const(def={:?})", def); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); let body_id = match tcx.hir().get(hir_id) { hir::Node::AnonConst(ac) => ac.body, _ => span_bug!( - tcx.def_span(def_id.to_def_id()), + tcx.def_span(def.did.to_def_id()), "from_anon_const can only process anonymous constants" ), }; let expr = &tcx.hir().body(body_id).value; - let ty = tcx.type_of(def_id.to_def_id()); + let ty = tcx.type_of(def.ty_def_id()); let lit_input = match expr.kind { hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), @@ -2276,8 +2283,8 @@ impl<'tcx> Const<'tcx> { ty::ConstKind::Param(ty::ParamConst::new(index, name)) } _ => ty::ConstKind::Unevaluated( - def_id.to_def_id(), - InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), + def.to_global(), + InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), None, ), }; @@ -2345,7 +2352,7 @@ impl<'tcx> Const<'tcx> { /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the /// unevaluated constant. pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { - if let ConstKind::Unevaluated(did, substs, promoted) = self.val { + if let ConstKind::Unevaluated(def, substs, promoted) = self.val { use crate::mir::interpret::ErrorHandled; let param_env_and_substs = param_env.with_reveal_all().and(substs); @@ -2361,7 +2368,7 @@ impl<'tcx> Const<'tcx> { // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. let param_env_and_substs = if param_env_and_substs.needs_infer() { - tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did)) + tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did)) } else { param_env_and_substs }; @@ -2371,7 +2378,7 @@ impl<'tcx> Const<'tcx> { let (param_env, substs) = param_env_and_substs.into_parts(); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - match tcx.const_eval_resolve(param_env, did, substs, promoted, None) { + match tcx.const_eval_resolve(param_env, def, substs, promoted, None) { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), @@ -2431,7 +2438,7 @@ pub enum ConstKind<'tcx> { /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. - Unevaluated(DefId, SubstsRef<'tcx>, Option), + Unevaluated(ty::WithOptParam, SubstsRef<'tcx>, Option), /// Used to hold computed value. Value(ConstValue<'tcx>), diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 8d7944004c75e..94863272c6ff2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -190,7 +190,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .ty; let needs_note = match ty.kind { ty::Closure(id, _) => { - let tables = self.infcx.tcx.typeck_tables_of(id.expect_local()); + let tables = self + .infcx + .tcx + .typeck_tables_of(self.infcx.tcx.with_opt_param(id.expect_local())); let hir_id = self.infcx.tcx.hir().as_local_hir_id(id.expect_local()); tables.closure_kind_origins().get(hir_id).is_none() @@ -865,22 +868,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("`{}` would have to be valid for `{}`...", name, region_name), ); - let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id); + let tcx = self.infcx.tcx; + + let fn_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id); err.span_label( drop_span, format!( "...but `{}` will be dropped here, when the {} returns", name, - self.infcx - .tcx - .hir() + tcx.hir() .opt_name(fn_hir_id) .map(|name| format!("function `{}`", name)) .unwrap_or_else(|| { - match &self - .infcx - .tcx - .typeck_tables_of(self.mir_def_id) + match &tcx + .typeck_tables_of(tcx.with_opt_param(self.mir_def_id)) .node_type(fn_hir_id) .kind { diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index ca8e54ea28649..2eaf6fab4d02c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -100,8 +100,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let did = did.expect_local(); let hir_id = self.infcx.tcx.hir().as_local_hir_id(did); - if let Some((span, name)) = - self.infcx.tcx.typeck_tables_of(did).closure_kind_origins().get(hir_id) + if let Some((span, name)) = self + .infcx + .tcx + .typeck_tables_of(self.infcx.tcx.with_opt_param(did)) + .closure_kind_origins() + .get(hir_id) { diag.span_note( *span, @@ -123,8 +127,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let did = did.expect_local(); let hir_id = self.infcx.tcx.hir().as_local_hir_id(did); - if let Some((span, name)) = - self.infcx.tcx.typeck_tables_of(did).closure_kind_origins().get(hir_id) + if let Some((span, name)) = self + .infcx + .tcx + .typeck_tables_of(self.infcx.tcx.with_opt_param(did)) + .closure_kind_origins() + .get(hir_id) { diag.span_note( *span, diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 4d4b6fb9386db..00cce45d30016 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -507,7 +507,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .map(|(pos, _)| pos) .next(); let def_id = hir.local_def_id(item_id); - let tables = self.infcx.tcx.typeck_tables_of(def_id); + let tables = self.infcx.tcx.typeck_tables_of(self.infcx.tcx.with_opt_param(def_id)); if let Some(ty::FnDef(def_id, _)) = tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind) { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 03b663eb75056..27bf01a1882b1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -90,14 +90,14 @@ pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { mir_borrowck, ..*providers }; } -fn mir_borrowck(tcx: TyCtxt<'_>, def_id: LocalDefId) -> BorrowCheckResult<'_> { - let (input_body, promoted) = tcx.mir_validated(def_id); - debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id.to_def_id())); +fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> BorrowCheckResult<'_> { + let (input_body, promoted) = tcx.mir_validated(def); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); let opt_closure_req = tcx.infer_ctxt().enter(|infcx| { let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); - do_mir_borrowck(&infcx, input_body, promoted, def_id) + do_mir_borrowck(&infcx, input_body, promoted, def) }); debug!("mir_borrowck done"); @@ -108,13 +108,13 @@ fn do_mir_borrowck<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexVec>, - def_id: LocalDefId, + def: ty::WithOptParam, ) -> BorrowCheckResult<'tcx> { - debug!("do_mir_borrowck(def_id = {:?})", def_id); + debug!("do_mir_borrowck(def_id = {:?})", def); let tcx = infcx.tcx; - let param_env = tcx.param_env(def_id); - let id = tcx.hir().as_local_hir_id(def_id); + let param_env = tcx.param_env(def.did); + let id = tcx.hir().as_local_hir_id(def.did); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { @@ -135,13 +135,13 @@ fn do_mir_borrowck<'a, 'tcx>( } // Gather the upvars of a closure, if any. - let tables = tcx.typeck_tables_of(def_id); + let tables = tcx.typeck_tables_of(def); if let Some(ErrorReported) = tables.tainted_by_errors { infcx.set_tainted_by_errors(); } let upvars: Vec<_> = tables .closure_captures - .get(&def_id.to_def_id()) + .get(&def.did.to_def_id()) .into_iter() .flat_map(|v| v.values()) .map(|upvar_id| { @@ -171,8 +171,7 @@ fn do_mir_borrowck<'a, 'tcx>( // will have a lifetime tied to the inference context. let mut body = input_body.clone(); let mut promoted = input_promoted.clone(); - let free_regions = - nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted); + let free_regions = nll::replace_regions_in_mir(infcx, def, param_env, &mut body, &mut promoted); let body = &body; // no further changes let location_table = &LocationTable::new(&body); @@ -190,7 +189,7 @@ fn do_mir_borrowck<'a, 'tcx>( let mdpe = MoveDataParamEnv { move_data, param_env }; let mut flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe) - .into_engine(tcx, &body, def_id.to_def_id()) + .into_engine(tcx, &body, def.did.to_def_id()) .iterate_to_fixpoint() .into_results_cursor(&body); @@ -207,7 +206,7 @@ fn do_mir_borrowck<'a, 'tcx>( nll_errors, } = nll::compute_regions( infcx, - def_id, + def.did, free_regions, body, &promoted, @@ -223,7 +222,7 @@ fn do_mir_borrowck<'a, 'tcx>( // write unit-tests, as well as helping with debugging. nll::dump_mir_results( infcx, - MirSource::item(def_id.to_def_id()), + MirSource::item(def.did.to_def_id()), &body, ®ioncx, &opt_closure_req, @@ -234,7 +233,7 @@ fn do_mir_borrowck<'a, 'tcx>( nll::dump_annotation( infcx, &body, - def_id.to_def_id(), + def.did.to_def_id(), ®ioncx, &opt_closure_req, &opaque_type_values, @@ -249,13 +248,13 @@ fn do_mir_borrowck<'a, 'tcx>( let regioncx = Rc::new(regioncx); let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set) - .into_engine(tcx, &body, def_id.to_def_id()) + .into_engine(tcx, &body, def.did.to_def_id()) .iterate_to_fixpoint(); let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe) - .into_engine(tcx, &body, def_id.to_def_id()) + .into_engine(tcx, &body, def.did.to_def_id()) .iterate_to_fixpoint(); let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe) - .into_engine(tcx, &body, def_id.to_def_id()) + .into_engine(tcx, &body, def.did.to_def_id()) .iterate_to_fixpoint(); let movable_generator = match tcx.hir().get(id) { @@ -274,7 +273,7 @@ fn do_mir_borrowck<'a, 'tcx>( let mut promoted_mbcx = MirBorrowckCtxt { infcx, body: promoted_body, - mir_def_id: def_id, + mir_def_id: def.did, move_data: &move_data, location_table: &LocationTable::new(promoted_body), movable_generator, @@ -306,7 +305,7 @@ fn do_mir_borrowck<'a, 'tcx>( let mut mbcx = MirBorrowckCtxt { infcx, body, - mir_def_id: def_id, + mir_def_id: def.did, move_data: &mdpe.move_data, location_table, movable_generator, @@ -1348,8 +1347,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // in order to populate our used_mut set. match **aggregate_kind { AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => { + let tcx = self.infcx.tcx; let BorrowCheckResult { used_mut_upvars, .. } = - self.infcx.tcx.mir_borrowck(def_id.expect_local()); + tcx.mir_borrowck(tcx.with_opt_param(def_id.expect_local())); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); for field in used_mut_upvars { self.propagate_closure_used_mut_upvar(&operands[field.index()]); diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index ea68364be37a3..67eca353f8590 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -59,20 +59,20 @@ crate struct NllOutput<'tcx> { /// `compute_regions`. pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, - def_id: LocalDefId, + def: ty::WithOptParam, param_env: ty::ParamEnv<'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexVec>, ) -> UniversalRegions<'tcx> { - debug!("replace_regions_in_mir(def_id={:?})", def_id); + debug!("replace_regions_in_mir(def={:?})", def); // Compute named region information. This also renumbers the inputs/outputs. - let universal_regions = UniversalRegions::new(infcx, def_id, param_env); + let universal_regions = UniversalRegions::new(infcx, def, param_env); // Replace all remaining regions with fresh inference variables. renumber::renumber_mir(infcx, body, promoted); - let source = MirSource::item(def_id.to_def_id()); + let source = MirSource::item(def.did.to_def_id()); mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(())); universal_regions diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/src/librustc_mir/borrow_check/type_check/input_output.rs index edd2dc3c2de55..55031baa91ab7 100644 --- a/src/librustc_mir/borrow_check/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/type_check/input_output.rs @@ -36,7 +36,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if !self.tcx().is_closure(self.mir_def_id.to_def_id()) { user_provided_sig = None; } else { - let typeck_tables = self.tcx().typeck_tables_of(self.mir_def_id); + let typeck_tables = + self.tcx().typeck_tables_of(self.tcx().with_opt_param(self.mir_def_id)); user_provided_sig = match typeck_tables.user_provided_sigs.get(&self.mir_def_id.to_def_id()) { None => None, diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 0e35cafb9f3e9..45d2981d3ec70 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -321,7 +321,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { let tcx = self.tcx(); - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val { if let Some(promoted) = promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, promoted: &Body<'tcx>, @@ -357,7 +357,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty, - def_id, + def.did, UserSubsts { substs, user_self_ty: None }, )), ) { @@ -1238,8 +1238,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = infcx.tcx; let param_env = self.param_env; let body = self.body; - let concrete_opaque_types = - &tcx.typeck_tables_of(anon_owner_def_id.expect_local()).concrete_opaque_types; + let concrete_opaque_types = &tcx + .typeck_tables_of(tcx.with_opt_param(anon_owner_def_id.expect_local())) + .concrete_opaque_types; let mut opaque_type_values = Vec::new(); debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id); @@ -2637,7 +2638,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { substs: SubstsRef<'tcx>, location: Location, ) -> ty::InstantiatedPredicates<'tcx> { - if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements + if let Some(ref closure_region_requirements) = + tcx.mir_borrowck(tcx.with_opt_param(def_id)).closure_requirements { let closure_constraints = QueryRegionConstraints { outlives: closure_region_requirements.apply_requirements( diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index 3003f4639d9fa..fbb21a312985f 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -227,12 +227,12 @@ impl<'tcx> UniversalRegions<'tcx> { /// known between those regions. pub fn new( infcx: &InferCtxt<'_, 'tcx>, - mir_def_id: LocalDefId, + mir_def: ty::WithOptParam, param_env: ty::ParamEnv<'tcx>, ) -> Self { let tcx = infcx.tcx; - let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id); - UniversalRegionsBuilder { infcx, mir_def_id: mir_def_id.to_def_id(), mir_hir_id, param_env } + let mir_hir_id = tcx.hir().as_local_hir_id(mir_def.did); + UniversalRegionsBuilder { infcx, mir_def: mir_def.to_global(), mir_hir_id, param_env } .build() } @@ -389,7 +389,7 @@ impl<'tcx> UniversalRegions<'tcx> { struct UniversalRegionsBuilder<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, - mir_def_id: DefId, + mir_def: ty::WithOptParam, mir_hir_id: HirId, param_env: ty::ParamEnv<'tcx>, } @@ -398,7 +398,7 @@ const FR: NLLRegionVariableOrigin = NLLRegionVariableOrigin::FreeRegion; impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { fn build(self) -> UniversalRegions<'tcx> { - debug!("build(mir_def_id={:?})", self.mir_def_id); + debug!("build(mir_def={:?})", self.mir_def); let param_env = self.param_env; debug!("build: param_env={:?}", param_env); @@ -418,7 +418,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let closure_base_def_id = self.infcx.tcx.closure_base_def_id(self.mir_def_id); + let closure_base_def_id = self.infcx.tcx.closure_base_def_id(self.mir_def.did); // If this is a closure or generator, then the late-bound regions from the enclosing // function are actually external regions to us. For example, here, 'a is not local @@ -426,8 +426,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // fn foo<'a>() { // let c = || { let x: &'a u32 = ...; } // } - if self.mir_def_id != closure_base_def_id { - self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices) + if self.mir_def.did != closure_base_def_id { + self.infcx + .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices) } let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); @@ -437,15 +438,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let first_local_index = self.infcx.num_region_vars(); let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars( FR, - self.mir_def_id, + self.mir_def.did, &bound_inputs_and_output, &mut indices, ); // Converse of above, if this is a function then the late-bound regions declared on its // signature are local to the fn. - if self.mir_def_id == closure_base_def_id { + if self.mir_def.did == closure_base_def_id { self.infcx - .replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices); + .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); } let (unnormalized_output_ty, mut unnormalized_input_tys) = @@ -457,7 +458,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { if self.infcx.tcx.fn_sig(def_id).c_variadic() { let va_list_did = self.infcx.tcx.require_lang_item( lang_items::VaListTypeLangItem, - Some(self.infcx.tcx.def_span(self.mir_def_id)), + Some(self.infcx.tcx.def_span(self.mir_def.did)), ); let region = self .infcx @@ -508,14 +509,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); + let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did); match tcx.hir().body_owner_kind(self.mir_hir_id) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { - let defining_ty = if self.mir_def_id == closure_base_def_id { + let defining_ty = if self.mir_def.did == closure_base_def_id { tcx.type_of(closure_base_def_id) } else { - let tables = tcx.typeck_tables_of(self.mir_def_id.expect_local()); + let tables = tcx.typeck_tables_of(self.mir_def.expect_local()); tables.node_type(self.mir_hir_id) }; @@ -531,20 +532,20 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), _ => span_bug!( - tcx.def_span(self.mir_def_id), + tcx.def_span(self.mir_def.did), "expected defining type for `{:?}`: `{:?}`", - self.mir_def_id, + self.mir_def.did, defining_ty ), } } BodyOwnerKind::Const | BodyOwnerKind::Static(..) => { - assert_eq!(closure_base_def_id, self.mir_def_id); + assert_eq!(closure_base_def_id, self.mir_def.did); let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id); let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, &identity_substs); - DefiningTy::Const(self.mir_def_id, substs) + DefiningTy::Const(self.mir_def.did, substs) } } } @@ -559,7 +560,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); + let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did); let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id); let fr_substs = match defining_ty { DefiningTy::Closure(_, ref substs) | DefiningTy::Generator(_, ref substs, _) => { @@ -593,7 +594,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; match defining_ty { DefiningTy::Closure(def_id, substs) => { - assert_eq!(self.mir_def_id, def_id); + assert_eq!(self.mir_def.did, def_id); let closure_sig = substs.as_closure().sig(); let inputs_and_output = closure_sig.inputs_and_output(); let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap(); @@ -617,7 +618,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::Generator(def_id, substs, movability) => { - assert_eq!(self.mir_def_id, def_id); + assert_eq!(self.mir_def.did, def_id); let resume_ty = substs.as_generator().resume_ty(); let output = substs.as_generator().return_ty(); let generator_ty = tcx.mk_generator(def_id, substs, movability); @@ -635,8 +636,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::Const(def_id, _) => { // For a constant body, there are no inputs, and one // "output" (the type of the constant). - assert_eq!(self.mir_def_id, def_id); - let ty = tcx.type_of(def_id); + assert_eq!(self.mir_def.did, def_id); + let ty = tcx.type_of(self.mir_def.ty_def_id()); let ty = indices.fold_to_region_vids(tcx, &ty); ty::Binder::dummy(tcx.intern_type_list(&[ty])) } diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index d62300b3f5541..c6eb84733a99b 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -288,17 +288,17 @@ pub fn const_eval_raw_provider<'tcx>( } let cid = key.value; - let def_id = cid.instance.def.def_id(); + let def = cid.instance.with_opt_param(tcx); - if let Some(def_id) = def_id.as_local() { - if tcx.has_typeck_tables(def_id) { - if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors { + if let Some(def) = def.as_local() { + if tcx.has_typeck_tables(def.did) { + if let Some(error_reported) = tcx.typeck_tables_of(def).tainted_by_errors { return Err(ErrorHandled::Reported(error_reported)); } } } - let is_static = tcx.is_static(def_id); + let is_static = tcx.is_static(def.did); let mut ecx = InterpCx::new( tcx, @@ -334,9 +334,9 @@ pub fn const_eval_raw_provider<'tcx>( } v - } else if def_id.is_local() { + } else if def.did.is_local() { // constant defined in this crate, we can figure out a lint level! - match tcx.def_kind(def_id) { + match tcx.def_kind(def.did) { // constants never produce a hard error at the definition site. Anything else is // a backwards compatibility hazard (and will break old versions of winapi for // sure) @@ -346,9 +346,9 @@ pub fn const_eval_raw_provider<'tcx>( // validation thus preventing such a hard error from being a backwards // compatibility hazard DefKind::Const | DefKind::AssocConst => { - let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + let hir_id = tcx.hir().as_local_hir_id(def.did.expect_local()); err.report_as_lint( - tcx.at(tcx.def_span(def_id)), + tcx.at(tcx.def_span(def.did)), "any use of this value will cause an error", hir_id, Some(err.span), @@ -359,7 +359,7 @@ pub fn const_eval_raw_provider<'tcx>( // deny-by-default lint _ => { if let Some(p) = cid.promoted { - let span = tcx.promoted_mir(def_id)[p].span; + let span = tcx.promoted_mir(def)[p].span; if let err_inval!(ReferencedConstant) = err.error { err.report_as_error( tcx.at(span), @@ -369,7 +369,7 @@ pub fn const_eval_raw_provider<'tcx>( err.report_as_lint( tcx.at(span), "reaching this expression at runtime will panic or abort", - tcx.hir().as_local_hir_id(def_id.expect_local()), + tcx.hir().as_local_hir_id(def.did.expect_local()), Some(err.span), ) } diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index dc13126df0e4c..1d1f160c6b63d 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -191,7 +191,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, debug!("find_mir_or_eval_fn: {:?}", instance); // Only check non-glue functions - if let ty::InstanceDef::Item(def_id) = instance.def { + if let ty::InstanceDef::Item(def_id, _) = instance.def { // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here. But we can at least rule out functions that are not const // at all. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 95e193b625354..2e8b1cfc18018 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -400,24 +400,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { promoted: Option, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { // do not continue if typeck errors occurred (can only occur in local crate) - let did = instance.def_id(); - if let Some(did) = did.as_local() { - if self.tcx.has_typeck_tables(did) { - if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors { + let def = instance.with_opt_param(*self.tcx); + if let Some(def) = def.as_local() { + if self.tcx.has_typeck_tables(def.did) { + if let Some(error_reported) = self.tcx.typeck_tables_of(def).tainted_by_errors { throw_inval!(TypeckError(error_reported)) } } } trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); if let Some(promoted) = promoted { - return Ok(&self.tcx.promoted_mir(did)[promoted]); + return Ok(&self.tcx.promoted_mir(def)[promoted]); } match instance { - ty::InstanceDef::Item(def_id) => { - if self.tcx.is_mir_available(did) { - Ok(self.tcx.optimized_mir(did)) + ty::InstanceDef::Item(_, _) => { + if self.tcx.is_mir_available(def.did) { + Ok(self.tcx.optimized_mir(def)) } else { - throw_unsup!(NoMirFor(def_id)) + throw_unsup!(NoMirFor(def.did)) } } _ => Ok(self.tcx.instance_mir(instance)), @@ -448,15 +448,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } /// The `substs` are assumed to already be in our interpreter "universe" (param_env). + #[inline] pub(super) fn resolve( &self, def_id: DefId, substs: SubstsRef<'tcx>, ) -> InterpResult<'tcx, ty::Instance<'tcx>> { - trace!("resolve: {:?}, {:#?}", def_id, substs); + self.resolve_const_arg(self.tcx.with_opt_param(def_id), substs) + } + + pub(super) fn resolve_const_arg( + &self, + def: ty::WithOptParam, + substs: SubstsRef<'tcx>, + ) -> InterpResult<'tcx, ty::Instance<'tcx>> { + trace!("resolve: {:?}, {:#?}", def, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - match ty::Instance::resolve(*self.tcx, self.param_env, def_id, substs) { + match ty::Instance::resolve_const_arg(*self.tcx, self.param_env, def, substs) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 38948ee53846a..ad6b54f3c84ac 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -531,8 +531,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val_val = match val.val { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { - let instance = self.resolve(def_id, substs)?; + ty::ConstKind::Unevaluated(def, substs, promoted) => { + let instance = self.resolve(def, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. // The reason we use `const_eval_raw` everywhere else is to prevent cycles during // validation, because validation automatically reads through any references, thus diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 4681079a22ddf..4906da19f3af3 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -257,7 +257,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) - | ty::InstanceDef::Item(_) => { + | ty::InstanceDef::Item(_, _) => { // We need MIR for this fn let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? { Some(body) => body, diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 3bb9ba3712058..44f0b86d564d5 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -226,7 +226,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => { let mut name = None; if let Some(def_id) = def_id.as_local() { - let tables = self.ecx.tcx.typeck_tables_of(def_id); + let tables = self.ecx.tcx.typeck_tables_of(self.ecx.tcx.with_opt_param(def_id)); if let Some(upvars) = tables.closure_captures.get(&def_id.to_def_id()) { // Sometimes the index is beyond the number of upvars (seen // for a generator). diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f9b3c319c1f66..913932b7f36b2 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -622,12 +622,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match substituted_constant.val { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { - match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) { + ty::ConstKind::Unevaluated(def, substs, promoted) => { + match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( - self.tcx.def_span(def_id), + self.tcx.def_span(def.did), "collection encountered polymorphic constant", ), } @@ -768,7 +768,7 @@ fn visit_instance_use<'tcx>( // need a mono item. fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { let def_id = match instance.def { - ty::InstanceDef::Item(def_id) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id, + ty::InstanceDef::Item(def_id, _) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id, ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index a945c1d626a9a..55c7485ec325d 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -314,7 +314,7 @@ fn mono_item_visibility( }; let def_id = match instance.def { - InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, + InstanceDef::Item(def_id, _) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, // These are all compiler glue and such, never exported, always hidden. InstanceDef::VtableShim(..) @@ -704,7 +704,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( match mono_item { MonoItem::Fn(instance) => { let def_id = match instance.def { - ty::InstanceDef::Item(def_id) => def_id, + ty::InstanceDef::Item(def_id, _) => def_id, ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::FnPtrShim(..) diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 8327affd982ed..27b57ffef8b34 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -169,7 +169,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) // Check if this is a generator, if so, return the drop glue for it if let Some(&ty::TyS { kind: ty::Generator(gen_def_id, substs, _), .. }) = ty { - let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap(); + let body = + &**tcx.optimized_mir(tcx.with_opt_param(gen_def_id)).generator_drop.as_ref().unwrap(); return body.subst(tcx, substs); } diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index e2893e81a2ce6..582a2c85243fd 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -244,11 +244,11 @@ where }; // Check the qualifs of the value of `const` items. - if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val { assert!(promoted.is_none()); // Don't peek inside trait associated constants. - if cx.tcx.trait_of_item(def_id).is_none() { - let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id); + if cx.tcx.trait_of_item(def.did).is_none() { + let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { return false; } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index d263bf12e8868..6aaf0fc39724e 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -537,7 +537,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { let instance = Instance::resolve(self.tcx, self.param_env, def_id, substs); debug!("Resolving ({:?}) -> {:?}", def_id, instance); if let Ok(Some(func)) = instance { - if let InstanceDef::Item(def_id) = func.def { + if let InstanceDef::Item(def_id, _) = func.def { if is_const_fn(self.tcx, def_id) { return; } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index b8f725e967ddb..d15524247e67c 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -146,8 +146,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } } &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => { - let UnsafetyCheckResult { violations, unsafe_blocks } = - self.tcx.unsafety_check_result(def_id.expect_local()); + let UnsafetyCheckResult { violations, unsafe_blocks } = self + .tcx + .unsafety_check_result(self.tcx.with_opt_param(def_id.expect_local())); self.register_violations(&violations, &unsafe_blocks); } }, @@ -535,28 +536,31 @@ fn check_unused_unsafe( intravisit::Visitor::visit_body(&mut visitor, body); } -fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: LocalDefId) -> UnsafetyCheckResult { - debug!("unsafety_violations({:?})", def_id); +fn unsafety_check_result( + tcx: TyCtxt<'_>, + def: ty::WithOptParam, +) -> UnsafetyCheckResult { + debug!("unsafety_violations({:?})", def); // N.B., this borrow is valid because all the consumers of // `mir_built` force this. - let body = &tcx.mir_built(def_id).borrow(); + let body = &tcx.mir_built(def).borrow(); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env(def.did); - let id = tcx.hir().as_local_hir_id(def_id); + let id = tcx.hir().as_local_hir_id(def.did); let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) { hir::BodyOwnerKind::Closure => (false, false), hir::BodyOwnerKind::Fn => { - (tcx.is_const_fn_raw(def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id())) + (tcx.is_const_fn_raw(def.did.to_def_id()), is_min_const_fn(tcx, def.did.to_def_id())) } hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false), }; let mut checker = - UnsafetyChecker::new(const_context, min_const_fn, body, def_id, tcx, param_env); + UnsafetyChecker::new(const_context, min_const_fn, body, def.did, tcx, param_env); checker.visit_body(&body); - check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks); + check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks); UnsafetyCheckResult { violations: checker.violations.into(), unsafe_blocks: checker.inherited_blocks.into(), @@ -651,7 +655,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { return; } - let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id); + let UnsafetyCheckResult { violations, unsafe_blocks } = + tcx.unsafety_check_result(tcx.with_opt_param(def_id)); for &UnsafetyViolation { source_info, lint_root, description, details, kind } in violations.iter() diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 068d055fa78f8..2a0dbfc9e562a 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -102,14 +102,14 @@ impl Inliner<'tcx> { // not inline us. This trick only works without incremental compilation. // So don't do it if that is enabled. if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id { - self.tcx.optimized_mir(callsite.callee) + self.tcx.optimized_mir(self.tcx.with_opt_param(callsite.callee)) } else { continue; } } else { // This cannot result in a cycle since the callee MIR is from another crate // and is already optimized. - self.tcx.optimized_mir(callsite.callee) + self.tcx.optimized_mir(self.tcx.with_opt_param(callsite.callee)) }; let callee_body = if self.consider_optimizing(callsite, callee_body) { diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 8ca240d2c7da7..e826a57bb3e72 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::steal::Steal; -use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, InstanceDef, TyCtxt, TypeFoldable}; use rustc_span::{Span, Symbol}; use std::borrow::Cow; @@ -116,13 +116,18 @@ pub struct MirSource<'tcx> { impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { - MirSource { instance: InstanceDef::Item(def_id), promoted: None } + MirSource { instance: InstanceDef::Item(def_id, None), promoted: None } } #[inline] pub fn def_id(&self) -> DefId { self.instance.def_id() } + + #[inline] + pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { + self.instance.with_opt_param(tcx) + } } /// Generates a default name for the pass based on the name of the @@ -202,8 +207,8 @@ pub fn run_passes( } } -fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { - let const_kind = tcx.hir().body_const_context(def_id.expect_local()); +fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> ConstQualifs { + let const_kind = tcx.hir().body_const_context(def.did.expect_local()); // No need to const-check a non-const `fn`. if const_kind.is_none() { @@ -214,15 +219,20 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before // performing the steal. - let body = &tcx.mir_const(def_id).borrow(); + let body = &tcx.mir_const(def).borrow(); if body.return_ty().references_error() { tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors"); return Default::default(); } - let ccx = - check_consts::ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) }; + let ccx = check_consts::ConstCx { + body, + tcx, + def_id: def.did, + const_kind, + param_env: tcx.param_env(def.did), + }; let mut validator = check_consts::validation::Validator::new(&ccx); validator.check_body(); @@ -233,22 +243,28 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { } /// Make MIR ready for const evaluation. This is run on all MIR, not just on consts! -fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal> { - let def_id = def_id.expect_local(); +fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> Steal> { + let def = def.expect_local(); // Unsafety check uses the raw mir, so make sure it is run. - let _ = tcx.unsafety_check_result(def_id); + let _ = tcx.unsafety_check_result(def); - let mut body = tcx.mir_built(def_id).steal(); + let mut body = tcx.mir_built(def).steal(); - util::dump_mir(tcx, None, "mir_map", &0, MirSource::item(def_id.to_def_id()), &body, |_, _| { - Ok(()) - }); + util::dump_mir( + tcx, + None, + "mir_map", + &0, + MirSource::item(def.did.to_def_id()), + &body, + |_, _| Ok(()), + ); run_passes( tcx, &mut body, - InstanceDef::Item(def_id.to_def_id()), + InstanceDef::Item(def.did.to_def_id(), def.param_did), None, MirPhase::Const, &[&[ @@ -264,13 +280,13 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal> { fn mir_validated( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, + def: ty::WithOptParam, ) -> (Steal>, Steal>>) { // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. - let _ = tcx.mir_const_qualif(def_id.to_def_id()); + let _ = tcx.mir_const_qualif(def.to_global()); - let mut body = tcx.mir_const(def_id.to_def_id()).steal(); + let mut body = tcx.mir_const(def.to_global()).steal(); let mut required_consts = Vec::new(); let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts); @@ -283,7 +299,7 @@ fn mir_validated( run_passes( tcx, &mut body, - InstanceDef::Item(def_id.to_def_id()), + InstanceDef::Item(def.did.to_def_id(), def.param_did), None, MirPhase::Validated, &[&[ @@ -303,17 +319,17 @@ fn mir_validated( fn mir_drops_elaborated_and_const_checked<'tcx>( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, + def: ty::WithOptParam, ) -> Steal> { // (Mir-)Borrowck uses `mir_validated`, so we have to force it to // execute before we can steal. - tcx.ensure().mir_borrowck(def_id); + tcx.ensure().mir_borrowck(def); - let (body, _) = tcx.mir_validated(def_id); + let (body, _) = tcx.mir_validated(def); let mut body = body.steal(); - run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, None); - check_consts::post_drop_elaboration::check_live_drops(tcx, def_id, &body); + run_post_borrowck_cleanup_passes(tcx, &mut body, def.did, None); + check_consts::post_drop_elaboration::check_live_drops(tcx, def.did, &body); tcx.alloc_steal_mir(body) } @@ -349,7 +365,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>( run_passes( tcx, body, - InstanceDef::Item(def_id.to_def_id()), + InstanceDef::Item(def_id.to_def_id(), None), promoted, MirPhase::DropElab, &[post_borrowck_cleanup], @@ -413,7 +429,7 @@ fn run_optimization_passes<'tcx>( run_passes( tcx, body, - InstanceDef::Item(def_id.to_def_id()), + InstanceDef::Item(def_id.to_def_id(), None), promoted, MirPhase::Optimized, &[ @@ -423,39 +439,39 @@ fn run_optimization_passes<'tcx>( ); } -fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { - if tcx.is_constructor(def_id) { +fn optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> Body<'_> { + if tcx.is_constructor(def.did) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const // qualification and borrow checking the trouble of special casing // constructors. - return shim::build_adt_ctor(tcx, def_id); + return shim::build_adt_ctor(tcx, def.did); } - let def_id = def_id.expect_local(); + let def = def.expect_local(); - let mut body = tcx.mir_drops_elaborated_and_const_checked(def_id).steal(); - run_optimization_passes(tcx, &mut body, def_id, None); + let mut body = tcx.mir_drops_elaborated_and_const_checked(def).steal(); + run_optimization_passes(tcx, &mut body, def.did, None); debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR"); body } -fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> IndexVec> { - if tcx.is_constructor(def_id) { +fn promoted_mir(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> IndexVec> { + if tcx.is_constructor(def.did) { return IndexVec::new(); } - let def_id = def_id.expect_local(); + let def = def.expect_local(); - tcx.ensure().mir_borrowck(def_id); - let (_, promoted) = tcx.mir_validated(def_id); + tcx.ensure().mir_borrowck(def); + let (_, promoted) = tcx.mir_validated(def); let mut promoted = promoted.steal(); for (p, mut body) in promoted.iter_enumerated_mut() { - run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, Some(p)); - run_optimization_passes(tcx, &mut body, def_id, Some(p)); + run_post_borrowck_cleanup_passes(tcx, &mut body, def.did, Some(p)); + run_optimization_passes(tcx, &mut body, def.did, Some(p)); } debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR"); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 8bcbcd79ae60b..957efab74ab43 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -60,15 +60,15 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> { return; } - let def_id = src.def_id(); + let def = src.with_opt_param(tcx); let mut rpo = traversal::reverse_postorder(body); - let ccx = ConstCx::new(tcx, def_id.expect_local(), body); + let ccx = ConstCx::new(tcx, def.did.expect_local(), body); let (temps, all_candidates) = collect_temps_and_candidates(&ccx, &mut rpo); let promotable_candidates = validate_candidates(&ccx, &temps, &all_candidates); - let promoted = promote_candidates(def_id, body, tcx, temps, promotable_candidates); + let promoted = promote_candidates(def, body, tcx, temps, promotable_candidates); self.promoted_fragments.set(promoted); } } @@ -936,7 +936,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { fn promote_candidate( mut self, - def_id: DefId, + def: ty::WithOptParam, candidate: Candidate, next_promoted_id: usize, ) -> Option> { @@ -954,8 +954,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { literal: tcx.mk_const(ty::Const { ty, val: ty::ConstKind::Unevaluated( - def_id, - InternalSubsts::for_item(tcx, def_id, |param, _| { + def, + InternalSubsts::for_item(tcx, def.did, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { tcx.lifetimes.re_erased.into() } else { @@ -1099,7 +1099,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { } pub fn promote_candidates<'tcx>( - def_id: DefId, + def: ty::WithOptParam, body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>, mut temps: IndexVec, @@ -1157,7 +1157,7 @@ pub fn promote_candidates<'tcx>( }; //FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice - if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) { + if let Some(promoted) = promoter.promote_candidate(def, candidate, promotions.len()) { promotions.push(promoted); } } diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 50193c4a0db7d..d57928d5dc4d7 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -21,7 +21,7 @@ where } for def_id in def_ids { - let body = &tcx.optimized_mir(def_id); + let body = &tcx.optimized_mir(tcx.with_opt_param(def_id)); write_mir_fn_graphviz(tcx, def_id, body, use_subgraphs, w)?; } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 02614044063fc..f849d9f25e69a 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -235,7 +235,7 @@ pub fn write_mir_pretty<'tcx>( let mut first = true; for def_id in dump_mir_def_ids(tcx, single) { - let body = &tcx.optimized_mir(def_id); + let body = &tcx.optimized_mir(tcx.with_opt_param(def_id)); if first { first = false; @@ -246,9 +246,10 @@ pub fn write_mir_pretty<'tcx>( write_mir_fn(tcx, MirSource::item(def_id), body, &mut |_, _| Ok(()), w)?; - for (i, body) in tcx.promoted_mir(def_id).iter_enumerated() { + for (i, body) in tcx.promoted_mir(tcx.with_opt_param(def_id)).iter_enumerated() { writeln!(w)?; - let src = MirSource { instance: ty::InstanceDef::Item(def_id), promoted: Some(i) }; + let src = + MirSource { instance: ty::InstanceDef::Item(def_id, None), promoted: Some(i) }; write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?; } } diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index e2cf1bce733d6..fdc58200b9694 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -21,13 +21,13 @@ use rustc_target::spec::PanicStrategy; use super::lints; -crate fn mir_built(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::steal::Steal> { - tcx.alloc_steal_mir(mir_build(tcx, def_id)) +crate fn mir_built(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> ty::steal::Steal> { + tcx.alloc_steal_mir(mir_build(tcx, def)) } /// Construct the MIR for a given `DefId`. -fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> { - let id = tcx.hir().as_local_hir_id(def_id); +fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> Body<'_> { + let id = tcx.hir().as_local_hir_id(def.did); // Figure out what primary body this item has. let (body_id, return_ty_span) = match tcx.hir().get(id) { @@ -57,11 +57,11 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> { }) => (*body_id, ty.span), Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => (*body, tcx.hir().span(*hir_id)), - _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id), + _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def), }; tcx.infer_ctxt().enter(|infcx| { - let cx = Cx::new(&infcx, id); + let cx = Cx::new(&infcx, id, def); let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors { build::construct_error(cx, body_id) } else if cx.body_owner_kind.is_fn_or_closure() { @@ -181,7 +181,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> { build::construct_const(cx, body_id, return_ty, return_ty_span) }; - lints::check(tcx, &body, def_id); + lints::check(tcx, &body, def.did); // The borrow checker will replace all the regions here with its own // inference variables. There's no point having non-erased regions here. diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index a1796c9433eac..357afa3cf7922 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -614,7 +614,11 @@ fn make_mirror_unadjusted<'a, 'tcx>( // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(cx.tcx(), did); let lhs = mk_const(cx.tcx().mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(did, substs, None), + val: ty::ConstKind::Unevaluated( + cx.tcx().with_opt_param(did), + substs, + None, + ), ty: var_ty, })); let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset }; @@ -810,7 +814,7 @@ fn convert_path_expr<'a, 'tcx>( debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: cx.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(def_id, substs, None), + val: ty::ConstKind::Unevaluated(cx.tcx.with_opt_param(def_id), substs, None), ty: cx.tables().node_type(expr.hir_id), }), user_ty, @@ -868,7 +872,7 @@ fn convert_var<'tcx>( let upvar_index = cx .tables() .closure_captures - .get(&cx.body_owner) + .get(&cx.body_owner.did.to_def_id()) .and_then(|upvars| upvars.get_full(&var_hir_id).map(|(i, _, _)| i)); debug!( @@ -882,10 +886,10 @@ fn convert_var<'tcx>( None => ExprKind::VarRef { id: var_hir_id }, Some(upvar_index) => { - let closure_def_id = cx.body_owner; + let closure_def_id = cx.body_owner.did; let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, - closure_expr_id: closure_def_id.expect_local(), + closure_expr_id: closure_def_id, }; let var_ty = cx.tables().node_type(var_hir_id); @@ -898,7 +902,7 @@ fn convert_var<'tcx>( // signature will be &self or &mut self and hence will // have a bound region with number 0 let region = ty::ReFree(ty::FreeRegion { - scope: closure_def_id, + scope: closure_def_id.to_def_id(), bound_region: ty::BoundRegion::BrAnon(0), }); let region = cx.tcx.mk_region(region); diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs index 46607fd07cdd7..51686b4b13dc0 100644 --- a/src/librustc_mir_build/hair/cx/mod.rs +++ b/src/librustc_mir_build/hair/cx/mod.rs @@ -8,7 +8,7 @@ use crate::hair::*; use rustc_ast::ast; use rustc_ast::attr; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::Node; use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; @@ -40,7 +40,7 @@ crate struct Cx<'a, 'tcx> { constness: hir::Constness, /// The `DefId` of the owner of this body. - body_owner: DefId, + body_owner: ty::WithOptParam, /// What kind of body is being compiled. crate body_owner_kind: hir::BodyOwnerKind, @@ -53,10 +53,14 @@ crate struct Cx<'a, 'tcx> { } impl<'a, 'tcx> Cx<'a, 'tcx> { - crate fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> { + crate fn new( + infcx: &'a InferCtxt<'a, 'tcx>, + src_id: hir::HirId, + body_owner: ty::WithOptParam, + ) -> Cx<'a, 'tcx> { let tcx = infcx.tcx; - let src_def_id = tcx.hir().local_def_id(src_id); - let tables = tcx.typeck_tables_of(src_def_id); + + let tables = tcx.typeck_tables_of(body_owner); let body_owner_kind = tcx.hir().body_owner_kind(src_id); let constness = match body_owner_kind { @@ -81,12 +85,12 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { tcx, infcx, root_lint_level: src_id, - param_env: tcx.param_env(src_def_id), - identity_substs: InternalSubsts::identity_for_item(tcx, src_def_id.to_def_id()), - region_scope_tree: tcx.region_scope_tree(src_def_id), + param_env: tcx.param_env(body_owner.did), + identity_substs: InternalSubsts::identity_for_item(tcx, body_owner.did.to_def_id()), + region_scope_tree: tcx.region_scope_tree(body_owner.did), tables, constness, - body_owner: src_def_id.to_def_id(), + body_owner, body_owner_kind, check_overflow, control_flow_destroyed: Vec::new(), diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 5c30b2a448c6d..450bb9ebcd55f 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -801,7 +801,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // `mir_const_qualif` must be called with the `DefId` of the item where the const is // defined, not where it is declared. The difference is significant for associated // constants. - let mir_structural_match_violation = self.tcx.mir_const_qualif(instance.def_id()).custom_eq; + let mir_structural_match_violation = + self.tcx.mir_const_qualif(instance.with_opt_param(self.tcx)).custom_eq; debug!("mir_structural_match_violation({:?}) -> {}", qpath, mir_structural_match_violation); match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) { diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs index c8666ba1fd078..57b141f337d59 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -400,7 +400,7 @@ impl Visitor<'tcx> for ItemVisitor<'tcx> { let owner_def_id = self.tcx.hir().body_owner_def_id(body_id); let body = self.tcx.hir().body(body_id); let param_env = self.tcx.param_env(owner_def_id.to_def_id()); - let tables = self.tcx.typeck_tables_of(owner_def_id); + let tables = self.tcx.typeck_tables_of(self.tcx.with_opt_param(owner_def_id)); ExprVisitor { tcx: self.tcx, param_env, tables }.visit_body(body); self.visit_body(body); } diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index ff5dabd5418c9..8c05c44dc5fa7 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -670,7 +670,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { exit_ln: ir.add_live_node(ExitNode), }; - let tables = ir.tcx.typeck_tables_of(def_id); + let tables = ir.tcx.typeck_tables_of(ir.tcx.with_opt_param(def_id)); let param_env = ir.tcx.param_env(def_id); let num_live_nodes = ir.num_live_nodes; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9e6e7ea962bc3..3d389e7368d6c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -353,7 +353,11 @@ fn item_tables<'a, 'tcx>( empty_tables: &'a ty::TypeckTables<'tcx>, ) -> &'a ty::TypeckTables<'tcx> { let def_id = tcx.hir().local_def_id(hir_id); - if tcx.has_typeck_tables(def_id) { tcx.typeck_tables_of(def_id) } else { empty_tables } + if tcx.has_typeck_tables(def_id) { + tcx.typeck_tables_of(tcx.with_opt_param(def_id)) + } else { + empty_tables + } } fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index e63e31e03c9f0..467e3ad1c45da 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -109,7 +109,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { F: FnOnce(&mut Self), { let tables = if self.tcx.has_typeck_tables(item_def_id) { - self.tcx.typeck_tables_of(item_def_id) + self.tcx.typeck_tables_of(self.tcx.with_opt_param(item_def_id)) } else { self.save_ctxt.empty_tables }; diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 176bd90303ddd..5e96a627617ac 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -1409,7 +1409,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let tables: &TypeckTables<'tcx> = match &in_progress_tables { Some(t) if t.hir_owner.map(|owner| owner.to_def_id()) == Some(generator_did_root) => t, _ => { - query_tables = self.tcx.typeck_tables_of(generator_did.expect_local()); + query_tables = self + .tcx + .typeck_tables_of(self.tcx.with_opt_param(generator_did.expect_local())); &query_tables } }; diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 32ab63458e752..786a230e62299 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -505,10 +505,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } } - &ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + &ty::PredicateKind::ConstEvaluatable(def, substs) => { match self.selcx.infcx().const_eval_resolve( obligation.param_env, - def_id, + def, substs, None, Some(obligation.cause.span), @@ -524,10 +524,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { let stalled_on = &mut pending_obligation.stalled_on; let mut evaluate = |c: &'tcx Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { match self.selcx.infcx().const_eval_resolve( obligation.param_env, - def_id, + def, substs, promoted, Some(obligation.cause.span), diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index cff5efbfd0fd1..cfbaeade75955 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -489,14 +489,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - &ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - match self.tcx().const_eval_resolve( - obligation.param_env, - def_id, - substs, - None, - None, - ) { + &ty::PredicateKind::ConstEvaluatable(def, substs) => { + match self.tcx().const_eval_resolve(obligation.param_env, def, substs, None, None) { Ok(_) => Ok(EvaluatedToOk), Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig), Err(_) => Ok(EvaluatedToErr), @@ -507,11 +501,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2); let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { self.infcx .const_eval_resolve( obligation.param_env, - def_id, + def, substs, promoted, Some(obligation.cause.span), diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index 1825c159ff3fb..12bea5c3b7abe 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -116,8 +116,8 @@ pub fn predicate_obligations<'a, 'tcx>( wf.compute(data.skip_binder().a.into()); // (*) wf.compute(data.skip_binder().b.into()); // (*) } - &ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - let obligations = wf.nominal_obligations(def_id, substs); + &ty::PredicateKind::ConstEvaluatable(def, substs) => { + let obligations = wf.nominal_obligations(def.did, substs); wf.out.extend(obligations); for arg in substs.iter() { @@ -359,13 +359,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs, promoted) => { assert!(promoted.is_none()); - let obligations = self.nominal_obligations(def_id, substs); + let obligations = self.nominal_obligations(def.did, substs); self.out.extend(obligations); - let predicate = ty::PredicateKind::ConstEvaluatable(def_id, substs) + let predicate = ty::PredicateKind::ConstEvaluatable(def, substs) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::new( diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs index 0acf769168137..6f86fe33664ca 100644 --- a/src/librustc_ty/instance.rs +++ b/src/librustc_ty/instance.rs @@ -12,17 +12,17 @@ use log::debug; fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, + key: ty::ParamEnvAnd<'tcx, (ty::WithOptParam, SubstsRef<'tcx>)>, ) -> Result>, ErrorReported> { - let (param_env, (def_id, substs)) = key.into_parts(); + let (param_env, (def, substs)) = key.into_parts(); - debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) { + debug!("resolve(def={:?}, substs={:?})", def, substs); + let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); - let item = tcx.associated_item(def_id); + let item = tcx.associated_item(def.did); resolve_associated_item(tcx, &item, param_env, trait_def_id, substs) } else { - let ty = tcx.type_of(def_id); + let ty = tcx.type_of(def.ty_def_id()); let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty); let def = match item_type.kind { @@ -33,7 +33,7 @@ fn resolve_instance<'tcx>( } => { debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def_id) + ty::InstanceDef::Intrinsic(def.did) } ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { let ty = substs.type_at(0); @@ -53,12 +53,12 @@ fn resolve_instance<'tcx>( } _ => { debug!(" => free item"); - ty::InstanceDef::Item(def_id) + ty::InstanceDef::Item(def.did, def.param_did) } }; Ok(Some(Instance { def, substs })) }; - debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result); + debug!("resolve(def={:?}, substs={:?}) = {:?}", def, substs, result); result } @@ -182,7 +182,7 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } traits::ImplSourceGenerator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(generator_data.generator_def_id), + def: ty::InstanceDef::Item(generator_data.generator_def_id, None), substs: generator_data.substs, }), traits::ImplSourceClosure(closure_data) => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1b08bf2fc7710..9969f4857416b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -886,8 +886,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } (GenericParamDefKind::Const, GenericArg::Const(ct)) => { - let ct_def_id = tcx.hir().local_def_id(ct.value.hir_id); - ty::Const::from_anon_const(tcx, ct_def_id).into() + ty::Const::const_arg_from_anon_const( + tcx, + ty::WithOptParam { + did: tcx.hir().local_def_id(ct.value.hir_id), + param_did: Some(param.def_id), + }, + ) + .into() } _ => unreachable!(), }, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 1c3d23a3a241f..0ca85b5165ea0 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -325,7 +325,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { } (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => self.to_ty(ty).into(), (GenericParamDefKind::Const, GenericArg::Const(ct)) => { - self.to_const(&ct.value).into() + self.const_arg_to_const(&ct.value, param.def_id).into() } _ => unreachable!(), }, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0325782e69d51..a67d6a1614a50 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -737,6 +737,11 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) { tcx.hir().krate().par_visit_all_item_likes(&visit); } +/// Computes `const_param_of` for all relevant `DefId`s in the current crate. +pub fn compute_const_params_of(tcx: TyCtxt<'_>) { + tcx.par_body_owners(|body_owner_def_id| tcx.ensure().const_param_of(body_owner_def_id)) +} + fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx }); } @@ -744,7 +749,7 @@ fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) { debug_assert!(crate_num == LOCAL_CRATE); tcx.par_body_owners(|body_owner_def_id| { - tcx.ensure().typeck_tables_of(body_owner_def_id); + tcx.ensure().typeck_tables_of(tcx.with_opt_param(body_owner_def_id)); }); } @@ -841,7 +846,7 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet { - &*tcx.typeck_tables_of(def_id).used_trait_imports + &*tcx.typeck_tables_of(ty::WithOptParam::dummy(def_id)).used_trait_imports } /// Inspects the substs of opaque types, replacing any inference variables @@ -955,9 +960,11 @@ where val.fold_with(&mut FixupFolder { tcx }) } -fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> { - let fallback = move || tcx.type_of(def_id.to_def_id()); - typeck_tables_of_with_fallback(tcx, def_id, fallback) +fn typeck_tables_of<'tcx>( + tcx: TyCtxt<'tcx>, + def: ty::WithOptParam, +) -> &ty::TypeckTables<'tcx> { + typeck_tables_of_with_fallback(tcx, def.did, move || tcx.type_of(def.ty_def_id())) } /// Used only to get `TypeckTables` for type inference during error recovery. @@ -982,7 +989,7 @@ fn typeck_tables_of_with_fallback<'tcx>( // as they are part of the same "inference environment". let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local(); if outer_def_id != def_id { - return tcx.typeck_tables_of(outer_def_id); + return tcx.typeck_tables_of(tcx.with_opt_param(outer_def_id)); } let id = tcx.hir().as_local_hir_id(def_id); @@ -1917,11 +1924,11 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) { // Consts can play a role in type-checking, so they are included here. hir::ItemKind::Static(..) => { let def_id = tcx.hir().local_def_id(it.hir_id); - tcx.ensure().typeck_tables_of(def_id); + tcx.ensure().typeck_tables_of(tcx.with_opt_param(def_id)); maybe_check_static_with_link_section(tcx, def_id, it.span); } hir::ItemKind::Const(..) => { - tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id)); + tcx.ensure().typeck_tables_of(tcx.with_opt_param(tcx.hir().local_def_id(it.hir_id))); } hir::ItemKind::Enum(ref enum_definition, _) => { check_enum(tcx, it.span, &enum_definition.variants, it.hir_id); @@ -2832,7 +2839,7 @@ pub fn check_enum<'tcx>( for v in vs { if let Some(ref e) = v.disr_expr { - tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id)); + tcx.ensure().typeck_tables_of(tcx.with_opt_param(tcx.hir().local_def_id(e.hir_id))); } } @@ -3531,6 +3538,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } + pub fn const_arg_to_const( + &self, + ast_c: &hir::AnonConst, + param_def_id: DefId, + ) -> &'tcx ty::Const<'tcx> { + let const_def = ty::WithOptParam { + did: self.tcx.hir().local_def_id(ast_c.hir_id), + param_did: Some(param_def_id), + }; + let c = ty::Const::const_arg_from_anon_const(self.tcx, const_def); + self.register_wf_obligation( + c.into(), + self.tcx.hir().span(ast_c.hir_id), + ObligationCauseCode::MiscObligation, + ); + c + } + pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> { let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id); let c = ty::Const::from_anon_const(self.tcx, const_def_id); @@ -5655,7 +5680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.to_ty(ty).into() } (GenericParamDefKind::Const, GenericArg::Const(ct)) => { - self.to_const(&ct.value).into() + self.const_arg_to_const(&ct.value, param.def_id).into() } _ => unreachable!(), }, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d1a86a7ee89a8..20736baf19119 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -422,8 +422,11 @@ fn check_type_defn<'tcx, F>( fcx.register_predicate(traits::Obligation::new( cause, fcx.param_env, - ty::PredicateKind::ConstEvaluatable(discr_def_id.to_def_id(), discr_substs) - .to_predicate(fcx.tcx), + ty::PredicateKind::ConstEvaluatable( + fcx.tcx.with_opt_param(discr_def_id.to_def_id()), + discr_substs, + ) + .to_predicate(fcx.tcx), )); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fb9e462893328..5f068ff06a77b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1460,7 +1460,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { | Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), ident, .. }) => { match get_infer_ret_ty(&sig.decl.output) { Some(ty) => { - let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id]; + let fn_sig = tcx + .typeck_tables_of(tcx.with_opt_param(def_id)) + .liberated_fn_sigs()[hir_id]; let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0); diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index e9e6a0731282f..7c7d416f5480a 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -36,7 +36,7 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { .. }) => { let body_owner = tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id)); - let tables = tcx.typeck_tables_of(body_owner.to_def_id()); + let tables = tcx.typeck_tables_of(tcx.with_opt_param(body_owner)); // This may fail in case the method/path does not actually exist. // As there is no relevant param for `def_id`, we simply return // `None` here. @@ -74,8 +74,9 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { | ExprKind::Struct(&QPath::Resolved(_, path), ..), .. }) => { - let body_owner = tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id)); - let _tables = tcx.typeck_tables_of(body_owner.to_def_id()); + let body_owner = + tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id)); + let _tables = tcx.typeck_tables_of(tcx.with_opt_param(body_owner)); &*path } _ => span_bug!(DUMMY_SP, "unexpected const parent path {:?}", parent_node), @@ -220,7 +221,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => { let concrete_ty = tcx - .mir_borrowck(owner.expect_local()) + .mir_borrowck(tcx.with_opt_param(owner.expect_local())) .concrete_opaque_types .get(&def_id) .map(|opaque| opaque.concrete_type) @@ -232,8 +233,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { owner, def_id, ), ); - if let Some(ErrorReported) = - tcx.typeck_tables_of(owner.expect_local()).tainted_by_errors + if let Some(ErrorReported) = tcx + .typeck_tables_of(tcx.with_opt_param(owner.expect_local())) + .tainted_by_errors { // Some error in the // owner fn prevented us from populating @@ -426,7 +428,12 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } // Calling `mir_borrowck` can lead to cycle errors through // const-checking, avoid calling it if we don't have to. - if !self.tcx.typeck_tables_of(def_id).concrete_opaque_types.contains_key(&self.def_id) { + if !self + .tcx + .typeck_tables_of(self.tcx.with_opt_param(def_id)) + .concrete_opaque_types + .contains_key(&self.def_id) + { debug!( "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`", self.def_id, def_id, @@ -434,7 +441,11 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { return; } // Use borrowck to get the type with unerased regions. - let ty = self.tcx.mir_borrowck(def_id).concrete_opaque_types.get(&self.def_id); + let ty = self + .tcx + .mir_borrowck(self.tcx.with_opt_param(def_id)) + .concrete_opaque_types + .get(&self.def_id); if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty { debug!( "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}", @@ -610,7 +621,7 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty let opaque_ty_def_id = opaque_ty_id.to_def_id(); - let owner_tables = tcx.typeck_tables_of(scope_def_id); + let owner_tables = tcx.typeck_tables_of(tcx.with_opt_param(scope_def_id)); let concrete_ty = owner_tables .concrete_opaque_types .get(&opaque_ty_def_id) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 8d8a1b4d96761..118c534860d69 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -364,6 +364,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(LOCAL_CRATE)); + tcx.sess.time("compute_const_params_of", || check::compute_const_params_of(tcx)); + check_unused::check_crate(tcx); check_for_entry_fn(tcx); From 88cf2bf3a3d607bc065c19c88d1869a5a70a5e28 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 4 May 2020 11:24:11 +0200 Subject: [PATCH 04/14] update rustdoc --- src/librustdoc/clean/utils.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index c4e4802db6c07..faad619e59047 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -466,12 +466,12 @@ pub fn name_from_pat(p: &hir::Pat) -> String { pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(def_id, _, promoted) => { - let mut s = if let Some(def_id) = def_id.as_local() { + ty::ConstKind::Unevaluated(def, _, promoted) => { + let mut s = if let Some(def_id) = def.did.as_local() { let hir_id = cx.tcx.hir().as_local_hir_id(def_id); print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) } else { - inline::print_inlined_const(cx, def_id) + inline::print_inlined_const(cx, def.did) }; if let Some(promoted) = promoted { s.push_str(&format!("::{:?}", promoted)) From 3df37a4726d3b00ec5405bd200d5949c3257dfb3 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 4 May 2020 11:24:26 +0200 Subject: [PATCH 05/14] update clippy --- src/tools/clippy/clippy_lints/src/await_holding_lock.rs | 2 +- src/tools/clippy/clippy_lints/src/consts.rs | 2 +- src/tools/clippy/clippy_lints/src/doc.rs | 2 +- src/tools/clippy/clippy_lints/src/fallible_impl_from.rs | 2 +- src/tools/clippy/clippy_lints/src/functions.rs | 4 ++-- src/tools/clippy/clippy_lints/src/implicit_return.rs | 2 +- src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs | 2 +- src/tools/clippy/clippy_lints/src/redundant_clone.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/mod.rs | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/await_holding_lock.rs b/src/tools/clippy/clippy_lints/src/await_holding_lock.rs index a88f922d8e03d..d37dbed1d5920 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_lock.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_lock.rs @@ -59,7 +59,7 @@ impl LateLintPass<'_, '_> for AwaitHoldingLock { hir_id: body.value.hir_id, }; let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let tables = cx.tcx.typeck_tables_of(def_id); + let tables = cx.tcx.typeck_tables_of(cx.tcx.with_opt_param(def_id)); check_interior_types(cx, &tables.generator_interior_types, body.value.span); } } diff --git a/src/tools/clippy/clippy_lints/src/consts.rs b/src/tools/clippy/clippy_lints/src/consts.rs index 22c5acca064e9..6e5ea04d035ed 100644 --- a/src/tools/clippy/clippy_lints/src/consts.rs +++ b/src/tools/clippy/clippy_lints/src/consts.rs @@ -332,7 +332,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { let result = self .lcx .tcx - .const_eval_resolve(self.param_env, def_id, substs, None, None) + .const_eval_resolve(self.param_env, self.lcx.tcx.with_opt_param(def_id), substs, None, None) .ok() .map(|val| rustc_middle::ty::Const::from_value(self.lcx.tcx, val, ty))?; let result = miri_to_const(&result); diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 8d1e91f9adbd6..dd8e8557bb786 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -229,7 +229,7 @@ fn lint_for_missing_headers<'a, 'tcx>( if let Some(body_id) = body_id; if let Some(future) = cx.tcx.lang_items().future_trait(); let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); + let mir = cx.tcx.optimized_mir(cx.tcx.with_opt_param(def_id.to_def_id())); let ret_ty = mir.return_ty(); if implements_trait(cx, ret_ty, future, &[]); if let ty::Opaque(_, subs) = ret_ty.kind; diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 92812816461c5..0c2a9bcf337f7 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -124,7 +124,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it let impl_item_def_id = cx.tcx.hir().local_def_id(impl_item.id.hir_id); let mut fpu = FindPanicUnwrap { lcx: cx, - tables: cx.tcx.typeck_tables_of(impl_item_def_id), + tables: cx.tcx.typeck_tables_of(cx.tcx.with_opt_param(impl_item_def_id)), result: Vec::new(), }; fpu.visit_expr(&body.value); diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs index 1f9bd7a691b52..9ea0c31899528 100644 --- a/src/tools/clippy/clippy_lints/src/functions.rs +++ b/src/tools/clippy/clippy_lints/src/functions.rs @@ -497,7 +497,7 @@ fn is_mutable_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, tys: &mut FxHash if cx.tcx.has_typeck_tables(def_id) { is_mutable_ty( cx, - &cx.tcx.typeck_tables_of(def_id.expect_local()).pat_ty(pat), + &cx.tcx.typeck_tables_of(cx.tcx.with_opt_param(def_id.expect_local())).pat_ty(pat), pat.span, tys, ) @@ -617,7 +617,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> { if self.cx.tcx.has_typeck_tables(def_id) && is_mutable_ty( self.cx, - self.cx.tcx.typeck_tables_of(def_id.expect_local()).expr_ty(arg), + self.cx.tcx.typeck_tables_of(self.cx.tcx.with_opt_param(def_id.expect_local())).expr_ty(arg), arg.span, &mut tys, ) diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs index c4308fd26a302..bd54c90024850 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_return.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn { return; } - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); + let mir = cx.tcx.optimized_mir(cx.tcx.with_opt_param(def_id.to_def_id())); // checking return type through MIR, HIR is not able to determine inferred closure return types // make sure it's not a macro diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 9cfc8d1913497..2470afc70e5e2 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn { FnKind::Closure(..) => return, } - let mir = cx.tcx.optimized_mir(def_id); + let mir = cx.tcx.optimized_mir(cx.tcx.with_opt_param(def_id.to_def_id())); if let Err((span, err)) = is_min_const_fn(cx.tcx, def_id.to_def_id(), &mir) { if rustc_mir::const_eval::is_min_const_fn(cx.tcx, def_id.to_def_id()) { diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index d563eb886ae7e..4a7396e736989 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -84,7 +84,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone { return; } - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); + let mir = cx.tcx.optimized_mir(cx.tcx.with_opt_param(def_id.to_def_id())); let maybe_storage_live_result = MaybeStorageLive .into_engine(cx.tcx, mir, def_id.to_def_id()) diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 6d4c6c6ce1cea..da4f41dfeab9b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -291,7 +291,7 @@ pub fn qpath_res(cx: &LateContext<'_, '_>, qpath: &hir::QPath<'_>, id: hir::HirI hir::QPath::TypeRelative(..) => { if cx.tcx.has_typeck_tables(id.owner.to_def_id()) { cx.tcx - .typeck_tables_of(id.owner.to_def_id().expect_local()) + .typeck_tables_of(cx.tcx.with_opt_param(id.owner)) .qpath_res(qpath, id) } else { Res::Err From 2c6e561baeb0f56cc5969606f0596613c82a722e Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 4 May 2020 11:24:41 +0200 Subject: [PATCH 06/14] update mir-opt tests --- .../rustc.BAR.PromoteTemps.diff | 4 ++-- .../rustc.FOO.PromoteTemps.diff | 4 ++-- .../32bit/rustc.main.ConstProp.diff | 4 ++-- .../64bit/rustc.main.ConstProp.diff | 4 ++-- .../const_prop_fails_gracefully/rustc.main.ConstProp.diff | 4 ++-- .../rustc.hello.ConstProp.diff | 4 ++-- .../const_prop/ref_deref/rustc.main.ConstProp.diff | 4 ++-- .../const_prop/ref_deref/rustc.main.PromoteTemps.diff | 4 ++-- .../ref_deref_project/rustc.main.ConstProp.diff | 4 ++-- .../ref_deref_project/rustc.main.PromoteTemps.diff | 4 ++-- .../const_prop/slice_len/32bit/rustc.main.ConstProp.diff | 4 ++-- .../const_prop/slice_len/64bit/rustc.main.ConstProp.diff | 4 ++-- .../inline/inline-retag/rustc.bar.Inline.after.mir | 8 ++++---- .../rustc.full_tested_match.PromoteTemps.after.mir | 4 ++-- .../rustc.main.SimplifyCfg-elaborate-drops.after.mir | 4 ++-- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff b/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff index 5c192979a8696..a39ad96739205 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff @@ -22,7 +22,7 @@ - // + ty: &i32 - // + val: Value(Scalar(alloc0)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), [], Some(promoted[0])) ++ // + val: Unevaluated(WithOptParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) } @@ -30,7 +30,7 @@ - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 + // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), [], Some(promoted[0])) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), param_did: None }, [], Some(promoted[0])) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44 diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff b/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff index 649cea6493e45..e9ca064129947 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff @@ -24,7 +24,7 @@ - // + ty: &i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), [], Some(promoted[0])) ++ // + val: Unevaluated(WithOptParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) } @@ -32,7 +32,7 @@ - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 + // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), [], Some(promoted[0])) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), param_did: None }, [], Some(promoted[0])) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff index 7ceec94d81e76..077854554088a 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff @@ -28,10 +28,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 - // + literal: Const { ty: &[i32; 3], val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff index 483a6f232ef79..022c97fb3e2ca 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff @@ -28,10 +28,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 - // + literal: Const { ty: &[i32; 3], val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff index 6c5fe7454b4ed..b09bbead4105d 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff @@ -19,10 +19,10 @@ _3 = const main::FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 // ty::Const // + ty: &i32 - // + val: Unevaluated(DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), [], None) + // + val: Unevaluated(WithOptParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), param_did: None }, [], None) // mir::Constant // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 - // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), [], None) } + // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), param_did: None }, [], None) } _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 _1 = move _2 as usize (Misc); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39 StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39 diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff index b4d1f087391f3..d8be755632feb 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff @@ -12,11 +12,11 @@ + _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21 // ty::Const // + ty: bool -- // + val: Unevaluated(DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), [bool], None) +- // + val: Unevaluated(WithOptParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), param_did: None }, [bool], None) + // + val: Value(Scalar(0x00)) // mir::Constant // + span: $DIR/control-flow-simplification.rs:12:8: 12:21 -- // + literal: Const { ty: bool, val: Unevaluated(DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), [bool], None) } +- // + literal: Const { ty: bool, val: Unevaluated(WithOptParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), param_did: None }, [bool], None) } - switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6 + // + literal: Const { ty: bool, val: Value(Scalar(0x00)) } + switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6 diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff index dcd3d4019811e..2c8fe3e63b28f 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff @@ -14,10 +14,10 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 // ty::Const // + ty: &i32 - // + val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref.rs:5:6: 5:10 - // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 - _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 + _1 = const 4i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff index ef696f1ab8052..f042b5319add6 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff @@ -18,13 +18,13 @@ - // + ty: i32 - // + val: Value(Scalar(0x00000004)) + // + ty: &i32 -+ // + val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) ++ // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/ref_deref.rs:5:8: 5:9 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } - _2 = &_3; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 + // + span: $DIR/ref_deref.rs:5:6: 5:10 -+ // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) } ++ // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } + _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 - StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11 diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff index dd2f5bd906428..7ce4635eeb588 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff @@ -14,10 +14,10 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 // ty::Const // + ty: &(i32, i32) - // + val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref_project.rs:5:6: 5:17 - // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff index 7f23f5ea7a69a..60b784f3ac37b 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff @@ -18,7 +18,7 @@ - // + ty: i32 - // + val: Value(Scalar(0x00000004)) + // + ty: &(i32, i32) -+ // + val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) ++ // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/ref_deref_project.rs:5:9: 5:10 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } @@ -30,7 +30,7 @@ - // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) } - _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 + // + span: $DIR/ref_deref_project.rs:5:6: 5:17 -+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) } ++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } + _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 - StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 diff --git a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff index 9471dbef410d1..5c7ad17739891 100644 --- a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff @@ -21,10 +21,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19 diff --git a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff index 3ae88e0d79863..a48a065d18854 100644 --- a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff @@ -21,10 +21,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19 diff --git a/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir b/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir index e83cc92eb43ef..2149200cefb9c 100644 --- a/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir @@ -38,10 +38,10 @@ fn bar() -> bool { _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 // ty::Const // + ty: &i32 - // + val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[1])) + // + val: Unevaluated(WithOptParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), param_did: None }, [], Some(promoted[1])) // mir::Constant // + span: $DIR/inline-retag.rs:12:7: 12:9 - // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[1])) } + // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), param_did: None }, [], Some(promoted[1])) } Retag(_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 Retag(_4); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 @@ -52,10 +52,10 @@ fn bar() -> bool { _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 // ty::Const // + ty: &i32 - // + val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/inline-retag.rs:12:11: 12:14 - // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), param_did: None }, [], Some(promoted[0])) } Retag(_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 Retag(_7); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir index 3e1dec697b76f..83aeceea1e6d2 100644 --- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir @@ -76,10 +76,10 @@ fn full_tested_match() -> () { _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15 // ty::Const // + ty: &std::option::Option - // + val: Unevaluated(DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/match_false_edges.rs:16:14: 16:15 - // + literal: Const { ty: &std::option::Option, val: Unevaluated(DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &std::option::Option, val: Unevaluated(WithOptParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), param_did: None }, [], Some(promoted[0])) } _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15 _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27 diff --git a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir index c8c5da37abe32..67df09f18b475 100644 --- a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -184,10 +184,10 @@ fn main() -> () { _27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23 // ty::Const // + ty: &i32 - // + val: Unevaluated(DefId(0:13 ~ retag[317d]::main[0]), [], Some(promoted[0])) + // + val: Unevaluated(WithOptParam { did: DefId(0:13 ~ retag[317d]::main[0]), param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $DIR/retag.rs:47:21: 47:23 - // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:13 ~ retag[317d]::main[0]), [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(WithOptParam { did: DefId(0:13 ~ retag[317d]::main[0]), param_did: None }, [], Some(promoted[0])) } Retag(_27); // scope 7 at $DIR/retag.rs:47:21: 47:23 _23 = &(*_27); // scope 7 at $DIR/retag.rs:47:21: 47:23 Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23 From cc7a6d1e39e103730b5b657267868f2d11e460a5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 4 May 2020 11:24:53 +0200 Subject: [PATCH 07/14] add tests for type dependent paths --- .../type-dependent/const-arg-in-const-arg.rs | 26 ++++++++++ .../type-dependent/issue-61936.rs | 47 +++++++++++++++++++ .../type-dependent/issue-63695.rs | 17 +++++++ .../type-dependent/issue-69816.rs | 20 ++++++++ .../type-dependent/issue-70507.rs | 47 +++++++++++++++++++ .../type-dependent/issue-71382.rs | 25 ++++++++++ .../ui/const-generics/type-dependent/qpath.rs | 12 +++++ .../const-generics/type-dependent/simple.rs | 12 +++++ .../type-dependent/type-mismatch.rs | 12 +++++ .../type-dependent/type-mismatch.stderr | 23 +++++++++ 10 files changed, 241 insertions(+) create mode 100644 src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs create mode 100644 src/test/ui/const-generics/type-dependent/issue-61936.rs create mode 100644 src/test/ui/const-generics/type-dependent/issue-63695.rs create mode 100644 src/test/ui/const-generics/type-dependent/issue-69816.rs create mode 100644 src/test/ui/const-generics/type-dependent/issue-70507.rs create mode 100644 src/test/ui/const-generics/type-dependent/issue-71382.rs create mode 100644 src/test/ui/const-generics/type-dependent/qpath.rs create mode 100644 src/test/ui/const-generics/type-dependent/simple.rs create mode 100644 src/test/ui/const-generics/type-dependent/type-mismatch.rs create mode 100644 src/test/ui/const-generics/type-dependent/type-mismatch.stderr diff --git a/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs new file mode 100644 index 0000000000000..ae50252facd25 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs @@ -0,0 +1,26 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] +#![feature(const_fn)] + +struct Foo; + +impl Foo { + fn foo(&self) -> usize { + let f = self; + f.bar::<{ + let f = Foo; + f.bar::<7>() + }>() + N + } + + const fn bar(&self) -> usize { + M + } +} + +fn main() { + let f = Foo; + + assert_eq!(f.foo::<13>(), 20) +} diff --git a/src/test/ui/const-generics/type-dependent/issue-61936.rs b/src/test/ui/const-generics/type-dependent/issue-61936.rs new file mode 100644 index 0000000000000..2dd6c0cd24191 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-61936.rs @@ -0,0 +1,47 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait SliceExt { + fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>; +} + +impl SliceExt for [T] { + fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> { + ArrayWindows{ idx: 0, slice: &self } + } +} + +struct ArrayWindows<'a, T, const N: usize> { + slice: &'a [T], + idx: usize, +} + +impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> { + type Item = [T; N]; + fn next(&mut self) -> Option { + let mut res = unsafe{ std::mem::zeroed() }; + let mut ptr = &mut res as *mut [T; N] as *mut T; + + for i in 0..N { + match self.slice[i..].get(i) { + None => return None, + Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())}, + }; + ptr = ptr.wrapping_add(1); + self.idx += 1; + } + + Some(res) + } +} + +const FOUR: usize = 4; + +fn main() { + let v: Vec = vec![100; 0usize]; + + for array in v.as_slice().array_windows::() { + assert_eq!(array, [0, 0, 0, 0]) + } +} diff --git a/src/test/ui/const-generics/type-dependent/issue-63695.rs b/src/test/ui/const-generics/type-dependent/issue-63695.rs new file mode 100644 index 0000000000000..f3c2e1775940f --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-63695.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait T { + fn test(&self) -> i32 { A } +} + +struct S(); + +impl T for S {} + +fn main() { + let foo = S(); + assert_eq!(foo.test::<8i32>(), 8); + assert_eq!(foo.test::<16i32>(), 16); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-69816.rs b/src/test/ui/const-generics/type-dependent/issue-69816.rs new file mode 100644 index 0000000000000..cbe86cef3230f --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-69816.rs @@ -0,0 +1,20 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait IterExt: Sized + Iterator { + fn default_for_size(self) -> [Self::Item; N] + where + [Self::Item; N]: Default, + { + Default::default() + } +} + +impl IterExt for T {} + +fn main(){ + const N: usize = 10; + let arr = (0u32..10).default_for_size::(); + assert_eq!(arr, [0; 10]); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-70507.rs b/src/test/ui/const-generics/type-dependent/issue-70507.rs new file mode 100644 index 0000000000000..6fcf4116d437c --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-70507.rs @@ -0,0 +1,47 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait ConstChunksExactTrait { + fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, {N}>; +} + +impl ConstChunksExactTrait for [T] { + fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, {N}> { + assert!(N != 0); + let rem = self.len() % N; + let len = self.len() - rem; + let (fst, _) = self.split_at(len); + ConstChunksExact { v: fst, } + } +} + +struct ConstChunksExact<'a, T: 'a, const N: usize> { + v: &'a [T], +} + +impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> { + type Item = &'a [T; N]; + + fn next(&mut self) -> Option { + if self.v.len() < N { + None + } else { + let (fst, snd) = self.v.split_at(N); + + self.v = snd; + let ptr = fst.as_ptr() as *const _; + Some(unsafe { &*ptr}) + } + } +} + +fn main() { + let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter(); + + for a in slice.const_chunks_exact::<3>() { + assert_eq!(a, iter.next().unwrap()); + } +} diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs new file mode 100644 index 0000000000000..3c9887a656b83 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs @@ -0,0 +1,25 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] +#![feature(const_compare_raw_pointers)] + +struct Test; + +fn pass() -> u8 { + 42 +} + +impl Test { + pub fn call_me(&self) -> u8 { + self.test::() + } + + fn test u8>(&self) -> u8 { + FN() + } +} + +fn main() { + let x = Test; + assert_eq!(x.call_me(), 42); +} diff --git a/src/test/ui/const-generics/type-dependent/qpath.rs b/src/test/ui/const-generics/type-dependent/qpath.rs new file mode 100644 index 0000000000000..f3f98e5faf52d --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/qpath.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct A; +impl A { + fn foo() -> usize { N + 1 } +} + +fn main() { + assert_eq!(A::foo::<7>(), 8); +} diff --git a/src/test/ui/const-generics/type-dependent/simple.rs b/src/test/ui/const-generics/type-dependent/simple.rs new file mode 100644 index 0000000000000..cc7c50d8fd835 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/simple.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct R; + +impl R { + fn method(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u8>(), 1); +} diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.rs b/src/test/ui/const-generics/type-dependent/type-mismatch.rs new file mode 100644 index 0000000000000..0c71f338bd262 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete + +struct R; + +impl R { + fn method(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u16>(), 1); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.stderr new file mode 100644 index 0000000000000..5bb7c5b0ea9bf --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.stderr @@ -0,0 +1,23 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-mismatch.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:10:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL | assert_eq!(R.method::<1u8>(), 1); + | ^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. From 19d9fd5796e04247a8b4a252b0994b32f37af579 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 25 May 2020 16:12:30 +0200 Subject: [PATCH 08/14] fix ice on unknown const arg parent --- src/librustc_typeck/collect/type_of.rs | 6 +++++- src/test/ui/const-generics/unknown_adt.rs | 7 +++++++ src/test/ui/const-generics/unknown_adt.stderr | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-generics/unknown_adt.rs create mode 100644 src/test/ui/const-generics/unknown_adt.stderr diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 7c7d416f5480a..e1987bfaa695f 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -108,7 +108,11 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { tcx.generics_of(tcx.parent(def_id).unwrap()) } Res::Def(_, def_id) => tcx.generics_of(def_id), - res => span_bug!( + Res::Err => { + tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err"); + return None; + } + _ => span_bug!( DUMMY_SP, "unexpected anon const res {:?} in path: {:?}", res, diff --git a/src/test/ui/const-generics/unknown_adt.rs b/src/test/ui/const-generics/unknown_adt.rs new file mode 100644 index 0000000000000..0ba9945b399ae --- /dev/null +++ b/src/test/ui/const-generics/unknown_adt.rs @@ -0,0 +1,7 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +fn main() { + let _: UnknownStruct<7>; + //~^ ERROR cannot find type `UnknownStruct` +} diff --git a/src/test/ui/const-generics/unknown_adt.stderr b/src/test/ui/const-generics/unknown_adt.stderr new file mode 100644 index 0000000000000..b2e287b762c69 --- /dev/null +++ b/src/test/ui/const-generics/unknown_adt.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `UnknownStruct` in this scope + --> $DIR/unknown_adt.rs:5:12 + | +LL | let _: UnknownStruct<7>; + | ^^^^^^^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From 0b5aa1b8328922fff9655b61c80fc5638bfe1e8d Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 5 Jun 2020 23:50:19 +0200 Subject: [PATCH 09/14] manually impl more traits for WithOptParam --- src/librustc_middle/ty/mod.rs | 18 +++++++++++-- src/librustc_middle/ty/structural_impls.rs | 30 ++++++++++++---------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 4d1e8ab33c7d0..8875d7053c141 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1576,7 +1576,7 @@ pub type PlaceholderConst = Placeholder; /// Luckily we only need to deal with const arguments once we /// know their corresponding parameters. We (ab)use this by /// calling `type_of(param_did)` for these arguments. -#[derive(Copy, Clone, Debug, Hash, HashStable, TypeFoldable, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub struct WithOptParam { pub did: T, /// The `DefId` of the corresponding generic paramter in case `did` is @@ -1586,13 +1586,27 @@ pub struct WithOptParam { pub param_did: Option, } -// We manually implement comparisions as the `param_did` can be ignored. +// We manually implement most traits for `WithOptParam` +// as the `param_did` is redundant. + impl PartialEq for WithOptParam { fn eq(&self, other: &Self) -> bool { self.did == other.did } } +impl Hash for WithOptParam { + fn hash(&self, state: &mut H) { + self.did.hash(state); + } +} + +impl> HashStable for WithOptParam { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + self.did.hash_stable(hcx, hasher); + } +} + impl Eq for WithOptParam {} impl PartialOrd for WithOptParam { diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 451a8a7760d05..7304c3407bddb 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -261,23 +261,23 @@ CloneTypeFoldableAndLiftImpls! { (), bool, usize, - ::rustc_target::abi::VariantIdx, + rustc_target::abi::VariantIdx, u64, String, crate::middle::region::Scope, - ::rustc_ast::ast::FloatTy, - ::rustc_ast::ast::InlineAsmOptions, - ::rustc_ast::ast::InlineAsmTemplatePiece, - ::rustc_ast::ast::NodeId, - ::rustc_span::symbol::Symbol, - ::rustc_hir::def::Res, - ::rustc_hir::def_id::DefId, - ::rustc_hir::LlvmInlineAsmInner, - ::rustc_hir::MatchSource, - ::rustc_hir::Mutability, - ::rustc_hir::Unsafety, - ::rustc_target::asm::InlineAsmRegOrRegClass, - ::rustc_target::spec::abi::Abi, + rustc_ast::ast::FloatTy, + rustc_ast::ast::InlineAsmOptions, + rustc_ast::ast::InlineAsmTemplatePiece, + rustc_ast::ast::NodeId, + rustc_span::symbol::Symbol, + rustc_hir::def::Res, + rustc_hir::def_id::DefId, + rustc_hir::LlvmInlineAsmInner, + rustc_hir::MatchSource, + rustc_hir::Mutability, + rustc_hir::Unsafety, + rustc_target::asm::InlineAsmRegOrRegClass, + rustc_target::spec::abi::Abi, crate::mir::Local, crate::mir::Promoted, crate::traits::Reveal, @@ -299,6 +299,8 @@ CloneTypeFoldableAndLiftImpls! { crate::ty::RegionVid, crate::ty::UniverseIndex, crate::ty::Variance, + crate::ty::WithOptParam, + crate::ty::WithOptParam, ::rustc_span::Span, } From 29ffa5550e22900d851c7e6c42df18594b5d145a Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 16 Jun 2020 20:59:20 +0200 Subject: [PATCH 10/14] add test for extern crates --- .../auxiliary/type_dependent_lib.rs | 36 +++++++++++++++++++ .../type-dependent/non-local.rs | 24 +++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs create mode 100644 src/test/ui/const-generics/type-dependent/non-local.rs diff --git a/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs new file mode 100644 index 0000000000000..c8db91b62b58c --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs @@ -0,0 +1,36 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +pub struct Struct(()); + +impl Struct { + pub fn new() -> Self { + Struct(()) + } + + pub fn same_ty(&self) -> (usize, usize) { + (N, M) + } + + pub fn different_ty(&self) -> (usize, u8) { + (N, M) + } + + pub fn containing_ty(&self) -> (usize, u8) { + (std::mem::size_of::() + N, M) + } + + pub fn we_have_to_go_deeper(&self) -> Struct { + Struct(()) + } +} + +pub trait Foo { + fn foo(&self) -> usize; +} + +impl Foo for Struct<7> { + fn foo(&self) -> usize { + M + } +} diff --git a/src/test/ui/const-generics/type-dependent/non-local.rs b/src/test/ui/const-generics/type-dependent/non-local.rs new file mode 100644 index 0000000000000..e6f3eb075f1da --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/non-local.rs @@ -0,0 +1,24 @@ +// aux-build:type_dependent_lib.rs +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +extern crate type_dependent_lib; + +use type_dependent_lib::*; + +fn main() { + let s = Struct::<42>::new(); + assert_eq!(s.same_ty::<7>(), (42, 7)); + assert_eq!(s.different_ty::<19>(), (42, 19)); + assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96)); + assert_eq!( + Struct::<18>::new() + .we_have_to_go_deeper::<19>() + .containing_ty::, 3>(), + (27, 3), + ); + + let s = Struct::<7>::new(); + assert_eq!(s.foo::<18>(), 18); +} From ae74817dc363d4272263c6b82cf02a8a10c1d9d5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 16 Jun 2020 21:03:12 +0200 Subject: [PATCH 11/14] cleanup --- src/librustc_middle/dep_graph/dep_node.rs | 1 + src/librustc_middle/query/mod.rs | 8 ++++++-- src/librustc_middle/ty/mod.rs | 1 + src/librustc_middle/ty/structural_impls.rs | 4 +--- src/librustc_typeck/collect/type_of.rs | 5 ++++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs index 2cbdb508e4d09..b4447b6205c90 100644 --- a/src/librustc_middle/dep_graph/dep_node.rs +++ b/src/librustc_middle/dep_graph/dep_node.rs @@ -379,6 +379,7 @@ impl<'tcx> DepNodeParams> for ty::WithOptParam { dep_node.extract_def_id(tcx).map(|def_id| tcx.with_opt_param(def_id)) } } + impl<'tcx> DepNodeParams> for ty::WithOptParam { #[inline] fn can_reconstruct_query_key() -> bool { diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 14f9232169a57..c4eefc8b1cfc7 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -89,8 +89,8 @@ rustc_queries! { desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } } - /// Computes the `DefId` of the corresponding const parameter of a const argument. - /// Returns `None` if `def_id` is not a const argument. + /// Computes the `DefId` of the corresponding const parameter in case the `key` is a + /// const argument and returns `None` otherwise. /// /// ```rust /// let a = foo::<7>(); @@ -98,6 +98,10 @@ rustc_queries! { /// /// fn foo() /// // ^ returns this `DefId`. + /// + /// fn bar() { + /// // ^ While calling `const_param_of` for other bodies returns `None`. + /// } /// ``` query const_param_of(key: DefId) -> Option { cache_on_disk_if { key.is_local() } diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 8875d7053c141..fd01905b5edfc 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1622,6 +1622,7 @@ impl Ord for WithOptParam { } impl<'tcx> TyCtxt<'tcx> { + #[inline(always)] pub fn with_opt_param + Copy>(self, did: T) -> WithOptParam { WithOptParam { did, param_did: self.const_param_of(did) } } diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 7304c3407bddb..09f508a95c292 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -844,9 +844,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { Self { substs: self.substs.fold_with(folder), def: match self.def { - // We don't fold the param `DefId` here, - // as it should only be used for `type_of`. - Item(did, param_did) => Item(did.fold_with(folder), param_did), + Item(did, param_did) => Item(did.fold_with(folder), param_did.fold_with(folder)), VtableShim(did) => VtableShim(did.fold_with(folder)), ReifyShim(did) => ReifyShim(did.fold_with(folder)), Intrinsic(did) => Intrinsic(did.fold_with(folder)), diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index e1987bfaa695f..c2d2300eaae6f 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -17,6 +17,9 @@ use rustc_trait_selection::traits; use super::ItemCtxt; use super::{bad_placeholder_type, is_suggestable_infer_ty}; +/// Computes the relevant generic parameter for a potential generic const argument. +/// +/// This should be called using the query `tcx.const_param_of`. pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { use hir::*; @@ -127,7 +130,7 @@ pub(super) fn const_param_of(tcx: TyCtxt<'_>, def_id: DefId) -> Option { .nth(arg_index) .map(|param| param.def_id) } - _ => return None, + _ => None, } } else { None From 2ada8e341ed522748b01dd9a7392f378816722ca Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 26 Jun 2020 12:57:13 +0200 Subject: [PATCH 12/14] wip --- src/librustc_middle/ty/mod.rs | 39 ++--------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index fd01905b5edfc..5053a590ecfd9 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1577,50 +1577,15 @@ pub type PlaceholderConst = Placeholder; /// know their corresponding parameters. We (ab)use this by /// calling `type_of(param_did)` for these arguments. #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +#[derive(Hash, HashStable)] pub struct WithOptParam { pub did: T, /// The `DefId` of the corresponding generic paramter in case `did` is /// a const argument. - /// - /// This must always be equal to `tcx.const_param_of(did)`. pub param_did: Option, } -// We manually implement most traits for `WithOptParam` -// as the `param_did` is redundant. - -impl PartialEq for WithOptParam { - fn eq(&self, other: &Self) -> bool { - self.did == other.did - } -} - -impl Hash for WithOptParam { - fn hash(&self, state: &mut H) { - self.did.hash(state); - } -} - -impl> HashStable for WithOptParam { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - self.did.hash_stable(hcx, hasher); - } -} - -impl Eq for WithOptParam {} - -impl PartialOrd for WithOptParam { - fn partial_cmp(&self, other: &Self) -> Option { - self.did.partial_cmp(&other.did) - } -} - -impl Ord for WithOptParam { - fn cmp(&self, other: &Self) -> Ordering { - self.did.cmp(&other.did) - } -} - impl<'tcx> TyCtxt<'tcx> { #[inline(always)] pub fn with_opt_param + Copy>(self, did: T) -> WithOptParam { From ae7828a15e1b681eb7712d12cd246da112b90475 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 26 Jun 2020 14:00:55 +0200 Subject: [PATCH 13/14] who told you this was unsound! --- .../back/symbol_export.rs | 4 +- src/librustc_middle/mir/mono.rs | 4 +- src/librustc_middle/ty/instance.rs | 37 +++++++------------ src/librustc_middle/ty/mod.rs | 12 +++++- src/librustc_middle/ty/structural_impls.rs | 13 +++---- src/librustc_mir/const_eval/eval_queries.rs | 2 +- src/librustc_mir/const_eval/machine.rs | 4 +- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 3 +- src/librustc_mir/monomorphize/partitioning.rs | 5 ++- .../transform/check_consts/validation.rs | 4 +- src/librustc_mir/transform/mod.rs | 16 ++++---- src/librustc_mir/transform/promote_consts.rs | 2 +- src/librustc_mir/util/pretty.rs | 8 ++-- src/librustc_mir_build/hair/pattern/mod.rs | 2 +- src/librustc_ty/instance.rs | 4 +- 17 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 62442f0c87fcb..a2942c30d2bf1 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -249,9 +249,9 @@ fn exported_symbols_provider_local( } match *mono_item { - MonoItem::Fn(Instance { def: InstanceDef::Item(def_id, _), substs }) => { + MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => { if substs.non_erasable_generics().next().is_some() { - let symbol = ExportedSymbol::Generic(def_id, substs); + let symbol = ExportedSymbol::Generic(def.did, substs); symbols.push((symbol, SymbolExportLevel::Rust)); } } diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index c1df5bef2467e..d86762f4827d2 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -346,8 +346,8 @@ impl<'tcx> CodegenUnit<'tcx> { // instances into account. The others don't matter for // the codegen tests and can even make item order // unstable. - InstanceDef::Item(def_id, _) => { - def_id.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id)) + InstanceDef::Item(def) => { + def.did.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id)) } InstanceDef::VtableShim(..) | InstanceDef::ReifyShim(..) diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs index f7d6822037e2a..3cc33b422f58b 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/src/librustc_middle/ty/instance.rs @@ -160,8 +160,8 @@ impl<'tcx> Instance<'tcx> { self.substs.non_erasable_generics().next()?; match self.def { - InstanceDef::Item(def_id, _) => tcx - .upstream_monomorphizations_for(def_id) + InstanceDef::Item(def) => tcx + .upstream_monomorphizations_for(def.did) .and_then(|monos| monos.get(&self.substs).cloned()), InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs), _ => None, @@ -173,8 +173,8 @@ impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(&self) -> DefId { match *self { - InstanceDef::Item(def_id, _) - | InstanceDef::VtableShim(def_id) + InstanceDef::Item(def) => def.did, + InstanceDef::VtableShim(def_id) | InstanceDef::ReifyShim(def_id) | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) @@ -186,12 +186,8 @@ impl<'tcx> InstanceDef<'tcx> { } #[inline] - pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { - ty::WithOptParam { - did: self.def_id(), - param_did: if let InstanceDef::Item(_, param_did) = *self { param_did } else { None } - .or_else(|| tcx.const_param_of(self.def_id())), - } + pub fn with_opt_param(self) -> ty::WithOptParam { + if let InstanceDef::Item(def) = self { def } else { ty::WithOptParam::dummy(self.def_id()) } } #[inline] @@ -207,7 +203,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; let def_id = match *self { - ty::InstanceDef::Item(def_id, _) => def_id, + ty::InstanceDef::Item(def) => def.did, ty::InstanceDef::DropGlue(_, Some(_)) => return false, _ => return true, }; @@ -253,8 +249,8 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { - InstanceDef::Item(def_id, _) => { - tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) + InstanceDef::Item(def) => { + tcx.codegen_fn_attrs(def.did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } _ => false, } @@ -271,7 +267,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { })?; match self.def { - InstanceDef::Item(_, _) => Ok(()), + InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"), InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), @@ -292,7 +288,7 @@ impl<'tcx> Instance<'tcx> { did, substs ); - Instance { def: InstanceDef::Item(did, None), substs } + Instance { def: InstanceDef::Item(ty::WithOptParam::dummy(did)), substs } } pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { @@ -304,11 +300,6 @@ impl<'tcx> Instance<'tcx> { self.def.def_id() } - #[inline] - pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { - self.def.with_opt_param(tcx) - } - /// Identical to `resolve`, but may also take an optional `param_def_id` for /// generic const arguments. pub fn resolve_const_arg( @@ -378,9 +369,9 @@ impl<'tcx> Instance<'tcx> { debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| { match resolved.def { - InstanceDef::Item(def_id, _) if resolved.def.requires_caller_location(tcx) => { + InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceDef::ReifyShim(def_id); + resolved.def = InstanceDef::ReifyShim(def.did); } InstanceDef::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); @@ -476,7 +467,7 @@ impl<'tcx> Instance<'tcx> { | InstanceDef::DropGlue(..) // FIXME(#69925): `FnPtrShim` should be in the other branch. | InstanceDef::FnPtrShim(..) - | InstanceDef::Item(_, _) + | InstanceDef::Item(_) | InstanceDef::Intrinsic(..) | InstanceDef::ReifyShim(..) | InstanceDef::Virtual(..) diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 5053a590ecfd9..3a9c9249b7e90 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1583,17 +1583,25 @@ pub struct WithOptParam { pub did: T, /// The `DefId` of the corresponding generic paramter in case `did` is /// a const argument. + /// + /// If `param_did` is `Some` it must be equal to `tcx.const_param_of`, + /// and may otherwise cause panics or problems. pub param_did: Option, } impl<'tcx> TyCtxt<'tcx> { #[inline(always)] pub fn with_opt_param + Copy>(self, did: T) -> WithOptParam { - WithOptParam { did, param_did: self.const_param_of(did) } + WithOptParam { did, param_did: None } } } impl> WithOptParam { + /// Wraps the given `DefId` and sets `param_did` to none. + pub fn dummy(did: T) -> WithOptParam { + WithOptParam { did, param_did: None } + } + pub fn ty_def_id(self) -> DefId { self.param_did.unwrap_or(self.did.into_query_param()) } @@ -2790,7 +2798,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { match instance { - ty::InstanceDef::Item(_, _) => self.optimized_mir(instance.with_opt_param(self)), + ty::InstanceDef::Item(def) => self.optimized_mir(def), ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::Intrinsic(..) diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 09f508a95c292..4b4d9ef7a3457 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -672,7 +672,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { type Lifted = ty::InstanceDef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::InstanceDef::Item(did, param_did) => Some(ty::InstanceDef::Item(did, param_did)), + ty::InstanceDef::Item(did) => Some(ty::InstanceDef::Item(did)), ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)), ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)), ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), @@ -844,7 +844,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { Self { substs: self.substs.fold_with(folder), def: match self.def { - Item(did, param_did) => Item(did.fold_with(folder), param_did.fold_with(folder)), + Item(def) => Item(def.fold_with(folder)), VtableShim(did) => VtableShim(did.fold_with(folder)), ReifyShim(did) => ReifyShim(did.fold_with(folder)), Intrinsic(did) => Intrinsic(did.fold_with(folder)), @@ -863,11 +863,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { use crate::ty::InstanceDef::*; self.substs.visit_with(visitor) || match self.def { - Item(did, _) - | VtableShim(did) - | ReifyShim(did) - | Intrinsic(did) - | Virtual(did, _) => did.visit_with(visitor), + Item(def) => def.visit_with(visitor), + VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { + did.visit_with(visitor) + } FnPtrShim(did, ty) | CloneShim(did, ty) => { did.visit_with(visitor) || ty.visit_with(visitor) } diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index c6eb84733a99b..a014a2255b7a2 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -288,7 +288,7 @@ pub fn const_eval_raw_provider<'tcx>( } let cid = key.value; - let def = cid.instance.with_opt_param(tcx); + let def = cid.instance.def.with_opt_param(); if let Some(def) = def.as_local() { if tcx.has_typeck_tables(def.did) { diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index 1d1f160c6b63d..2693a82eadf19 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -191,11 +191,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, debug!("find_mir_or_eval_fn: {:?}", instance); // Only check non-glue functions - if let ty::InstanceDef::Item(def_id, _) = instance.def { + if let ty::InstanceDef::Item(def) = instance.def { // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here. But we can at least rule out functions that are not const // at all. - if ecx.tcx.is_const_fn_raw(def_id) { + if ecx.tcx.is_const_fn_raw(def.did) { // If this function is a `const fn` then under certain circumstances we // can evaluate call via the query system, thus memoizing all future calls. if ecx.try_eval_const_fn_call(instance, ret, args)? { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 2e8b1cfc18018..a5c237d138c2f 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -400,7 +400,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { promoted: Option, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { // do not continue if typeck errors occurred (can only occur in local crate) - let def = instance.with_opt_param(*self.tcx); + let def = instance.with_opt_param(); if let Some(def) = def.as_local() { if self.tcx.has_typeck_tables(def.did) { if let Some(error_reported) = self.tcx.typeck_tables_of(def).tainted_by_errors { @@ -413,7 +413,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(&self.tcx.promoted_mir(def)[promoted]); } match instance { - ty::InstanceDef::Item(_, _) => { + ty::InstanceDef::Item(_) => { if self.tcx.is_mir_available(def.did) { Ok(self.tcx.optimized_mir(def)) } else { diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 4906da19f3af3..4681079a22ddf 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -257,7 +257,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) - | ty::InstanceDef::Item(_, _) => { + | ty::InstanceDef::Item(_) => { // We need MIR for this fn let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? { Some(body) => body, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 913932b7f36b2..6a3e63eebf1e6 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -768,7 +768,8 @@ fn visit_instance_use<'tcx>( // need a mono item. fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { let def_id = match instance.def { - ty::InstanceDef::Item(def_id, _) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id, + ty::InstanceDef::Item(def) => def.did, + ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id, ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 55c7485ec325d..d9f127eb3f677 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -314,7 +314,8 @@ fn mono_item_visibility( }; let def_id = match instance.def { - InstanceDef::Item(def_id, _) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, + InstanceDef::Item(def) => def.did, + InstanceDef::DropGlue(def_id, Some(_)) => def_id, // These are all compiler glue and such, never exported, always hidden. InstanceDef::VtableShim(..) @@ -704,7 +705,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( match mono_item { MonoItem::Fn(instance) => { let def_id = match instance.def { - ty::InstanceDef::Item(def_id, _) => def_id, + ty::InstanceDef::Item(def) => def.did, ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::FnPtrShim(..) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 6aaf0fc39724e..a7c21debba410 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -537,8 +537,8 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { let instance = Instance::resolve(self.tcx, self.param_env, def_id, substs); debug!("Resolving ({:?}) -> {:?}", def_id, instance); if let Ok(Some(func)) = instance { - if let InstanceDef::Item(def_id, _) = func.def { - if is_const_fn(self.tcx, def_id) { + if let InstanceDef::Item(def) = func.def { + if is_const_fn(self.tcx, def.did) { return; } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index e826a57bb3e72..9236bd3a2d454 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -116,17 +116,17 @@ pub struct MirSource<'tcx> { impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { - MirSource { instance: InstanceDef::Item(def_id, None), promoted: None } + MirSource { instance: InstanceDef::Item(ty::WithOptParam::dummy(def_id)), promoted: None } } #[inline] - pub fn def_id(&self) -> DefId { + pub fn def_id(self) -> DefId { self.instance.def_id() } #[inline] - pub fn with_opt_param(&self, tcx: TyCtxt<'tcx>) -> ty::WithOptParam { - self.instance.with_opt_param(tcx) + pub fn with_opt_param(self) -> ty::WithOptParam { + self.instance.with_opt_param() } } @@ -264,7 +264,7 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptParam) -> Steal> { run_passes( tcx, &mut body, - InstanceDef::Item(def.did.to_def_id(), def.param_did), + InstanceDef::Item(def.to_global()), None, MirPhase::Const, &[&[ @@ -299,7 +299,7 @@ fn mir_validated( run_passes( tcx, &mut body, - InstanceDef::Item(def.did.to_def_id(), def.param_did), + InstanceDef::Item(def.to_global()), None, MirPhase::Validated, &[&[ @@ -365,7 +365,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>( run_passes( tcx, body, - InstanceDef::Item(def_id.to_def_id(), None), + InstanceDef::Item(ty::WithOptParam::dummy(def_id.to_def_id())), promoted, MirPhase::DropElab, &[post_borrowck_cleanup], @@ -429,7 +429,7 @@ fn run_optimization_passes<'tcx>( run_passes( tcx, body, - InstanceDef::Item(def_id.to_def_id(), None), + InstanceDef::Item(ty::WithOptParam::dummy(def_id.to_def_id())), promoted, MirPhase::Optimized, &[ diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 957efab74ab43..f6d6109e98387 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> { return; } - let def = src.with_opt_param(tcx); + let def = src.with_opt_param(); let mut rpo = traversal::reverse_postorder(body); let ccx = ConstCx::new(tcx, def.did.expect_local(), body); diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index f849d9f25e69a..1da0cad7de64e 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -235,7 +235,8 @@ pub fn write_mir_pretty<'tcx>( let mut first = true; for def_id in dump_mir_def_ids(tcx, single) { - let body = &tcx.optimized_mir(tcx.with_opt_param(def_id)); + let def = ty::WithOptParam::dummy(def_id); + let body = &tcx.optimized_mir(def); if first { first = false; @@ -246,10 +247,9 @@ pub fn write_mir_pretty<'tcx>( write_mir_fn(tcx, MirSource::item(def_id), body, &mut |_, _| Ok(()), w)?; - for (i, body) in tcx.promoted_mir(tcx.with_opt_param(def_id)).iter_enumerated() { + for (i, body) in tcx.promoted_mir(def).iter_enumerated() { writeln!(w)?; - let src = - MirSource { instance: ty::InstanceDef::Item(def_id, None), promoted: Some(i) }; + let src = MirSource { instance: ty::InstanceDef::Item(def), promoted: Some(i) }; write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?; } } diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 450bb9ebcd55f..93b2115925400 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -802,7 +802,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // defined, not where it is declared. The difference is significant for associated // constants. let mir_structural_match_violation = - self.tcx.mir_const_qualif(instance.with_opt_param(self.tcx)).custom_eq; + self.tcx.mir_const_qualif(instance.def.with_opt_param()).custom_eq; debug!("mir_structural_match_violation({:?}) -> {}", qpath, mir_structural_match_violation); match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) { diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs index 6f86fe33664ca..19c591fba7ff6 100644 --- a/src/librustc_ty/instance.rs +++ b/src/librustc_ty/instance.rs @@ -53,7 +53,7 @@ fn resolve_instance<'tcx>( } _ => { debug!(" => free item"); - ty::InstanceDef::Item(def.did, def.param_did) + ty::InstanceDef::Item(def) } }; Ok(Some(Instance { def, substs })) @@ -182,7 +182,7 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } traits::ImplSourceGenerator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(generator_data.generator_def_id, None), + def: ty::InstanceDef::Item(ty::WithOptParam::dummy(generator_data.generator_def_id)), substs: generator_data.substs, }), traits::ImplSourceClosure(closure_data) => { From a23a444d773fdd510a31da3efe987aa448dbf1ac Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 26 Jun 2020 14:27:08 +0200 Subject: [PATCH 14/14] fix rebase --- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/interpret/operand.rs | 2 +- .../transform/instrument_coverage.rs | 2 +- src/librustc_typeck/check/mod.rs | 7 ++++--- .../type-dependent/issue-71382.rs | 5 ++--- .../type-dependent/issue-71382.stderr | 17 +++++++++++++++++ 6 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/const-generics/type-dependent/issue-71382.stderr diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index a5c237d138c2f..dbc1d202003c5 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -454,7 +454,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { def_id: DefId, substs: SubstsRef<'tcx>, ) -> InterpResult<'tcx, ty::Instance<'tcx>> { - self.resolve_const_arg(self.tcx.with_opt_param(def_id), substs) + self.resolve_const_arg(ty::WithOptParam::dummy(def_id), substs) } pub(super) fn resolve_const_arg( diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index ad6b54f3c84ac..17b9c31d6b172 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -532,7 +532,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), ty::ConstKind::Unevaluated(def, substs, promoted) => { - let instance = self.resolve(def, substs)?; + let instance = self.resolve_const_arg(def, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. // The reason we use `const_eval_raw` everywhere else is to prevent cycles during // validation, because validation automatically reads through any references, thus diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs index 06b648ab5a908..8ba19fef2813d 100644 --- a/src/librustc_mir/transform/instrument_coverage.rs +++ b/src/librustc_mir/transform/instrument_coverage.rs @@ -25,7 +25,7 @@ pub struct InstrumentCoverage; /// constructing the arguments for `llvm.instrprof.increment`. pub(crate) fn provide(providers: &mut Providers<'_>) { providers.coverage_data = |tcx, def_id| { - let mir_body = tcx.optimized_mir(def_id); + let mir_body = tcx.optimized_mir(ty::WithOptParam::dummy(def_id)); // FIXME(richkadel): The current implementation assumes the MIR for the given DefId // represents a single function. Validate and/or correct if inlining and/or monomorphization // invalidates these assumptions. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a67d6a1614a50..d009a4f591eea 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1751,7 +1751,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) { let mut label = false; if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) { - let tables = tcx.typeck_tables_of(tcx.hir().local_def_id(hir_id)); + let tables = tcx.typeck_tables_of(ty::WithOptParam::dummy(tcx.hir().local_def_id(hir_id))); if visitor .returns .iter() @@ -1854,8 +1854,9 @@ fn binding_opaque_type_cycle_error( .. }) => { let hir_id = tcx.hir().as_local_hir_id(def_id); - let tables = - tcx.typeck_tables_of(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id))); + let tables = tcx.typeck_tables_of(ty::WithOptParam::dummy( + tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)), + )); if let Some(ty) = tables.node_type_opt(expr.hir_id) { err.span_label( expr.span, diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs index 3c9887a656b83..05abd488816ff 100644 --- a/src/test/ui/const-generics/type-dependent/issue-71382.rs +++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs @@ -1,7 +1,5 @@ -// run-pass #![feature(const_generics)] -#![allow(incomplete_features)] -#![feature(const_compare_raw_pointers)] +//~^ WARN the feature `const_generics` is incomplete struct Test; @@ -15,6 +13,7 @@ impl Test { } fn test u8>(&self) -> u8 { + //~^ ERROR using function pointers as const generic parameters is forbidden FN() } } diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.stderr new file mode 100644 index 0000000000000..f441b71031ece --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.stderr @@ -0,0 +1,17 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-71382.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71382.rs:15:23 + | +LL | fn test u8>(&self) -> u8 { + | ^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted +