diff options
| author | bors <bors@rust-lang.org> | 2023-11-16 09:31:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-11-16 09:31:29 +0000 |
| commit | 255d04cd9bb6bb51d4586a288facd01ee23cbcbf (patch) | |
| tree | 10b32a10a95d0ae65b6316dfc7931e6ab8ca30fd | |
| parent | 012bd49b8a60f02d504774293d7a381dfe74d5f4 (diff) | |
| parent | 13bfe141ff5bb92901eea3e88432cda75a208b9f (diff) | |
| download | rust-255d04cd9bb6bb51d4586a288facd01ee23cbcbf.tar.gz rust-255d04cd9bb6bb51d4586a288facd01ee23cbcbf.zip | |
Auto merge of #3167 - RalfJung:rustup, r=RalfJung
Rustup
83 files changed, 878 insertions, 339 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index b6eb9ae980e..94981c45582 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -50,8 +50,8 @@ impl OutlivesSuggestionBuilder { // naming the `'self` lifetime in methods, etc. fn region_name_is_suggestable(name: &RegionName) -> bool { match name.source { - RegionNameSource::NamedEarlyBoundRegion(..) - | RegionNameSource::NamedFreeRegion(..) + RegionNameSource::NamedEarlyParamRegion(..) + | RegionNameSource::NamedLateParamRegion(..) | RegionNameSource::Static => true, // Don't give suggestions for upvars, closure return types, or other unnameable diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a0a809123c0..e3927403939 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -181,8 +181,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// Returns `true` if a closure is inferred to be an `FnMut` closure. fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { - if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref() - && let ty::BoundRegionKind::BrEnv = free_region.bound_region + if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref() + && let ty::BoundRegionKind::BrEnv = late_param.bound_region && let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty { return args.as_closure().kind() == ty::ClosureKind::FnMut; @@ -995,7 +995,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .infcx .tcx .is_suitable_region(sub) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.boundregion)) + .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.bound_region)) else { return; }; @@ -1004,7 +1004,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .infcx .tcx .is_suitable_region(sup) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.boundregion)) + .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.bound_region)) else { return; }; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 9d6b0a0e91b..fee35485cd7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -23,14 +23,14 @@ pub(crate) struct RegionName { } /// Denotes the source of a region that is named by a `RegionName`. For example, a free region that -/// was named by the user would get `NamedFreeRegion` and `'static` lifetime would get `Static`. +/// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`. /// This helps to print the right kinds of diagnostics. #[derive(Debug, Clone)] pub(crate) enum RegionNameSource { /// A bound (not free) region that was instantiated at the def site (not an HRTB). - NamedEarlyBoundRegion(Span), + NamedEarlyParamRegion(Span), /// A free region that the user has a name (`'a`) for. - NamedFreeRegion(Span), + NamedLateParamRegion(Span), /// The `'static` region. Static, /// The free region corresponding to the environment of a closure. @@ -69,8 +69,8 @@ pub(crate) enum RegionNameHighlight { impl RegionName { pub(crate) fn was_named(&self) -> bool { match self.source { - RegionNameSource::NamedEarlyBoundRegion(..) - | RegionNameSource::NamedFreeRegion(..) + RegionNameSource::NamedEarlyParamRegion(..) + | RegionNameSource::NamedLateParamRegion(..) | RegionNameSource::Static => true, RegionNameSource::SynthesizedFreeEnvRegion(..) | RegionNameSource::AnonRegionFromArgument(..) @@ -85,8 +85,8 @@ impl RegionName { pub(crate) fn span(&self) -> Option<Span> { match self.source { RegionNameSource::Static => None, - RegionNameSource::NamedEarlyBoundRegion(span) - | RegionNameSource::NamedFreeRegion(span) + RegionNameSource::NamedEarlyParamRegion(span) + | RegionNameSource::NamedLateParamRegion(span) | RegionNameSource::SynthesizedFreeEnvRegion(span, _) | RegionNameSource::AnonRegionFromUpvar(span, _) | RegionNameSource::AnonRegionFromYieldTy(span, _) @@ -104,8 +104,8 @@ impl RegionName { pub(crate) fn highlight_region_name(&self, diag: &mut Diagnostic) { match &self.source { - RegionNameSource::NamedFreeRegion(span) - | RegionNameSource::NamedEarlyBoundRegion(span) => { + RegionNameSource::NamedLateParamRegion(span) + | RegionNameSource::NamedEarlyParamRegion(span) => { diag.span_label(*span, format!("lifetime `{self}` defined here")); } RegionNameSource::SynthesizedFreeEnvRegion(span, note) => { @@ -280,28 +280,31 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { debug!("give_region_a_name: error_region = {:?}", error_region); match *error_region { - ty::ReEarlyBound(ebr) => ebr.has_name().then(|| { + ty::ReEarlyParam(ebr) => ebr.has_name().then(|| { let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); - RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span) } + RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) } }), ty::ReStatic => { Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static }) } - ty::ReFree(free_region) => match free_region.bound_region { + ty::ReLateParam(late_param) => match late_param.bound_region { ty::BoundRegionKind::BrNamed(region_def_id, name) => { // Get the span to point to, even if we don't use the name. let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); debug!( "bound region named: {:?}, is_named: {:?}", name, - free_region.bound_region.is_named() + late_param.bound_region.is_named() ); - if free_region.bound_region.is_named() { + if late_param.bound_region.is_named() { // A named region that is actually named. - Some(RegionName { name, source: RegionNameSource::NamedFreeRegion(span) }) + Some(RegionName { + name, + source: RegionNameSource::NamedLateParamRegion(span), + }) } else if tcx.asyncness(self.mir_hir_id().owner).is_async() { // If we spuriously thought that the region is named, we should let the // system generate a true name for error messages. Currently this can @@ -847,7 +850,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { &self, fr: RegionVid, ) -> Option<RegionName> { - let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else { + let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else { return None; }; if region.has_name() { @@ -862,7 +865,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let found = tcx .any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| { - *r == ty::ReEarlyBound(region) + *r == ty::ReEarlyParam(region) }); Some(RegionName { @@ -881,7 +884,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { &self, fr: RegionVid, ) -> Option<RegionName> { - let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else { + let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else { return None; }; if region.has_name() { @@ -943,7 +946,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { &self, clauses: &[ty::Clause<'tcx>], ty: Ty<'tcx>, - region: ty::EarlyBoundRegion, + region: ty::EarlyParamRegion, ) -> bool { let tcx = self.infcx.tcx; ty.walk().any(|arg| { @@ -956,7 +959,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {} _ => return false, } - tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyBound(region)) + tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region)) }) } else { false diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index fb0e5811c26..c93cfa78832 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -36,7 +36,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// call `infer_opaque_definition_from_instantiation` to get the inferred /// type of `_Return<'_a>`. `infer_opaque_definition_from_instantiation` /// compares lifetimes directly, so we need to map the inference variables - /// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`. + /// back to concrete lifetimes: `'static`, `ReEarlyParam` or `ReLateParam`. /// /// First we map all the lifetimes in the concrete type to an equal /// universal region that occurs in the concrete type's args, in this case @@ -386,7 +386,7 @@ fn check_opaque_type_parameter_valid( let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Lifetime(lt) if is_ty_alias => { - matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_)) + matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) } // FIXME(#113916): we can't currently check for unique lifetime params, // see that issue for more. We will also have to ignore unused lifetime diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index ae7f9c5244c..02f94e5b972 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -462,7 +462,6 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // "Liberate" the late-bound regions. These correspond to // "local" free regions. - let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars( @@ -784,7 +783,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { debug!(?br); let liberated_region = - ty::Region::new_free(self.tcx, all_outlive_scope.to_def_id(), br.kind); + ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), br.kind); let region_vid = { let name = match br.kind.get_name() { Some(name) => name, @@ -854,7 +853,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// Initially, the `UniversalRegionIndices` map contains only the /// early-bound regions in scope. Once that is all setup, we come /// in later and instantiate the late-bound regions, and then we - /// insert the `ReFree` version of those into the map as + /// insert the `ReLateParam` version of those into the map as /// well. These are used for error reporting. fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) { debug!("insert_late_bound_region({:?}, {:?})", r, vid); @@ -933,7 +932,8 @@ fn for_each_late_bound_region_in_item<'tcx>( let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; - let liberated_region = ty::Region::new_free(tcx, mir_def_id.to_def_id(), bound_region); + let liberated_region = + ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), bound_region); f(liberated_region); } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 4dd6372b5e0..242c6aed906 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -368,6 +368,24 @@ pub unsafe fn create_module<'ll>( llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1), ); + // Add module flags specified via -Z llvm_module_flag + for (key, value, behavior) in &sess.opts.unstable_opts.llvm_module_flag { + let key = format!("{key}\0"); + let behavior = match behavior.as_str() { + "error" => llvm::LLVMModFlagBehavior::Error, + "warning" => llvm::LLVMModFlagBehavior::Warning, + "require" => llvm::LLVMModFlagBehavior::Require, + "override" => llvm::LLVMModFlagBehavior::Override, + "append" => llvm::LLVMModFlagBehavior::Append, + "appendunique" => llvm::LLVMModFlagBehavior::AppendUnique, + "max" => llvm::LLVMModFlagBehavior::Max, + "min" => llvm::LLVMModFlagBehavior::Min, + // We already checked this during option parsing + _ => unreachable!(), + }; + llvm::LLVMRustAddModuleFlag(llmod, behavior, key.as_ptr().cast(), *value) + } + llmod } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 7905a0e3924..17a53aafe9a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1520,14 +1520,14 @@ fn report_ice( /// This allows tools to enable rust logging without having to magically match rustc's /// tracing crate version. pub fn init_rustc_env_logger(handler: &EarlyErrorHandler) { - init_env_logger(handler, "RUSTC_LOG"); + init_logger(handler, rustc_log::LoggerConfig::from_env("RUSTC_LOG")); } /// This allows tools to enable rust logging without having to magically match rustc's -/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var -/// other than `RUSTC_LOG`. -pub fn init_env_logger(handler: &EarlyErrorHandler, env: &str) { - if let Err(error) = rustc_log::init_env_logger(env) { +/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose +/// the values directly rather than having to set an environment variable. +pub fn init_logger(handler: &EarlyErrorHandler, cfg: rustc_log::LoggerConfig) { + if let Err(error) = rustc_log::init_logger(cfg) { handler.early_error(error.to_string()); } } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5a9c67a6a9d..8126b451181 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -258,12 +258,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion { def_id, index, name }) + ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name }) } Some(rbv::ResolvedArg::Free(scope, id)) => { let name = lifetime_name(id.expect_local()); - ty::Region::new_free(tcx, scope, ty::BrNamed(id, name)) + ty::Region::new_late_param(tcx, scope, ty::BrNamed(id, name)) // (*) -- not late-bound, won't change } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index d3a383ff7c5..f026f78cc2b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -532,8 +532,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReFree(fr) = *r { - ty::Region::new_free( + if let ty::ReLateParam(fr) = *r { + ty::Region::new_late_param( self.tcx, fr.scope, self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region), @@ -1078,20 +1078,20 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> { region: ty::Region<'tcx>, ) -> Result<ty::Region<'tcx>, Self::Error> { match region.kind() { - // Remap all free regions, which correspond to late-bound regions in the function. - ty::ReFree(_) => {} + // Remap late-bound regions from the function. + ty::ReLateParam(_) => {} // Remap early-bound regions as long as they don't come from the `impl` itself, // in which case we don't really need to renumber them. - ty::ReEarlyBound(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {} + ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {} _ => return Ok(region), } let e = if let Some(region) = self.map.get(®ion) { - if let ty::ReEarlyBound(e) = region.kind() { e } else { bug!() } + if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() } } else { let guar = match region.kind() { - ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) - | ty::ReFree(ty::FreeRegion { + ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) + | ty::ReLateParam(ty::LateParamRegion { bound_region: ty::BoundRegionKind::BrNamed(def_id, _), .. }) => { @@ -1119,9 +1119,9 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> { return Err(guar); }; - Ok(ty::Region::new_early_bound( + Ok(ty::Region::new_early_param( self.tcx, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: e.def_id, name: e.name, index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32, diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index dda3f742569..0a05c1039b6 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -81,8 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( self_type_did: DefId, adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyEarlyBound) - else { + let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else { return Ok(()); }; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 729e9f2f1d1..d7b50d127cd 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -595,9 +595,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( // Same for the region. In our example, 'a corresponds // to the 'me parameter. let region_param = gat_generics.param_at(*region_a_idx, tcx); - let region_param = ty::Region::new_early_bound( + let region_param = ty::Region::new_early_param( tcx, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: region_param.def_id, index: region_param.index, name: region_param.name, @@ -628,9 +628,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( debug!("required clause: {region_a} must outlive {region_b}"); // Translate into the generic parameters of the GAT. let region_a_param = gat_generics.param_at(*region_a_idx, tcx); - let region_a_param = ty::Region::new_early_bound( + let region_a_param = ty::Region::new_early_param( tcx, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: region_a_param.def_id, index: region_a_param.index, name: region_a_param.name, @@ -638,9 +638,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( ); // Same for the region. let region_b_param = gat_generics.param_at(*region_b_idx, tcx); - let region_b_param = ty::Region::new_early_bound( + let region_b_param = ty::Region::new_early_param( tcx, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: region_b_param.def_id, index: region_b_param.index, name: region_b_param.name, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index e5e192e0079..f277badf275 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -550,7 +550,7 @@ fn infringing_fields_error( .entry((ty.clone(), predicate.clone())) .or_default() .push(origin.span()); - if let ty::RegionKind::ReEarlyBound(ebr) = *b + if let ty::RegionKind::ReEarlyParam(ebr) = *b && ebr.has_name() { bounds.push((b.to_string(), a.to_string(), None)); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9636c614446..1e75b863165 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -443,7 +443,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { self.tcx.replace_late_bound_regions_uncached( poly_trait_ref, |_| { - ty::Region::new_early_bound(self.tcx, ty::EarlyBoundRegion { + ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion { def_id: item_def_id, index: 0, name: Symbol::intern(<_name), diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 104da581e01..68d040d5846 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -362,10 +362,10 @@ fn compute_bidirectional_outlives_predicates<'tcx>( ) { for param in opaque_own_params { let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); - if let ty::ReEarlyBound(..) = *orig_lifetime { - let dup_lifetime = ty::Region::new_early_bound( + if let ty::ReEarlyParam(..) = *orig_lifetime { + let dup_lifetime = ty::Region::new_early_param( tcx, - ty::EarlyBoundRegion { def_id: param.def_id, index: param.index, name: param.name }, + ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name }, ); let span = tcx.def_span(param.def_id); predicates.push(( diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d51e9eb5983..53efc2c6e82 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -2012,7 +2012,7 @@ fn is_late_bound_map( fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<!> { debug!("r={:?}", r.kind()); - if let ty::RegionKind::ReEarlyBound(region) = r.kind() { + if let ty::RegionKind::ReEarlyParam(region) = r.kind() { self.arg_is_constrained[region.index as usize] = true; } diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index ed5e9dd2b5a..65d1ffa40e2 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -13,8 +13,8 @@ impl From<ty::ParamTy> for Parameter { } } -impl From<ty::EarlyBoundRegion> for Parameter { - fn from(param: ty::EarlyBoundRegion) -> Self { +impl From<ty::EarlyParamRegion> for Parameter { + fn from(param: ty::EarlyParamRegion) -> Self { Parameter(param.index) } } @@ -73,7 +73,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector { } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - if let ty::ReEarlyBound(data) = *r { + if let ty::ReEarlyParam(data) = *r { self.parameters.push(Parameter::from(data)); } ControlFlow::Continue(()) diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 85703c60c30..218f658b061 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -146,11 +146,11 @@ fn is_free_region(region: Region<'_>) -> bool { // These correspond to `T: 'a` relationships: // // struct Foo<'a, T> { - // field: &'a T, // this would generate a ReEarlyBound referencing `'a` + // field: &'a T, // this would generate a ReEarlyParam referencing `'a` // } // // We care about these, so fall through. - ty::ReEarlyBound(_) => true, + ty::ReEarlyParam(_) => true, // These correspond to `T: 'static` relationships which can be // rather surprising. @@ -173,7 +173,7 @@ fn is_free_region(region: Region<'_>) -> bool { ty::ReError(_) => false, // These regions don't appear in types from type declarations: - ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => { + ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReLateParam(..) => { bug!("unexpected region in outlives inference: {:?}", region); } } diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 6c1efb6470e..f09594cbbc6 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -413,7 +413,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { variance: VarianceTermPtr<'a>, ) { match *region { - ty::ReEarlyBound(ref data) => { + ty::ReEarlyParam(ref data) => { self.add_constraint(current, data.index, variance); } @@ -428,7 +428,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::ReError(_) => {} - ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => { + ty::ReLateParam(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => { // We don't expect to see anything but 'static or bound // regions when visiting member types or method types. bug!( diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 9fb39a0e93b..410706110c9 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -106,7 +106,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> { #[instrument(level = "trace", skip(self), ret)] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { + if let ty::RegionKind::ReEarlyParam(ebr) = r.kind() { self.variances[ebr.index as usize] = ty::Invariant; } ControlFlow::Continue(()) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index a1ce5983f30..bd653e79913 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> { let v = match def { - Some(def) => infer::EarlyBoundRegion(span, def.name), + Some(def) => infer::RegionParameterDefinition(span, def.name), None => infer::MiscVariable(span), }; Some(self.next_region_var(v)) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index bd40e6c1047..4e54144b5d0 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3296,8 +3296,12 @@ fn print_disambiguation_help<'tcx>( { let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id); let item_name = item.ident(tcx); - let rcvr_ref = tcx.fn_sig(item.def_id).skip_binder().skip_binder().inputs()[0] - .ref_mutability() + let rcvr_ref = tcx.fn_sig(item.def_id) + .skip_binder() + .skip_binder() + .inputs() + .get(0) + .and_then(|ty| ty.ref_mutability()) .map_or("", |mutbl| mutbl.ref_prefix_str()); let args = format!( "({}{})", diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 869878420ae..294bd9d1d54 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -17,7 +17,7 @@ impl<'a> DescriptionCtx<'a> { alt_span: Option<Span>, ) -> Option<Self> { let (span, kind, arg) = match *region { - ty::ReEarlyBound(ref br) => { + ty::ReEarlyParam(ref br) => { let scope = region.free_region_binding_scope(tcx).expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) @@ -32,7 +32,7 @@ impl<'a> DescriptionCtx<'a> { (Some(span), "as_defined_anon", String::new()) } } - ty::ReFree(ref fr) => { + ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { @@ -70,7 +70,7 @@ impl<'a> DescriptionCtx<'a> { ty::RePlaceholder(_) | ty::ReError(_) => return None, // FIXME(#13998) RePlaceholder should probably print like - // ReFree rather than dumping Debug output on the user. + // ReLateParam rather than dumping Debug output on the user. // // We shouldn't really be having unification failures with ReVar // and ReBound though. diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index ba7007d908f..b502590c1bf 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -172,7 +172,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match *r { - ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r, + ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r, ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region( CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) }, @@ -223,7 +223,11 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match *r { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReError(_) => r, + ty::ReEarlyParam(_) + | ty::ReLateParam(_) + | ty::ReErased + | ty::ReStatic + | ty::ReError(_) => r, ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r), ty::RePlaceholder(..) | ty::ReBound(..) => { // We only expect region names that the user can type. @@ -359,9 +363,9 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } ty::ReStatic - | ty::ReEarlyBound(..) + | ty::ReEarlyParam(..) | ty::ReError(_) - | ty::ReFree(_) + | ty::ReLateParam(_) | ty::RePlaceholder(..) | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f09a33be839..0546f4e1afc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -168,7 +168,7 @@ pub(super) fn note_and_explain_region<'tcx>( alt_span: Option<Span>, ) { let (description, span) = match *region { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::RePlaceholder(_) | ty::ReStatic => { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { msg_span_from_named_region(tcx, region, alt_span) } @@ -202,7 +202,7 @@ fn msg_span_from_named_region<'tcx>( alt_span: Option<Span>, ) -> (String, Option<Span>) { match *region { - ty::ReEarlyBound(ref br) => { + ty::ReEarlyParam(ref br) => { let scope = region.free_region_binding_scope(tcx).expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) @@ -218,7 +218,7 @@ fn msg_span_from_named_region<'tcx>( }; (text, Some(span)) } - ty::ReFree(ref fr) => { + ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { @@ -315,7 +315,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( // Explain the region we are capturing. match *hidden_region { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { // Assuming regionck succeeded (*), we ought to always be // capturing *some* region from the fn header, and hence it // ought to be free. So under normal circumstances, we will go @@ -2364,7 +2364,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, format!("{labeled_user_string} may not live long enough"), match sub.kind() { - ty::ReEarlyBound(_) | ty::ReFree(_) if sub.has_name() => error_code!(E0309), + ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309), ty::ReStatic => error_code!(E0310), _ => error_code!(E0311), }, @@ -2372,7 +2372,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { '_explain: { let (description, span) = match sub.kind() { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { msg_span_from_named_region(self.tcx, sub, Some(span)) } _ => (format!("lifetime `{sub}`"), Some(span)), @@ -2515,7 +2515,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime) { Some(info) if !lifetime.has_name() => { - (info.boundregion.get_id().unwrap().expect_local(), info.def_id) + (info.bound_region.get_id().unwrap().expect_local(), info.def_id) } _ => return lifetime.get_name_or_anon().to_string(), }; @@ -2714,8 +2714,8 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { a: ty::Region<'tcx>, b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { - if (a.is_var() && b.is_free_or_static()) - || (b.is_var() && a.is_free_or_static()) + if (a.is_var() && b.is_free()) + || (b.is_var() && a.is_free()) || (a.is_var() && b.is_var()) || a == b { @@ -2779,7 +2779,9 @@ impl<'tcx> InferCtxt<'tcx> { br_string(br), self.tcx.associated_item(def_id).name ), - infer::EarlyBoundRegion(_, name) => format!(" for lifetime parameter `{name}`"), + infer::RegionParameterDefinition(_, name) => { + format!(" for lifetime parameter `{name}`") + } infer::UpvarRegion(ref upvar_id, _) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); format!(" for capture of `{var_name}` by closure") diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 1a60bab18db..f56d5d7d345 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -70,9 +70,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let anon_reg_sub = self.tcx().is_suitable_region(sub)?; let scope_def_id_sup = anon_reg_sup.def_id; - let bregion_sup = anon_reg_sup.boundregion; + let bregion_sup = anon_reg_sup.bound_region; let scope_def_id_sub = anon_reg_sub.def_id; - let bregion_sub = anon_reg_sub.boundregion; + let bregion_sub = anon_reg_sub.bound_region; let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index be6d1a3750c..7252a812466 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -41,8 +41,8 @@ pub fn find_param_with_region<'tcx>( replace_region: Region<'tcx>, ) -> Option<AnonymousParamInfo<'tcx>> { let (id, bound_region) = match *anon_region { - ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), - ty::ReEarlyBound(ebr) => { + ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region), + ty::ReEarlyParam(ebr) => { (tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name)) } _ => return None, // not a free region diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index ed1a2a11719..0dde3082d48 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -22,8 +22,8 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> { Self { tcx, free_regions } } - pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { - self.free_regions.lub_free_regions(self.tcx, r_a, r_b) + pub fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { + self.free_regions.lub_param_regions(self.tcx, r_a, r_b) } } @@ -59,7 +59,7 @@ impl<'tcx> FreeRegionMap<'tcx> { r_a: Region<'tcx>, r_b: Region<'tcx>, ) -> bool { - assert!(r_a.is_free_or_static() && r_b.is_free_or_static()); + assert!(r_a.is_free() && r_b.is_free()); let re_static = tcx.lifetimes.re_static; if self.check_relation(re_static, r_b) { // `'a <= 'static` is always true, and not stored in the @@ -80,15 +80,15 @@ impl<'tcx> FreeRegionMap<'tcx> { /// cases, this is more conservative than necessary, in order to /// avoid making arbitrary choices. See /// `TransitiveRelation::postdom_upper_bound` for more details. - pub fn lub_free_regions( + pub fn lub_param_regions( &self, tcx: TyCtxt<'tcx>, r_a: Region<'tcx>, r_b: Region<'tcx>, ) -> Region<'tcx> { - debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b); - assert!(r_a.is_free()); - assert!(r_b.is_free()); + debug!("lub_param_regions(r_a={:?}, r_b={:?})", r_a, r_b); + assert!(r_a.is_param()); + assert!(r_b.is_param()); let result = if r_a == r_b { r_a } else { @@ -97,7 +97,7 @@ impl<'tcx> FreeRegionMap<'tcx> { Some(r) => r, } }; - debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result); + debug!("lub_param_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result); result } } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index e212547eaaf..11ab86277c1 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -115,8 +115,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> { r } - ty::ReEarlyBound(..) - | ty::ReFree(_) + ty::ReEarlyParam(..) + | ty::ReLateParam(_) | ty::ReVar(_) | ty::RePlaceholder(..) | ty::ReStatic diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs index 84891022720..9e24b020510 100644 --- a/compiler/rustc_infer/src/infer/generalize.rs +++ b/compiler/rustc_infer/src/infer/generalize.rs @@ -340,8 +340,8 @@ where ty::RePlaceholder(..) | ty::ReVar(..) | ty::ReStatic - | ty::ReEarlyBound(..) - | ty::ReFree(..) => { + | ty::ReEarlyParam(..) + | ty::ReLateParam(..) => { // see common code below } } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 4ff9d749422..800aee1f4d3 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -17,7 +17,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReBound, RePlaceholder, ReVar}; -use rustc_middle::ty::{ReEarlyBound, ReErased, ReError, ReFree, ReStatic}; +use rustc_middle::ty::{ReEarlyParam, ReErased, ReError, ReLateParam, ReStatic}; use rustc_middle::ty::{Region, RegionVid}; use rustc_span::Span; use std::fmt; @@ -390,7 +390,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - ReStatic | ReEarlyBound(_) | ReFree(_) => { + ReStatic | ReEarlyParam(_) | ReLateParam(_) => { // nothing lives longer than `'static` // All empty regions are less than early-bound, free, @@ -423,9 +423,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - ReStatic | ReEarlyBound(_) | ReFree(_) => { + ReStatic | ReEarlyParam(_) | ReLateParam(_) => { // nothing lives longer than `'static` - // All empty regions are less than early-bound, free, + // All empty regions are less than early-bound, late-bound, // and scope regions. true } @@ -450,8 +450,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Check for the case where we know that `'b: 'static` -- in that case, // `a <= b` for all `a`. - let b_free_or_static = b.is_free_or_static(); - if b_free_or_static && sub_free_regions(tcx.lifetimes.re_static, b) { + if b.is_free() && sub_free_regions(tcx.lifetimes.re_static, b) { return true; } @@ -460,8 +459,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // `lub` relationship defined below, since sometimes the "lub" // is actually the `postdom_upper_bound` (see // `TransitiveRelation` for more details). - let a_free_or_static = a.is_free_or_static(); - if a_free_or_static && b_free_or_static { + if a.is_free() && b.is_free() { return sub_free_regions(a, b); } @@ -501,8 +499,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.tcx().lifetimes.re_static } - (ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => { - self.region_rels.lub_free_regions(a, b) + (ReEarlyParam(_) | ReLateParam(_), ReEarlyParam(_) | ReLateParam(_)) => { + self.region_rels.lub_param_regions(a, b) } // For these types, we cannot define any additional @@ -723,13 +721,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { return; } - // We place free regions first because we are special casing - // SubSupConflict(ReFree, ReFree) when reporting error, and so + // We place late-bound regions first because we are special casing + // SubSupConflict(ReLateParam, ReLateParam) when reporting error, and so // the user will more likely get a specific suggestion. fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 { match *x.region { - ReEarlyBound(_) => 0, - ReFree(_) => 1, + ReEarlyParam(_) => 0, + ReLateParam(_) => 1, _ => 2, } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 3c539f18eb9..956d097a5b2 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -508,7 +508,10 @@ pub enum RegionVariableOrigin { Coercion(Span), /// Region variables created as the values for early-bound regions. - EarlyBoundRegion(Span, Symbol), + /// + /// FIXME(@lcnr): This can also store a `DefId`, similar to + /// `TypeVariableOriginKind::TypeParameterDefinition`. + RegionParameterDefinition(Span, Symbol), /// Region variables created when instantiating a binder with /// existential variables, e.g. when calling a function or method. @@ -1165,7 +1168,7 @@ impl<'tcx> InferCtxt<'tcx> { GenericParamDefKind::Lifetime => { // Create a region inference variable for the given // region parameter definition. - self.next_region_var(EarlyBoundRegion(span, param.name)).into() + self.next_region_var(RegionParameterDefinition(span, param.name)).into() } GenericParamDefKind::Type { .. } => { // Create a type inference variable for the given @@ -2041,7 +2044,7 @@ impl RegionVariableOrigin { | AddrOfRegion(a) | Autoref(a) | Coercion(a) - | EarlyBoundRegion(a, ..) + | RegionParameterDefinition(a, ..) | BoundRegion(a, ..) | UpvarRegion(_, a) => a, Nll(..) => bug!("NLL variable used with `span`"), diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 47e3dd762b0..f8dbfdde30c 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -138,8 +138,8 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { } OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) { ( - ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), - ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), + ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_), + ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_), ) => self.region_relation.add(r_a, r_b), (ty::ReError(_), _) | (_, ty::ReError(_)) => {} // FIXME(#109628): We shouldn't have existential variables in implied bounds. diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index de142f05fb7..e888340bde3 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -662,8 +662,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { match *region { ty::ReStatic | ty::ReErased - | ty::ReFree(..) - | ty::ReEarlyBound(..) + | ty::ReLateParam(..) + | ty::ReEarlyParam(..) | ty::ReError(_) => ty::UniverseIndex::ROOT, ty::RePlaceholder(placeholder) => placeholder.universe, ty::ReVar(vid) => self.var_universe(vid), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8a5851bd5cb..e6e132978ed 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -769,6 +769,7 @@ fn test_unstable_options_tracking_hash() { tracked!(instrument_xray, Some(InstrumentXRay::default())); tracked!(link_directives, false); tracked!(link_only, true); + tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]); tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); tracked!(maximal_hir_to_mir_coverage, true); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6f6150a4172..e3dd8faeedb 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1910,7 +1910,7 @@ impl ExplicitOutlivesRequirements { .iter() .filter_map(|(clause, _)| match clause.kind().skip_binder() { ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { - ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b), + ty::ReEarlyParam(ebr) if ebr.def_id == def_id => Some(b), _ => None, }, _ => None, @@ -1953,7 +1953,7 @@ impl ExplicitOutlivesRequirements { let is_inferred = match tcx.named_bound_var(lifetime.hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives .iter() - .any(|r| matches!(**r, ty::ReEarlyBound(ebr) if { ebr.def_id == def_id })), + .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { ebr.def_id == def_id })), _ => false, }; diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 0c9ec556549..e3464cb8a2d 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -14,7 +14,7 @@ //! //! ``` //! fn main() { -//! rustc_log::init_env_logger("LOG").unwrap(); +//! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap(); //! //! let edition = rustc_span::edition::Edition::Edition2021; //! rustc_span::create_session_globals_then(edition, || { @@ -52,13 +52,36 @@ use tracing_subscriber::fmt::{ }; use tracing_subscriber::layer::SubscriberExt; -pub fn init_env_logger(env: &str) -> Result<(), Error> { - let filter = match env::var(env) { +/// The values of all the environment variables that matter for configuring a logger. +/// Errors are explicitly preserved so that we can share error handling. +pub struct LoggerConfig { + pub filter: Result<String, VarError>, + pub color_logs: Result<String, VarError>, + pub verbose_entry_exit: Result<String, VarError>, + pub verbose_thread_ids: Result<String, VarError>, + pub backtrace: Result<String, VarError>, +} + +impl LoggerConfig { + pub fn from_env(env: &str) -> Self { + LoggerConfig { + filter: env::var(env), + color_logs: env::var(format!("{env}_COLOR")), + verbose_entry_exit: env::var(format!("{env}_ENTRY_EXIT")), + verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")), + backtrace: env::var(format!("{env}_BACKTRACE")), + } + } +} + +/// Initialize the logger with the given values for the filter, coloring, and other options env variables. +pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { + let filter = match cfg.filter { Ok(env) => EnvFilter::new(env), _ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)), }; - let color_logs = match env::var(String::from(env) + "_COLOR") { + let color_logs = match cfg.color_logs { Ok(value) => match value.as_ref() { "always" => true, "never" => false, @@ -69,14 +92,14 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> { Err(VarError::NotUnicode(_value)) => return Err(Error::NonUnicodeColorValue), }; - let verbose_entry_exit = match env::var_os(String::from(env) + "_ENTRY_EXIT") { - None => false, - Some(v) => &v != "0", + let verbose_entry_exit = match cfg.verbose_entry_exit { + Ok(v) => &v != "0", + Err(_) => false, }; - let verbose_thread_ids = match env::var_os(String::from(env) + "_THREAD_IDS") { - None => false, - Some(v) => &v == "1", + let verbose_thread_ids = match cfg.verbose_thread_ids { + Ok(v) => &v == "1", + Err(_) => false, }; let layer = tracing_tree::HierarchicalLayer::default() @@ -91,7 +114,7 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> { .with_thread_names(verbose_thread_ids); let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); - match env::var(format!("{env}_BACKTRACE")) { + match cfg.backtrace { Ok(str) => { let fmt_layer = tracing_subscriber::fmt::layer() .with_writer(io::stderr) diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 92d1fcc7ed2..6e50e894046 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -64,8 +64,8 @@ impl<'tcx> UnifyValue for UnifiedRegion<'tcx> { cmp::min_by_key(r1, r2, |r| match r.kind() { ty::ReStatic | ty::ReErased - | ty::ReFree(..) - | ty::ReEarlyBound(..) + | ty::ReLateParam(..) + | ty::ReEarlyParam(..) | ty::ReError(_) => ty::UniverseIndex::ROOT, ty::RePlaceholder(placeholder) => placeholder.universe, ty::ReVar(..) | ty::ReBound(..) => bug!("not a universal region"), diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 56fed05c63f..b76d1d6e141 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -77,7 +77,7 @@ use std::ops::Deref; /// picture, but rather the ending point. // // FIXME(pnkfelix): this currently derives `PartialOrd` and `Ord` to -// placate the same deriving in `ty::FreeRegion`, but we may want to +// placate the same deriving in `ty::LateParamRegion`, but we may want to // actually attach a more meaningful ordering to scopes than the one // generated via deriving here. #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index e360fb3eaaf..b87c6885e04 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -525,6 +525,13 @@ impl<'tcx> TyCtxt<'tcx> { self.alloc_map.lock().reserve() } + /// Miri's provenance GC needs to see all live allocations. The interpreter manages most + /// allocations but some are managed by [`TyCtxt`] and without this method the interpreter + /// doesn't know their [`AllocId`]s are in use. + pub fn iter_allocs<F: FnMut(AllocId)>(self, func: F) { + self.alloc_map.lock().alloc_map.keys().copied().for_each(func) + } + /// Reserves a new ID *if* this allocation has not been dedup-reserved before. /// Should only be used for "symbolic" allocations (function pointers, vtables, statics), we /// don't want to dedup IDs for "real" memory! diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1598d05251d..e635c3f96ec 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -113,9 +113,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ExprConst = ty::Expr<'tcx>; type Region = Region<'tcx>; - type EarlyBoundRegion = ty::EarlyBoundRegion; + type EarlyParamRegion = ty::EarlyParamRegion; type BoundRegion = ty::BoundRegion; - type FreeRegion = ty::FreeRegion; + type LateParamRegion = ty::LateParamRegion; type InferRegion = ty::RegionVid; type PlaceholderRegion = ty::PlaceholderRegion; @@ -445,14 +445,14 @@ impl<'tcx> CommonConsts<'tcx> { } } -/// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime -/// conflict. +/// This struct contains information regarding a free parameter region, +/// either a `ReEarlyParam` or `ReLateParam`. #[derive(Debug)] pub struct FreeRegionInfo { - /// `LocalDefId` corresponding to FreeRegion + /// `LocalDefId` of the free region. pub def_id: LocalDefId, - /// the bound region corresponding to FreeRegion - pub boundregion: ty::BoundRegionKind, + /// the bound region corresponding to free region. + pub bound_region: ty::BoundRegionKind, /// checks if bound region is in Impl Item pub is_impl_item: bool, } @@ -1080,8 +1080,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option<FreeRegionInfo> { let (suitable_region_binding_scope, bound_region) = loop { let def_id = match region.kind() { - ty::ReFree(fr) => fr.bound_region.get_id()?.as_local()?, - ty::ReEarlyBound(ebr) => ebr.def_id.expect_local(), + ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?, + ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(), _ => return None, // not a free region }; let scope = self.local_parent(def_id); @@ -1102,11 +1102,7 @@ impl<'tcx> TyCtxt<'tcx> { _ => false, }; - Some(FreeRegionInfo { - def_id: suitable_region_binding_scope, - boundregion: bound_region, - is_impl_item, - }) + Some(FreeRegionInfo { def_id: suitable_region_binding_scope, bound_region, is_impl_item }) } /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type. @@ -1743,7 +1739,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { match param.kind { GenericParamDefKind::Lifetime => { - ty::Region::new_early_bound(self, param.to_early_bound_region_data()).into() + ty::Region::new_early_param(self, param.to_early_bound_region_data()).into() } GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(), GenericParamDefKind::Const { .. } => ty::Const::new_param( @@ -2040,7 +2036,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the def-id of an early-bound lifetime on an RPIT corresponding to /// a duplicated captured lifetime, map it back to the early- or late-bound /// lifetime of the function from which it originally as captured. If it is - /// a late-bound lifetime, this will represent the liberated (`ReFree`) lifetime + /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime /// of the signature. // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just // re-use the generics of the opaque, this function will need to be tweaked slightly. @@ -2079,9 +2075,9 @@ impl<'tcx> TyCtxt<'tcx> { } let generics = self.generics_of(new_parent); - return ty::Region::new_early_bound( + return ty::Region::new_early_param( self, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: ebv, index: generics .param_def_id_to_index(self, ebv) @@ -2092,7 +2088,7 @@ impl<'tcx> TyCtxt<'tcx> { } Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => { let new_parent = self.parent(lbv); - return ty::Region::new_free( + return ty::Region::new_late_param( self, new_parent, ty::BoundRegionKind::BrNamed( diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index e8ff3b230cb..cff0d4df673 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -326,7 +326,7 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<TyCtxt<'tcx>>, { self.replace_late_bound_regions_uncached(value, |br| { - ty::Region::new_free(self, all_outlive_scope, br.kind) + ty::Region::new_late_param(self, all_outlive_scope, br.kind) }) } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index c9607b2245a..8fd08c724d2 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -809,7 +809,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { #[cold] #[inline(never)] - fn region_param_out_of_range(data: ty::EarlyBoundRegion, args: &[GenericArg<'_>]) -> ! { + fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! { bug!( "Region parameter out of range when substituting in region {} (index={}, args = {:?})", data.name, @@ -820,7 +820,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> { #[cold] #[inline(never)] - fn region_param_invalid(data: ty::EarlyBoundRegion, other: GenericArgKind<'_>) -> ! { + fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! { bug!( "Unexpected parameter {:?} when substituting in region {} (index={})", other, @@ -835,7 +835,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> { // regions that appear in a function signature is done using // the specialized routine `ty::replace_late_regions()`. match *r { - ty::ReEarlyBound(data) => { + ty::ReEarlyParam(data) => { let rk = self.args.get(data.index as usize).map(|k| k.unpack()); match rk { Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), @@ -844,7 +844,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> { } } ty::ReBound(..) - | ty::ReFree(_) + | ty::ReLateParam(_) | ty::ReStatic | ty::RePlaceholder(_) | ty::ReErased diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 888ee1d237a..4a6e3cfacd3 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; -use super::{Clause, EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt}; +use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt}; #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum GenericParamDefKind { @@ -62,9 +62,9 @@ pub struct GenericParamDef { } impl GenericParamDef { - pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion { + pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion { if let GenericParamDefKind::Lifetime = self.kind { - ty::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name } + ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name } } else { bug!("cannot convert a non-lifetime parameter def to an early bound region") } @@ -260,10 +260,10 @@ impl<'tcx> Generics { } } - /// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`. + /// Returns the `GenericParamDef` associated with this `EarlyParamRegion`. pub fn region_param( &'tcx self, - param: &EarlyBoundRegion, + param: &ty::EarlyParamRegion, tcx: TyCtxt<'tcx>, ) -> &'tcx GenericParamDef { let param = self.param_at(param.index as usize, tcx); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e1c616ba078..559bf9fb825 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -98,11 +98,12 @@ pub use self::sty::BoundRegionKind::*; pub use self::sty::{ AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind, - ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyBoundRegion, EffectVid, ExistentialPredicate, - ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, InlineConstArgs, - InlineConstArgsParts, ParamConst, ParamTy, PolyExistentialPredicate, PolyExistentialProjection, - PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, PredicateKind, Region, - RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo, + ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, EffectVid, ExistentialPredicate, + ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs, + InlineConstArgsParts, LateParamRegion, ParamConst, ParamTy, PolyExistentialPredicate, + PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, + PredicateKind, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, + VarianceDiagInfo, }; pub use self::trait_def::TraitDef; pub use self::typeck_results::{ @@ -463,7 +464,7 @@ pub struct CReaderCacheKey { #[rustc_pass_by_value] pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>); -impl ty::EarlyBoundRegion { +impl EarlyParamRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). pub fn has_name(&self) -> bool { diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index cabf2ab5dfe..1305f63bdbc 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -113,7 +113,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { ty::ReError(_) => return r, // The regions that we expect from borrow checking. - ty::ReEarlyBound(_) | ty::ReFree(_) => {} + ty::ReEarlyParam(_) | ty::ReLateParam(_) => {} ty::RePlaceholder(_) | ty::ReVar(_) => { // All of the regions in the type should either have been diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 21bf5b4b3b1..ad070dcc9e3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2158,10 +2158,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions; match *region { - ty::ReEarlyBound(ref data) => data.has_name(), + ty::ReEarlyParam(ref data) => data.has_name(), ty::ReBound(_, ty::BoundRegion { kind: br, .. }) - | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) + | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { bound: ty::BoundRegion { kind: br, .. }, .. }) => { @@ -2228,14 +2228,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { // to fit that into a short string. Hence the recommendation to use // `explain_region()` or `note_and_explain_region()`. match *region { - ty::ReEarlyBound(ref data) => { + ty::ReEarlyParam(ref data) => { if data.name != kw::Empty { p!(write("{}", data.name)); return Ok(()); } } ty::ReBound(_, ty::BoundRegion { kind: br, .. }) - | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) + | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { bound: ty::BoundRegion { kind: br, .. }, .. }) => { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6af68bc5dba..e223ffd7c5d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -79,9 +79,9 @@ impl fmt::Debug for ty::BoundRegionKind { } } -impl fmt::Debug for ty::FreeRegion { +impl fmt::Debug for ty::LateParamRegion { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region) } } @@ -444,7 +444,7 @@ TrivialTypeTraversalImpls! { crate::ty::Placeholder<crate::ty::BoundRegion>, crate::ty::Placeholder<crate::ty::BoundTy>, crate::ty::Placeholder<ty::BoundVar>, - crate::ty::FreeRegion, + crate::ty::LateParamRegion, crate::ty::InferTy, crate::ty::IntVarValue, crate::ty::adjustment::PointerCoercion, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d0df4498a66..2b1e57f5871 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -61,9 +61,9 @@ pub struct TypeAndMut<'tcx> { #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] -/// A "free" region `fr` can be interpreted as "some region +/// The parameter representation of late-bound function parameters, "some region /// at least as big as the scope `fr.scope`". -pub struct FreeRegion { +pub struct LateParamRegion { pub scope: DefId, pub bound_region: BoundRegionKind, } @@ -1468,11 +1468,11 @@ pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); impl<'tcx> Region<'tcx> { #[inline] - pub fn new_early_bound( + pub fn new_early_param( tcx: TyCtxt<'tcx>, - early_bound_region: ty::EarlyBoundRegion, + early_bound_region: ty::EarlyParamRegion, ) -> Region<'tcx> { - tcx.intern_region(ty::ReEarlyBound(early_bound_region)) + tcx.intern_region(ty::ReEarlyParam(early_bound_region)) } #[inline] @@ -1493,12 +1493,12 @@ impl<'tcx> Region<'tcx> { } #[inline] - pub fn new_free( + pub fn new_late_param( tcx: TyCtxt<'tcx>, scope: DefId, bound_region: ty::BoundRegionKind, ) -> Region<'tcx> { - tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region })) + tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region })) } #[inline] @@ -1549,10 +1549,10 @@ impl<'tcx> Region<'tcx> { /// to avoid the cost of the `match`. pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { match kind { - ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region), + ty::ReEarlyParam(region) => Region::new_early_param(tcx, region), ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region), - ty::ReFree(ty::FreeRegion { scope, bound_region }) => { - Region::new_free(tcx, scope, bound_region) + ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => { + Region::new_late_param(tcx, scope, bound_region) } ty::ReStatic => tcx.lifetimes.re_static, ty::ReVar(vid) => Region::new_var(tcx, vid), @@ -1574,13 +1574,13 @@ impl<'tcx> Deref for Region<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] #[derive(HashStable)] -pub struct EarlyBoundRegion { +pub struct EarlyParamRegion { pub def_id: DefId, pub index: u32, pub name: Symbol, } -impl fmt::Debug for EarlyBoundRegion { +impl fmt::Debug for EarlyParamRegion { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name) } @@ -1722,9 +1722,9 @@ impl<'tcx> Region<'tcx> { pub fn get_name(self) -> Option<Symbol> { if self.has_name() { match *self { - ty::ReEarlyBound(ebr) => Some(ebr.name), + ty::ReEarlyParam(ebr) => Some(ebr.name), ty::ReBound(_, br) => br.kind.get_name(), - ty::ReFree(fr) => fr.bound_region.get_name(), + ty::ReLateParam(fr) => fr.bound_region.get_name(), ty::ReStatic => Some(kw::StaticLifetime), ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(), _ => None, @@ -1744,9 +1744,9 @@ impl<'tcx> Region<'tcx> { /// Is this region named by the user? pub fn has_name(self) -> bool { match *self { - ty::ReEarlyBound(ebr) => ebr.has_name(), + ty::ReEarlyParam(ebr) => ebr.has_name(), ty::ReBound(_, br) => br.kind.is_named(), - ty::ReFree(fr) => fr.bound_region.is_named(), + ty::ReLateParam(fr) => fr.bound_region.is_named(), ty::ReStatic => true, ty::ReVar(..) => false, ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(), @@ -1802,12 +1802,12 @@ impl<'tcx> Region<'tcx> { flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; } - ty::ReEarlyBound(..) => { + ty::ReEarlyParam(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_PARAM; } - ty::ReFree { .. } => { + ty::ReLateParam { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; } @@ -1851,22 +1851,28 @@ impl<'tcx> Region<'tcx> { /// function might return the `DefId` of a closure. pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { match *self { - ty::ReEarlyBound(br) => tcx.parent(br.def_id), - ty::ReFree(fr) => fr.scope, + ty::ReEarlyParam(br) => tcx.parent(br.def_id), + ty::ReLateParam(fr) => fr.scope, _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), } } /// True for free regions other than `'static`. - pub fn is_free(self) -> bool { - matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_)) + pub fn is_param(self) -> bool { + matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_)) } - /// True if `self` is a free region or static. - pub fn is_free_or_static(self) -> bool { + /// True for free region in the current context. + /// + /// This is the case for `'static` and param regions. + pub fn is_free(self) -> bool { match *self { - ty::ReStatic => true, - _ => self.is_free(), + ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true, + ty::ReVar(..) + | ty::RePlaceholder(..) + | ty::ReBound(..) + | ty::ReErased + | ty::ReError(..) => false, } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 1a76a8d350d..914ff1fabd1 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -126,7 +126,7 @@ pub struct TypeckResults<'tcx> { /// fn(&'a u32) -> u32 /// ``` /// - /// Note that `'a` is not bound (it would be an `ReFree`) and + /// Note that `'a` is not bound (it would be an `ReLateParam`) and /// that the `Foo` opaque type is replaced by its hidden type. liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 144e98f784a..e9f65d99a2e 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -35,12 +35,14 @@ pub struct Discr<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CheckRegions { No, - /// Only permit early bound regions. This is useful for Adts which - /// can never have late bound regions. - OnlyEarlyBound, - /// Permit both late bound and early bound regions. Use this for functions, - /// which frequently have late bound regions. - Bound, + /// Only permit parameter regions. This should be used + /// for everything apart from functions, which may use + /// `ReBound` to represent late-bound regions. + OnlyParam, + /// Check region parameters from a function definition. + /// Allows `ReEarlyParam` and `ReBound` to handle early + /// and late-bound region parameters. + FromFunction, } #[derive(Copy, Clone, Debug)] @@ -431,7 +433,7 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|&(_, k)| { match k.unpack() { GenericArgKind::Lifetime(region) => match region.kind() { - ty::ReEarlyBound(ref ebr) => { + ty::ReEarlyParam(ref ebr) => { !impl_generics.region_param(ebr, self).pure_wrt_drop } // Error: not a region param @@ -468,17 +470,17 @@ impl<'tcx> TyCtxt<'tcx> { for arg in args { match arg.unpack() { GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { - (CheckRegions::Bound, ty::ReBound(di, reg)) => { + (CheckRegions::FromFunction, ty::ReBound(di, reg)) => { if !seen_late.insert((di, reg)) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => { + (CheckRegions::OnlyParam | CheckRegions::FromFunction, ty::ReEarlyParam(p)) => { if !seen.insert(p.index) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => { + (CheckRegions::OnlyParam | CheckRegions::FromFunction, _) => { return Err(NotUniqueParam::NotParam(lt.into())); } (CheckRegions::No, _) => {} diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 7b6153eea09..e886db3da29 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -9,13 +9,10 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] -#![cfg_attr(not(bootstrap), doc(rust_logo))] -#![cfg_attr(not(bootstrap), allow(internal_features))] -#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -// We want to be able to build this crate with a stable compiler, so no -// `#![feature]` attributes should be added. +// WARNING: We want to be able to build this crate with a stable compiler, +// so no `#![feature]` attributes should be added! use rustc_lexer::unescape; pub use Alignment::*; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 07712636445..b824eb51ef7 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -429,6 +429,7 @@ mod desc { pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`"; pub const parse_inlining_threshold: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number"; + pub const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)"; } mod parse { @@ -1331,6 +1332,33 @@ mod parse { } true } + + pub(crate) fn parse_llvm_module_flag( + slot: &mut Vec<(String, u32, String)>, + v: Option<&str>, + ) -> bool { + let elements = v.unwrap_or_default().split(':').collect::<Vec<_>>(); + let [key, md_type, value, behavior] = elements.as_slice() else { + return false; + }; + if *md_type != "u32" { + // Currently we only support u32 metadata flags, but require the + // type for forward-compatibility. + return false; + } + let Ok(value) = value.parse::<u32>() else { + return false; + }; + let behavior = behavior.to_lowercase(); + let all_behaviors = + ["error", "warning", "require", "override", "append", "appendunique", "max", "min"]; + if !all_behaviors.contains(&behavior.as_str()) { + return false; + } + + slot.push((key.to_string(), value, behavior)); + true + } } options! { @@ -1629,6 +1657,8 @@ options! { "link native libraries in the linker invocation (default: yes)"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), + llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED], + "a list of module flags to pass to LLVM (space separated)"), llvm_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED], "a list LLVM plugins to enable (space separated)"), llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 170f53a7a69..8845320ca8b 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,7 +9,7 @@ use crate::rustc_internal::{IndexMap, RustcInternal}; use crate::rustc_smir::hir::def::DefKind; -use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; +use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyParamRegion, Region}; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -682,10 +682,44 @@ impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { type T = stable_mir::mir::Place; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { stable_mir::mir::Place { local: self.local.as_usize(), - projection: format!("{:?}", self.projection), + projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { + type T = stable_mir::mir::ProjectionElem; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use mir::ProjectionElem::*; + match self { + Deref => stable_mir::mir::ProjectionElem::Deref, + Field(idx, ty) => { + stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables)) + } + Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)), + ConstantIndex { offset, min_length, from_end } => { + stable_mir::mir::ProjectionElem::ConstantIndex { + offset: *offset, + min_length: *min_length, + from_end: *from_end, + } + } + Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice { + from: *from, + to: *to, + from_end: *from_end, + }, + // MIR includes an `Option<Symbol>` argument for `Downcast` that is the name of the + // variant, used for printing MIR. However this information should also be accessible + // via a lookup using the `VariantIdx`. The `Option<Symbol>` argument is therefore + // dropped when converting to Stable MIR. A brief justification for this decision can be + // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 + Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)), + OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)), + Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)), } } } @@ -693,8 +727,8 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { type T = stable_mir::mir::UserTypeProjection; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - UserTypeProjection { base: self.base.as_usize(), projection: format!("{:?}", self.projs) } + fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { + UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) } } } @@ -1695,7 +1729,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::RegionKind; match self { - ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion { + ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { def_id: tables.region_def(early_reg.def_id), index: early_reg.index, name: early_reg.name.to_string(), diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 80dec80bf03..1501e7d0cf7 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -282,12 +282,12 @@ fn encode_region<'tcx>( s.push('E'); compress(dict, DictKey::Region(region), &mut s); } - // FIXME(@lcnr): Why is `ReEarlyBound` reachable here. - RegionKind::ReEarlyBound(..) | RegionKind::ReErased => { + // FIXME(@lcnr): Why is `ReEarlyParam` reachable here. + RegionKind::ReEarlyParam(..) | RegionKind::ReErased => { s.push_str("u6region"); compress(dict, DictKey::Region(region), &mut s); } - RegionKind::ReFree(..) + RegionKind::ReLateParam(..) | RegionKind::ReStatic | RegionKind::ReError(_) | RegionKind::ReVar(..) diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs index 5f08bc0039a..004dc45263c 100644 --- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs +++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs @@ -237,7 +237,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> { CanonicalizeMode::Response { .. } => return r, }, - ty::ReFree(_) | ty::ReEarlyBound(_) => match self.canonicalize_mode { + ty::ReLateParam(_) | ty::ReEarlyParam(_) => match self.canonicalize_mode { CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => bug!("unexpected region in response: {r:?}"), }, diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 69bfdd4688c..951080ac61a 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { visitor: &mut V, ) -> ControlFlow<V::BreakTy> { // HACK: An arbitrary cutoff to avoid dealing with overflow and cycles. - if self.goal.depth >= 10 { + if self.goal.depth <= 10 { let infcx = self.goal.infcx; infcx.probe(|_| { let mut instantiated_goals = vec![]; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 787d8063005..7ca33ae41c0 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -20,6 +20,7 @@ use crate::traits::{ }; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, TraitEngine}; @@ -1002,7 +1003,12 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> { // and then prove the resulting predicate as a nested goal. let trait_ref = match predicate.kind().no_bound_vars() { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref, - Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))) => { + Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))) + if matches!( + infcx.tcx.def_kind(proj.projection_ty.def_id), + DefKind::AssocTy | DefKind::AssocConst + ) => + { proj.projection_ty.trait_ref(infcx.tcx) } _ => return ControlFlow::Continue(()), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index fff5510bbfb..2c004c65929 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -484,7 +484,7 @@ fn is_impossible_associated_item( t.super_visit_with(self) } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - if let ty::ReEarlyBound(param) = r.kind() + if let ty::ReEarlyParam(param) = r.kind() && let param_def_id = self.generics.region_param(¶m, self.tcx).def_id && self.tcx.parent(param_def_id) == self.trait_item_def_id { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 5c34df1ed50..24afd7dc357 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -53,9 +53,9 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => { match data { ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { - // We need to remap all of the late-bound lifetimes in theassumed wf types - // of the fn (which are represented as ReFree) to the early-bound lifetimes - // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). + // We need to remap all of the late-bound lifetimes in the assumed wf types + // of the fn (which are represented as ReLateParam) to the early-bound lifetimes + // of the RPITIT (which are represented by ReEarlyParam owned by the opaque). // Luckily, this is very easy to do because we already have that mapping // stored in the HIR of this RPITIT. // @@ -65,19 +65,19 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let mut mapping = FxHashMap::default(); let generics = tcx.generics_of(def_id); - // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, - // since it has been liberated), map it back to the early-bound lifetime of + // For each captured opaque lifetime, if it's late-bound (`ReLateParam` in this + // case, since it has been liberated), map it back to the early-bound lifetime of // the GAT. Since RPITITs also have all of the fn's generics, we slice only // the end of the list corresponding to the opaque's generics. for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); - if matches!(*orig_lt, ty::ReFree(..)) { + if matches!(*orig_lt, ty::ReLateParam(..)) { mapping.insert( orig_lt, - ty::Region::new_early_bound( + ty::Region::new_early_param( tcx, - ty::EarlyBoundRegion { + ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name, @@ -90,7 +90,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let remapped_wf_tys = tcx.fold_regions( tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), |region, _| { - // If `region` is a `ReFree` that is captured by the + // If `region` is a `ReLateParam` that is captured by the // opaque, remap it to its corresponding the early- // bound region. if let Some(remapped_region) = mapping.get(®ion) { diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 9242a1a751b..7ca2da42042 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -159,10 +159,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { // Only check that the parent generics of the TAIT/RPIT are unique. // the args owned by the opaque are going to always be duplicate // lifetime params for RPITs, and empty for TAITs. - match self - .tcx - .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::Bound) - { + match self.tcx.uses_unique_generic_params( + &alias_ty.args[..parent_count], + CheckRegions::FromFunction, + ) { Ok(()) => { // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not // supported at all, so this is sound to do, but once we want to support them, you'll diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index d10927b0d93..af741a0a3a0 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -8,7 +8,7 @@ bitflags! { // required. /// Does this have `Param`? const HAS_TY_PARAM = 1 << 0; - /// Does this have `ReEarlyBound`? + /// Does this have `ReEarlyParam`? const HAS_RE_PARAM = 1 << 1; /// Does this have `ConstKind::Param`? const HAS_CT_PARAM = 1 << 2; diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 7f75e5b35a2..da504c54fdd 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -47,9 +47,9 @@ pub trait Interner: Sized { // Kinds of regions type Region: Clone + DebugWithInfcx<Self> + Hash + Ord; - type EarlyBoundRegion: Clone + Debug + Hash + Ord; + type EarlyParamRegion: Clone + Debug + Hash + Ord; type BoundRegion: Clone + Debug + Hash + Ord; - type FreeRegion: Clone + Debug + Hash + Ord; + type LateParamRegion: Clone + Debug + Hash + Ord; type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord; type PlaceholderRegion: Clone + Debug + Hash + Ord; diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index fc9eaf63ac8..5d3ce49bc8f 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -22,8 +22,8 @@ use self::RegionKind::*; /// ```text /// static ----------+-----...------+ (greatest) /// | | | -/// early-bound and | | -/// free regions | | +/// param regions | | +/// | | | /// | | | /// | | | /// empty(root) placeholder(U1) | @@ -88,8 +88,8 @@ use self::RegionKind::*; /// To do this, we replace the bound regions with placeholder markers, /// which don't satisfy any relation not explicitly provided. /// -/// There are two kinds of placeholder regions in rustc: `ReFree` and -/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed +/// There are two kinds of placeholder regions in rustc: `ReLateParam` and +/// `RePlaceholder`. When checking an item's body, `ReLateParam` is supposed /// to be used. These also support explicit bounds: both the internally-stored /// *scope*, which the region is assumed to outlive, as well as other /// relations stored in the `FreeRegionMap`. Note that these relations @@ -123,26 +123,35 @@ use self::RegionKind::*; )] #[derive(TyEncodable, TyDecodable)] pub enum RegionKind<I: Interner> { - /// Region bound in a type or fn declaration which will be - /// substituted 'early' -- that is, at the same time when type - /// parameters are substituted. - ReEarlyBound(I::EarlyBoundRegion), + /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. + /// + /// There are some important differences between region and type parameters. + /// Not all region parameters in the source are represented via `ReEarlyParam`: + /// late-bound function parameters are instead lowered to a `ReBound`. Late-bound + /// regions get eagerly replaced with `ReLateParam` which behaves in the same way as + /// `ReEarlyParam`. Region parameters are also sometimes implicit, + /// e.g. in `impl Trait for &()`. + ReEarlyParam(I::EarlyParamRegion), /// A higher-ranked region. These represent either late-bound function parameters /// or bound variables from a `for<'a>`-binder. /// /// While inside of a function, e.g. during typeck, the late-bound function parameters - /// can be converted to `ReFree` by calling `tcx.liberate_late_bound_regions`. + /// can be converted to `ReLateParam` by calling `tcx.liberate_late_bound_regions`. /// /// Bound regions inside of types **must not** be erased, as they impact trait /// selection and the `TypeId` of that type. `for<'a> fn(&'a ())` and /// `fn(&'static ())` are different types and have to be treated as such. ReBound(DebruijnIndex, I::BoundRegion), - /// When checking a function body, the types of all arguments and so forth - /// that refer to bound region parameters are modified to refer to free - /// region parameters. - ReFree(I::FreeRegion), + /// Late-bound function parameters are represented using a `ReBound`. When + /// inside of a function, we convert these bound variables to placeholder + /// parameters via `tcx.liberate_late_bound_regions`. They are then treated + /// the same way as `ReEarlyParam` while inside of the function. + /// + /// See <https://rustc-dev-guide.rust-lang.org/early-late-bound-summary.html> for + /// more info about early and late bound lifetime parameters. + ReLateParam(I::LateParamRegion), /// Static data that has an "infinite" lifetime. Top in the region lattice. ReStatic, @@ -150,8 +159,11 @@ pub enum RegionKind<I: Interner> { /// A region variable. Should not exist outside of type inference. ReVar(I::InferRegion), - /// A placeholder region -- basically, the higher-ranked version of `ReFree`. + /// A placeholder region -- the higher-ranked version of `ReLateParam`. /// Should not exist outside of type inference. + /// + /// Used when instantiating a `forall` binder via + /// `infcx.instantiate_binder_with_placeholders`. RePlaceholder(I::PlaceholderRegion), /// Erased region, used by trait selection, in MIR and during codegen. @@ -166,9 +178,9 @@ pub enum RegionKind<I: Interner> { #[inline] const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize { match value { - ReEarlyBound(_) => 0, + ReEarlyParam(_) => 0, ReBound(_, _) => 1, - ReFree(_) => 2, + ReLateParam(_) => 2, ReStatic => 3, ReVar(_) => 4, RePlaceholder(_) => 5, @@ -180,9 +192,9 @@ const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize { // This is manually implemented because a derive would require `I: Copy` impl<I: Interner> Copy for RegionKind<I> where - I::EarlyBoundRegion: Copy, + I::EarlyParamRegion: Copy, I::BoundRegion: Copy, - I::FreeRegion: Copy, + I::LateParamRegion: Copy, I::InferRegion: Copy, I::PlaceholderRegion: Copy, I::ErrorGuaranteed: Copy, @@ -195,9 +207,9 @@ impl<I: Interner> PartialEq for RegionKind<I> { fn eq(&self, other: &RegionKind<I>) -> bool { regionkind_discriminant(self) == regionkind_discriminant(other) && match (self, other) { - (ReEarlyBound(a_r), ReEarlyBound(b_r)) => a_r == b_r, + (ReEarlyParam(a_r), ReEarlyParam(b_r)) => a_r == b_r, (ReBound(a_d, a_r), ReBound(b_d, b_r)) => a_d == b_d && a_r == b_r, - (ReFree(a_r), ReFree(b_r)) => a_r == b_r, + (ReLateParam(a_r), ReLateParam(b_r)) => a_r == b_r, (ReStatic, ReStatic) => true, (ReVar(a_r), ReVar(b_r)) => a_r == b_r, (RePlaceholder(a_r), RePlaceholder(b_r)) => a_r == b_r, @@ -223,13 +235,13 @@ impl<I: Interner> DebugWithInfcx<I> for RegionKind<I> { f: &mut core::fmt::Formatter<'_>, ) -> core::fmt::Result { match this.data { - ReEarlyBound(data) => write!(f, "ReEarlyBound({data:?})"), + ReEarlyParam(data) => write!(f, "ReEarlyParam({data:?})"), ReBound(binder_id, bound_region) => { write!(f, "ReBound({binder_id:?}, {bound_region:?})") } - ReFree(fr) => write!(f, "{fr:?}"), + ReLateParam(fr) => write!(f, "{fr:?}"), ReStatic => f.write_str("ReStatic"), @@ -252,9 +264,9 @@ impl<I: Interner> fmt::Debug for RegionKind<I> { // This is not a derived impl because a derive would require `I: HashStable` impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I> where - I::EarlyBoundRegion: HashStable<CTX>, + I::EarlyParamRegion: HashStable<CTX>, I::BoundRegion: HashStable<CTX>, - I::FreeRegion: HashStable<CTX>, + I::LateParamRegion: HashStable<CTX>, I::InferRegion: HashStable<CTX>, I::PlaceholderRegion: HashStable<CTX>, { @@ -269,10 +281,10 @@ where d.hash_stable(hcx, hasher); r.hash_stable(hcx, hasher); } - ReEarlyBound(r) => { + ReEarlyParam(r) => { r.hash_stable(hcx, hasher); } - ReFree(r) => { + ReLateParam(r) => { r.hash_stable(hcx, hasher); } RePlaceholder(r) => { diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 06933783685..351e7bb69c3 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -398,22 +398,128 @@ pub enum Operand { pub struct Place { pub local: Local, /// projection out of a place (access a field, deref a pointer, etc) - pub projection: String, + pub projection: Vec<ProjectionElem>, +} + +// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This +// is so it can be used for both Places (for which the projection elements are of type +// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements +// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use +// ProjectionElem for Places. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ProjectionElem { + /// Dereference projections (e.g. `*_1`) project to the address referenced by the base place. + Deref, + + /// A field projection (e.g., `f` in `_1.f`) project to a field in the base place. The field is + /// referenced by source-order index rather than the name of the field. The fields type is also + /// given. + Field(FieldIdx, Ty), + + /// Index into a slice/array. The value of the index is computed at runtime using the `V` + /// argument. + /// + /// Note that this does not also dereference, and so it does not exactly correspond to slice + /// indexing in Rust. In other words, in the below Rust code: + /// + /// ```rust + /// let x = &[1, 2, 3, 4]; + /// let i = 2; + /// x[i]; + /// ``` + /// + /// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same + /// thing is true of the `ConstantIndex` and `Subslice` projections below. + Index(Local), + + /// Index into a slice/array given by offsets. + /// + /// These indices are generated by slice patterns. Easiest to explain by example: + /// + /// ```ignore (illustrative) + /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false }, + /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false }, + /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true }, + /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true }, + /// ``` + ConstantIndex { + /// index or -index (in Python terms), depending on from_end + offset: u64, + /// The thing being indexed must be at least this long. For arrays this + /// is always the exact length. + min_length: u64, + /// Counting backwards from end? This is always false when indexing an + /// array. + from_end: bool, + }, + + /// Projects a slice from the base place. + /// + /// These indices are generated by slice patterns. If `from_end` is true, this represents + /// `slice[from..slice.len() - to]`. Otherwise it represents `array[from..to]`. + Subslice { + from: u64, + to: u64, + /// Whether `to` counts from the start or end of the array/slice. + from_end: bool, + }, + + /// "Downcast" to a variant of an enum or a coroutine. + Downcast(VariantIdx), + + /// Like an explicit cast from an opaque type to a concrete type, but without + /// requiring an intermediate variable. + OpaqueCast(Ty), + + /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where + /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping + /// explicit during optimizations and codegen. + /// + /// This projection doesn't impact the runtime behavior of the program except for potentially changing + /// some type metadata of the interpreter or codegen backend. + Subtype(Ty), } #[derive(Clone, Debug, Eq, PartialEq)] pub struct UserTypeProjection { pub base: UserTypeAnnotationIndex, - pub projection: String, + + pub projection: Opaque, } pub type Local = usize; pub const RETURN_LOCAL: Local = 0; +/// The source-order index of a field in a variant. +/// +/// For example, in the following types, +/// ```ignore(illustrative) +/// enum Demo1 { +/// Variant0 { a: bool, b: i32 }, +/// Variant1 { c: u8, d: u64 }, +/// } +/// struct Demo2 { e: u8, f: u16, g: u8 } +/// ``` +/// `a`'s `FieldIdx` is `0`, +/// `b`'s `FieldIdx` is `1`, +/// `c`'s `FieldIdx` is `0`, and +/// `g`'s `FieldIdx` is `2`. type FieldIdx = usize; /// The source-order index of a variant in a type. +/// +/// For example, in the following types, +/// ```ignore(illustrative) +/// enum Demo1 { +/// Variant0 { a: bool, b: i32 }, +/// Variant1 { c: u8, d: u64 }, +/// } +/// struct Demo2 { e: u8, f: u16, g: u8 } +/// ``` +/// `a` is in the variant with the `VariantIdx` of `0`, +/// `c` is in the variant with the `VariantIdx` of `1`, and +/// `g` is in the variant with the `VariantIdx` of `0`. pub type VariantIdx = usize; type UserTypeAnnotationIndex = usize; @@ -536,6 +642,10 @@ impl Constant { } impl Place { + // FIXME(klinvill): This function is expected to resolve down the chain of projections to get + // the type referenced at the end of it. E.g. calling `ty()` on `*(_1.f)` should end up + // returning the type referenced by `f`. The information needed to do this may not currently be + // present in Stable MIR since at least an implementation for AdtDef is probably needed. pub fn ty(&self, locals: &[LocalDecl]) -> Ty { let _start_ty = locals[self.local].ty; todo!("Implement projection") diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index 806dced71ff..475d6e9763d 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -76,6 +76,15 @@ pub trait MirVisitor { self.super_place(place, ptx, location) } + fn visit_projection_elem( + &mut self, + elem: &ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + self.super_projection_elem(elem, ptx, location); + } + fn visit_local(&mut self, local: &Local, ptx: PlaceContext, location: Location) { let _ = (local, ptx, location); } @@ -264,7 +273,29 @@ pub trait MirVisitor { fn super_place(&mut self, place: &Place, ptx: PlaceContext, location: Location) { let _ = location; let _ = ptx; - visit_opaque(&Opaque(place.projection.clone())); + self.visit_local(&place.local, ptx, location); + + for elem in &place.projection { + self.visit_projection_elem(elem, ptx, location); + } + } + + fn super_projection_elem( + &mut self, + elem: &ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + match elem { + ProjectionElem::Deref => {} + ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), + ProjectionElem::Index(local) => self.visit_local(local, ptx, location), + ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {} + ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} + ProjectionElem::Downcast(_idx) => {} + ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), + ProjectionElem::Subtype(ty) => self.visit_ty(ty, location), + } } fn super_rvalue(&mut self, rvalue: &Rvalue, location: Location) { diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index d2f1f3af0ce..e95c09abe78 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -61,7 +61,7 @@ pub struct Region { #[derive(Clone, Debug, Eq, PartialEq)] pub enum RegionKind { - ReEarlyBound(EarlyBoundRegion), + ReEarlyParam(EarlyParamRegion), ReBound(DebruijnIndex, BoundRegion), ReStatic, RePlaceholder(Placeholder<BoundRegion>), @@ -71,7 +71,7 @@ pub enum RegionKind { pub(crate) type DebruijnIndex = u32; #[derive(Clone, Debug, Eq, PartialEq)] -pub struct EarlyBoundRegion { +pub struct EarlyParamRegion { pub def_id: RegionDef, pub index: u32, pub name: Symbol, diff --git a/src/doc/unstable-book/src/compiler-flags/llvm-module-flag.md b/src/doc/unstable-book/src/compiler-flags/llvm-module-flag.md new file mode 100644 index 00000000000..454ad0a9a6d --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/llvm-module-flag.md @@ -0,0 +1,12 @@ +# `llvm-module-flag` + +--------------------- + +This flag allows adding a key/value to the `!llvm.module.flags` metadata in the +LLVM-IR for a compiled Rust module. The syntax is + +`-Z llvm_module_flag=<name>:<type>:<value>:<behavior>` + +Currently only u32 values are supported but the type is required to be specified +for forward compatibility. The `behavior` element must match one of the named +LLVM [metadata behaviors](https://llvm.org/docs/LangRef.html#module-flags-metadata) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index eb946e82f39..007c5e113b7 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -723,7 +723,7 @@ where fn region_name(region: Region<'_>) -> Option<Symbol> { match *region { - ty::ReEarlyBound(r) => Some(r.name), + ty::ReEarlyParam(r) => Some(r.name), _ => None, } } @@ -743,7 +743,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { match *r { // These are the regions that can be seen in the AST. ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r), - ty::ReEarlyBound(_) | ty::ReStatic | ty::ReBound(..) | ty::ReError(_) => r, + ty::ReEarlyParam(_) | ty::ReStatic | ty::ReBound(..) | ty::ReError(_) => r, r => bug!("unexpected region: {r:?}"), } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d33e41dc2b3..429589f01fd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -287,9 +287,9 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Life ty::ReStatic => Some(Lifetime::statik()), _ if !region.has_name() => None, ty::ReBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => Some(Lifetime(name)), - ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)), + ty::ReEarlyParam(ref data) => Some(Lifetime(data.name)), ty::ReBound(..) - | ty::ReFree(..) + | ty::ReLateParam(..) | ty::ReVar(..) | ty::ReError(_) | ty::RePlaceholder(..) @@ -1928,13 +1928,13 @@ fn clean_trait_object_lifetime_bound<'tcx>( // latter contrary to `clean_middle_region`. match *region { ty::ReStatic => Some(Lifetime::statik()), - ty::ReEarlyBound(region) if region.name != kw::Empty => Some(Lifetime(region.name)), + ty::ReEarlyParam(region) if region.name != kw::Empty => Some(Lifetime(region.name)), ty::ReBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) if name != kw::Empty => { Some(Lifetime(name)) } - ty::ReEarlyBound(_) + ty::ReEarlyParam(_) | ty::ReBound(..) - | ty::ReFree(_) + | ty::ReLateParam(_) | ty::ReVar(_) | ty::RePlaceholder(_) | ty::ReErased diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index dda06d4c9c1..a43ea5582b7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -53,6 +53,7 @@ extern crate rustc_interface; extern crate rustc_lexer; extern crate rustc_lint; extern crate rustc_lint_defs; +extern crate rustc_log; extern crate rustc_macros; extern crate rustc_metadata; extern crate rustc_middle; @@ -175,7 +176,7 @@ pub fn main() { // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml). init_logging(&handler); - rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG"); + rustc_driver::init_logger(&handler, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")); let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) { Some(args) => main_args(&mut handler, &args, using_internal_features), diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index d6fa742b796..4db65b0d04f 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -175,7 +175,7 @@ impl<'tcx> PassByRefOrValue { }, // Early bound regions on functions are either from the containing item, are bounded by another // lifetime, or are used as a bound for a type or lifetime. - RegionKind::ReEarlyBound(..) => continue, + RegionKind::ReEarlyParam(..) => continue, _ => (), } diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index c6ac96a4539..1d4b4d10d50 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -465,9 +465,9 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .walk() .filter_map(|arg| { arg.as_region().and_then(|lifetime| match lifetime.kind() { - ty::ReEarlyBound(r) => Some(r.def_id), + ty::ReEarlyParam(r) => Some(r.def_id), ty::ReBound(_, r) => r.kind.get_id(), - ty::ReFree(r) => r.bound_region.get_id(), + ty::ReLateParam(r) => r.bound_region.get_id(), ty::ReStatic | ty::ReVar(_) | ty::RePlaceholder(_) diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 62a58576da5..3a23ff7fe6a 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -1,6 +1,7 @@ #![feature(rustc_private)] extern crate rustc_driver; +extern crate rustc_log; extern crate rustc_session; use std::env; @@ -173,7 +174,7 @@ fn parse_args() -> (OutputFormat, PathBuf) { fn main() { let handler = rustc_session::EarlyErrorHandler::new(rustc_session::config::ErrorOutputType::default()); - rustc_driver::init_env_logger(&handler, "RUST_LOG"); + rustc_driver::init_logger(&handler, rustc_log::LoggerConfig::from_env("RUST_LOG")); let (format, dst) = parse_args(); let result = main_with_result(format, &dst); if let Err(e) = result { diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0d677d36e36..673e11163c8 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6d069a0ac7a423db87d86320edd39974f9f0c492 +525c91d096194decbfa70245743d697fb010ac91 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index cd628444fed..7f777cd4727 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -9,11 +9,12 @@ extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_hir; extern crate rustc_interface; +extern crate rustc_log; extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; -use std::env; +use std::env::{self, VarError}; use std::num::NonZeroU64; use std::path::PathBuf; use std::str::FromStr; @@ -183,45 +184,54 @@ macro_rules! show_error { ($($tt:tt)*) => { show_error(&format_args!($($tt)*)) }; } -fn init_early_loggers(handler: &EarlyErrorHandler) { - // Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to - // initialize them both, and we always initialize `miri`'s first. - let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE"); - env_logger::init_from_env(env); - // Enable verbose entry/exit logging by default if MIRI_LOG is set. - if env::var_os("MIRI_LOG").is_some() && env::var_os("RUSTC_LOG_ENTRY_EXIT").is_none() { - env::set_var("RUSTC_LOG_ENTRY_EXIT", "1"); - } - // We only initialize `rustc` if the env var is set (so the user asked for it). - // If it is not set, we avoid initializing now so that we can initialize - // later with our custom settings, and *not* log anything for what happens before - // `miri` gets started. - if env::var_os("RUSTC_LOG").is_some() { - rustc_driver::init_rustc_env_logger(handler); - } -} +fn rustc_logger_config() -> rustc_log::LoggerConfig { + // Start with the usual env vars. + let mut cfg = rustc_log::LoggerConfig::from_env("RUSTC_LOG"); -fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) { - // We initialize loggers right before we start evaluation. We overwrite the `RUSTC_LOG` - // env var if it is not set, control it based on `MIRI_LOG`. - // (FIXME: use `var_os`, but then we need to manually concatenate instead of `format!`.) + // Overwrite if MIRI_LOG is set. if let Ok(var) = env::var("MIRI_LOG") { - if env::var_os("RUSTC_LOG").is_none() { + // MIRI_LOG serves as default for RUSTC_LOG, if that is not set. + if matches!(cfg.filter, Err(VarError::NotPresent)) { // We try to be a bit clever here: if `MIRI_LOG` is just a single level // used for everything, we only apply it to the parts of rustc that are // CTFE-related. Otherwise, we use it verbatim for `RUSTC_LOG`. // This way, if you set `MIRI_LOG=trace`, you get only the right parts of // rustc traced, but you can also do `MIRI_LOG=miri=trace,rustc_const_eval::interpret=debug`. if log::Level::from_str(&var).is_ok() { - env::set_var( - "RUSTC_LOG", - format!("rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}"), - ); + cfg.filter = Ok(format!( + "rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}" + )); } else { - env::set_var("RUSTC_LOG", &var); + cfg.filter = Ok(var); } - rustc_driver::init_rustc_env_logger(handler); } + // Enable verbose entry/exit logging by default if MIRI_LOG is set. + if matches!(cfg.verbose_entry_exit, Err(VarError::NotPresent)) { + cfg.verbose_entry_exit = Ok(format!("1")); + } + } + + cfg +} + +fn init_early_loggers(handler: &EarlyErrorHandler) { + // Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to + // initialize them both, and we always initialize `miri`'s first. + let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE"); + env_logger::init_from_env(env); + // Now for rustc. We only initialize `rustc` if the env var is set (so the user asked for it). + // If it is not set, we avoid initializing now so that we can initialize later with our custom + // settings, and *not* log anything for what happens before `miri` gets started. + if env::var_os("RUSTC_LOG").is_some() { + rustc_driver::init_logger(handler, rustc_logger_config()); + } +} + +fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) { + // If `RUSTC_LOG` is not set, then `init_early_loggers` did not call + // `rustc_driver::init_logger`, so we have to do this now. + if env::var_os("RUSTC_LOG").is_none() { + rustc_driver::init_logger(handler, rustc_logger_config()); } // If `MIRI_BACKTRACE` is set and `RUSTC_CTFE_BACKTRACE` is not, set `RUSTC_CTFE_BACKTRACE`. diff --git a/tests/codegen/llvm_module_flags.rs b/tests/codegen/llvm_module_flags.rs new file mode 100644 index 00000000000..acc035086de --- /dev/null +++ b/tests/codegen/llvm_module_flags.rs @@ -0,0 +1,7 @@ +// Test for -Z llvm_module_flags +// compile-flags: -Z llvm_module_flag=foo:u32:123:error -Z llvm_module_flag=bar:u32:42:max + +fn main() {} + +// CHECK: !{i32 1, !"foo", i32 123} +// CHECK: !{i32 7, !"bar", i32 42} diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs new file mode 100644 index 00000000000..9c649a2effc --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/projections.rs @@ -0,0 +1,173 @@ +// run-pass +// Tests the Stable MIR projections API + +// ignore-stage1 +// ignore-cross-compile +// ignore-remote +// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 +// edition: 2021 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] + +extern crate rustc_hir; +extern crate rustc_middle; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate stable_mir; + +use rustc_hir::def::DefKind; +use rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind}; +use stable_mir::ty::{RigidTy, TyKind}; +use std::assert_matches::assert_matches; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "input"; + +/// Tests projections within Place objects +fn test_place_projections(_tcx: TyCtxt<'_>) -> ControlFlow<()> { + let items = stable_mir::all_local_items(); + let body = get_item(&items, (DefKind::Fn, "projections")).unwrap().body(); + assert_eq!(body.blocks.len(), 4); + // The first statement assigns `&s.c` to a local. The projections include a deref for `s`, since + // `s` is passed as a reference argument, and a field access for field `c`. + match &body.blocks[0].statements[0].kind { + StatementKind::Assign( + stable_mir::mir::Place { local: _, projection: local_proj }, + Rvalue::Ref(_, _, stable_mir::mir::Place { local: _, projection: r_proj }), + ) => { + // We can't match on vecs, only on slices. Comparing statements for equality wouldn't be + // any easier since we'd then have to add in the expected local and region values + // instead of matching on wildcards. + assert!(local_proj.is_empty()); + match &r_proj[..] { + // Similarly we can't match against a type, only against its kind. + [ProjectionElem::Deref, ProjectionElem::Field(2, ty)] => assert_matches!( + ty.kind(), + TyKind::RigidTy(RigidTy::Uint(stable_mir::ty::UintTy::U8)) + ), + other => panic!( + "Unable to match against expected rvalue projection. Expected the projection \ + for `s.c`, which is a Deref and u8 Field. Got: {:?}", + other + ), + }; + } + other => panic!( + "Unable to match against expected Assign statement with a Ref rvalue. Expected the \ + statement to assign `&s.c` to a local. Got: {:?}", + other + ), + }; + // This statement assigns `slice[1]` to a local. The projections include a deref for `slice`, + // since `slice` is a reference, and an index. + match &body.blocks[2].statements[0].kind { + StatementKind::Assign( + stable_mir::mir::Place { local: _, projection: local_proj }, + Rvalue::Use(stable_mir::mir::Operand::Copy(stable_mir::mir::Place { + local: _, + projection: r_proj, + })), + ) => { + // We can't match on vecs, only on slices. Comparing for equality wouldn't be any easier + // since we'd then have to add in the expected local values instead of matching on + // wildcards. + assert!(local_proj.is_empty()); + assert_matches!(r_proj[..], [ProjectionElem::Deref, ProjectionElem::Index(_)]); + } + other => panic!( + "Unable to match against expected Assign statement with a Use rvalue. Expected the \ + statement to assign `slice[1]` to a local. Got: {:?}", + other + ), + }; + // The first terminator gets a slice of an array via the Index operation. Specifically it + // performs `&vals[1..3]`. There are no projections in this case, the arguments are just locals. + match &body.blocks[0].terminator.kind { + stable_mir::mir::TerminatorKind::Call { args, .. } => + // We can't match on vecs, only on slices. Comparing for equality wouldn't be any easier + // since we'd then have to add in the expected local values instead of matching on + // wildcards. + { + match &args[..] { + [ + stable_mir::mir::Operand::Move(stable_mir::mir::Place { + local: _, + projection: arg1_proj, + }), + stable_mir::mir::Operand::Move(stable_mir::mir::Place { + local: _, + projection: arg2_proj, + }), + ] => { + assert!(arg1_proj.is_empty()); + assert!(arg2_proj.is_empty()); + } + other => { + panic!( + "Unable to match against expected arguments to Index call. Expected two \ + move operands. Got: {:?}", + other + ) + } + } + } + other => panic!( + "Unable to match against expected Call terminator. Expected a terminator that calls \ + the Index operation. Got: {:?}", + other + ), + }; + + ControlFlow::Continue(()) +} + +// Use internal API to find a function in a crate. +fn get_item<'a>( + items: &'a stable_mir::CrateItems, + item: (DefKind, &str), +) -> Option<&'a stable_mir::CrateItem> { + items.iter().find(|crate_item| { + crate_item.kind().to_string() == format!("{:?}", item.0) && crate_item.name() == item.1 + }) +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, tcx, test_place_projections(tcx)).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + pub struct Struct1 {{ _a: u8, _b: u16, c: u8 }} + + pub fn projections(s: &Struct1) -> u8 {{ + let v = &s.c; + let vals = [1, 2, 3, 4]; + let slice = &vals[1..3]; + v + slice[1] + }}"# + )?; + Ok(()) +} diff --git a/tests/ui/impl-trait/auto-trait-coherence.next.stderr b/tests/ui/impl-trait/auto-trait-coherence.next.stderr index 7833ac688ba..cee359997b4 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.next.stderr +++ b/tests/ui/impl-trait/auto-trait-coherence.next.stderr @@ -6,6 +6,8 @@ LL | impl<T: Send> AnotherTrait for T {} ... LL | impl AnotherTrait for D<OpaqueType> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>` + | + = note: upstream crates may add a new impl of trait `std::marker::Send` for type `OpaqueType` in future versions error: aborting due to previous error diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr b/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr index 84b61dc5044..4cd4febc4f0 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr @@ -1,4 +1,4 @@ -error: {foo<ReEarlyBound(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} +error: {foo<ReEarlyParam(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} --> $DIR/erased-regions-in-hidden-ty.rs:11:36 | LL | fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Fn() + 'static { diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr b/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr index 84b61dc5044..4cd4febc4f0 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr @@ -1,4 +1,4 @@ -error: {foo<ReEarlyBound(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} +error: {foo<ReEarlyParam(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} --> $DIR/erased-regions-in-hidden-ty.rs:11:36 | LL | fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Fn() + 'static { diff --git a/tests/ui/methods/method-ambiguity-no-rcvr.rs b/tests/ui/methods/method-ambiguity-no-rcvr.rs new file mode 100644 index 00000000000..8f36011d41f --- /dev/null +++ b/tests/ui/methods/method-ambiguity-no-rcvr.rs @@ -0,0 +1,14 @@ +struct Qux; + +trait Foo { + fn foo(); +} + +trait FooBar { + fn foo() {} +} + +fn main() { + Qux.foo(); + //~^ ERROR no method named `foo` found for struct `Qux` in the current scope +} diff --git a/tests/ui/methods/method-ambiguity-no-rcvr.stderr b/tests/ui/methods/method-ambiguity-no-rcvr.stderr new file mode 100644 index 00000000000..95c9d7ebac0 --- /dev/null +++ b/tests/ui/methods/method-ambiguity-no-rcvr.stderr @@ -0,0 +1,32 @@ +error[E0599]: no method named `foo` found for struct `Qux` in the current scope + --> $DIR/method-ambiguity-no-rcvr.rs:12:9 + | +LL | struct Qux; + | ---------- method `foo` not found for this struct +... +LL | Qux.foo(); + | ^^^ this is an associated function, not a method + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: candidate #1 is defined in the trait `Foo` + --> $DIR/method-ambiguity-no-rcvr.rs:4:5 + | +LL | fn foo(); + | ^^^^^^^^^ +note: candidate #2 is defined in the trait `FooBar` + --> $DIR/method-ambiguity-no-rcvr.rs:8:5 + | +LL | fn foo() {} + | ^^^^^^^^ +help: disambiguate the associated function for candidate #1 + | +LL | <Qux as Foo>::foo(Qux); + | ~~~~~~~~~~~~~~~~~~~~~~ +help: disambiguate the associated function for candidate #2 + | +LL | <Qux as FooBar>::foo(Qux); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr index ba885d1b97e..320f529624f 100644 --- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,17 +1,17 @@ -error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [ReEarlyBound(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a), T, ReEarlyBound(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a)])` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [ReEarlyParam(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a), T, ReEarlyParam(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a)])` captures lifetime that does not appear in bounds --> $DIR/impl-trait-captures.rs:11:5 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { | -- ------------ opaque type defined here | | - | hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here + | hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here LL | x | ^ | -help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [ReEarlyBound(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a), T, ReEarlyBound(DefId(0:14 ~ impl_trait_captures[aeb9]::foo::{opaque#0}::'a), 2, 'a)])` captures `ReFree(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound +help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [ReEarlyParam(DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a), 0, 'a), T, ReEarlyParam(DefId(0:14 ~ impl_trait_captures[aeb9]::foo::{opaque#0}::'a), 2, 'a)])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound | -LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) { - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) { + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to previous error |
