diff options
198 files changed, 1682 insertions, 1091 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 902b4b1a1ec..d1ae8c1fdbd 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -271,7 +271,7 @@ impl<'a> AstValidator<'a> { self.session.emit_err(InvalidVisibility { span: vis.span, - implied: if vis.kind.is_pub() { Some(vis.span) } else { None }, + implied: vis.kind.is_pub().then_some(vis.span), note, }); } @@ -294,27 +294,6 @@ impl<'a> AstValidator<'a> { } } - fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) { - // Check only lifetime parameters are present and that the lifetime - // parameters that are present have no bounds. - let non_lt_param_spans: Vec<_> = params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - if !param.bounds.is_empty() { - let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - self.session.emit_err(ForbiddenLifetimeBound { spans }); - } - None - } - _ => Some(param.ident.span), - }) - .collect(); - if !non_lt_param_spans.is_empty() { - self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans }); - } - } - fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { self.check_decl_num_args(fn_decl); self.check_decl_cvaradic_pos(fn_decl); @@ -745,7 +724,6 @@ impl<'a> AstValidator<'a> { ) .emit(); }); - self.check_late_bound_lifetime_defs(&bfty.generic_params); if let Extern::Implicit(_) = bfty.ext { let sig_span = self.session.source_map().next_point(ty.span.shrink_to_lo()); self.maybe_lint_missing_abi(sig_span, ty.id); @@ -1318,9 +1296,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { for predicate in &generics.where_clause.predicates { match predicate { WherePredicate::BoundPredicate(bound_pred) => { - // A type binding, eg `for<'c> Foo: Send+Clone+'c` - self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params); - // This is slightly complicated. Our representation for poly-trait-refs contains a single // binder and thus we only allow a single level of quantification. However, // the syntax of Rust permits quantification in two places in where clauses, @@ -1396,11 +1371,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef) { - self.check_late_bound_lifetime_defs(&t.bound_generic_params); - visit::walk_poly_trait_ref(self, t); - } - fn visit_variant_data(&mut self, s: &'a VariantData) { self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s)) } @@ -1437,10 +1407,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .emit(); } - if let FnKind::Closure(ClosureBinder::For { generic_params, .. }, ..) = fk { - self.check_late_bound_lifetime_defs(generic_params); - } - if let FnKind::Fn( _, _, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 89ba6f936d1..3af2ef4e727 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -11,6 +11,8 @@ use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi; +use crate::errors::ForbiddenLifetimeBound; + macro_rules! gate_feature_fn { ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{ let (visitor, has_feature, span, name, explain, help) = @@ -136,6 +138,34 @@ impl<'a> PostExpansionVisitor<'a> { } ImplTraitVisitor { vis: self }.visit_ty(ty); } + + fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) { + // Check only lifetime parameters are present and that the lifetime + // parameters that are present have no bounds. + let non_lt_param_spans: Vec<_> = params + .iter() + .filter_map(|param| match param.kind { + ast::GenericParamKind::Lifetime { .. } => None, + _ => Some(param.ident.span), + }) + .collect(); + // FIXME: gate_feature_post doesn't really handle multispans... + if !non_lt_param_spans.is_empty() && !self.features.non_lifetime_binders { + feature_err( + &self.sess.parse_sess, + sym::non_lifetime_binders, + non_lt_param_spans, + rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param, + ) + .emit(); + } + for param in params { + if !param.bounds.is_empty() { + let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); + self.sess.emit_err(ForbiddenLifetimeBound { spans }); + } + } + } } impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { @@ -147,7 +177,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { .. }) = attr_info { - gate_feature_fn!(self, has_feature, attr.span, *name, descr); + gate_feature_fn!(self, has_feature, attr.span, *name, *descr); } // Check unstable flavors of the `#[doc]` attribute. if attr.has_name(sym::doc) { @@ -306,6 +336,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::TyKind::BareFn(bare_fn_ty) => { // Function pointers cannot be `const` self.check_extern(bare_fn_ty.ext, ast::Const::No); + self.check_late_bound_lifetime_defs(&bare_fn_ty.generic_params); } ast::TyKind::Never => { gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental"); @@ -318,6 +349,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_ty(self, ty) } + fn visit_generics(&mut self, g: &'a ast::Generics) { + for predicate in &g.where_clause.predicates { + match predicate { + ast::WherePredicate::BoundPredicate(bound_pred) => { + // A type binding, eg `for<'c> Foo: Send+Clone+'c` + self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params); + } + _ => {} + } + } + visit::walk_generics(self, g); + } + fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) { if let ast::FnRetTy::Ty(output_ty) = ret_ty { if let ast::TyKind::Never = output_ty.kind { @@ -437,12 +481,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_pat(self, pattern) } + fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) { + self.check_late_bound_lifetime_defs(&t.bound_generic_params); + visit::walk_poly_trait_ref(self, t); + } + fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { if let Some(header) = fn_kind.header() { // Stability of const fn methods are covered in `visit_assoc_item` below. self.check_extern(header.ext, header.constness); } + if let FnKind::Closure(ast::ClosureBinder::For { generic_params, .. }, ..) = fn_kind { + self.check_late_bound_lifetime_defs(generic_params); + } + if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() { gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 40531c1c164..3d240108b4a 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -731,7 +731,7 @@ pub fn eval_condition( sess, sym::cfg_target_compact, cfg.span, - &"compact `cfg(target(..))` is experimental and subject to change" + "compact `cfg(target(..))` is experimental and subject to change" ).emit(); } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 1550958ab8e..d51cc652bfd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -180,20 +180,20 @@ trait TypeOpInfo<'tcx> { return; }; - let placeholder_region = tcx.mk_region(ty::RePlaceholder(ty::Placeholder { + let placeholder_region = tcx.mk_re_placeholder(ty::Placeholder { name: placeholder.name, universe: adjusted_universe.into(), - })); + }); let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) = error_element { let adjusted_universe = error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32()); adjusted_universe.map(|adjusted| { - tcx.mk_region(ty::RePlaceholder(ty::Placeholder { + tcx.mk_re_placeholder(ty::Placeholder { name: error_placeholder.name, universe: adjusted.into(), - })) + }) }) } else { None @@ -390,7 +390,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( error_region, ®ion_constraints, |vid| ocx.infcx.region_var_origin(vid), - |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))), + |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_re_var(vid)), ) } @@ -411,7 +411,7 @@ fn try_extract_error_from_region_constraints<'tcx>( } // FIXME: Should this check the universe of the var? Constraint::VarSubReg(vid, sup) if sup == placeholder_region => { - Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone())) + Some((infcx.tcx.mk_re_var(vid), cause.clone())) } _ => None, } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7b07c2a4633..9e90ca3b92c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1186,11 +1186,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return None; }; debug!("checking call args for uses of inner_param: {:?}", args); - if args.contains(&Operand::Move(inner_param)) { - Some((loc, term)) - } else { - None - } + args.contains(&Operand::Move(inner_param)).then_some((loc, term)) }) else { debug!("no uses of inner_param found as a by-move call arg"); return; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a82e695d649..0033dc70c70 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -280,17 +280,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { debug!("give_region_a_name: error_region = {:?}", error_region); match *error_region { - ty::ReEarlyBound(ebr) => { - if ebr.has_name() { - let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); - Some(RegionName { - name: ebr.name, - source: RegionNameSource::NamedEarlyBoundRegion(span), - }) - } else { - None - } - } + ty::ReEarlyBound(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) } + }), ty::ReStatic => { Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static }) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index f2693bded59..83fdb6066c6 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1297,7 +1297,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let vid = self.to_region_vid(r); let scc = self.constraint_sccs.scc(vid); let repr = self.scc_representatives[scc]; - tcx.mk_region(ty::ReVar(repr)) + tcx.mk_re_var(repr) }) } @@ -1719,7 +1719,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } // If not, report an error. - let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid)); + let member_region = infcx.tcx.mk_re_var(member_region_vid); errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion { span: m_c.definition_span, hidden_ty: m_c.hidden_ty, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index c7b22d5f2e6..bb42301828d 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -91,7 +91,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } None => { subst_regions.push(vid); - infcx.tcx.re_error_with_message( + infcx.tcx.mk_re_error_with_message( concrete_type.span, "opaque type with non-universal region substs", ) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index d5c401ae1c6..a411aec518e 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -50,13 +50,11 @@ pub(super) fn generate<'mir, 'tcx>( compute_relevant_live_locals(typeck.tcx(), &free_regions, &body); let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx()); - let polonius_drop_used = if facts_enabled { + let polonius_drop_used = facts_enabled.then(|| { let mut drop_used = Vec::new(); polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used); - Some(drop_used) - } else { - None - }; + drop_used + }); trace::trace( typeck, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 5b7adae66ac..7a05fde47fc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -137,7 +137,7 @@ pub(crate) fn type_check<'mir, 'tcx>( upvars: &[Upvar<'tcx>], use_polonius: bool, ) -> MirTypeckResults<'tcx> { - let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body)); + let implicit_region_bound = infcx.tcx.mk_re_var(universal_regions.fr_fn_body); let mut constraints = MirTypeckRegionConstraints { placeholder_indices: PlaceholderIndices::default(), placeholder_index_to_region: IndexVec::default(), diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 56930c89b2c..3f254a6b7b6 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -480,10 +480,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { LangItem::VaList, Some(self.infcx.tcx.def_span(self.mir_def.did)), ); - let region = self - .infcx - .tcx - .mk_region(ty::ReVar(self.infcx.next_nll_region_var(FR).to_region_vid())); + let region = + self.infcx.tcx.mk_re_var(self.infcx.next_nll_region_var(FR).to_region_vid()); let va_list_ty = self .infcx .tcx @@ -636,7 +634,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br); let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); // The "inputs" of the closure in the @@ -748,10 +746,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { { let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { debug!(?br); - let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: all_outlive_scope.to_def_id(), - bound_region: br.kind, - })); + let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind); let region_vid = self.next_nll_region_var(origin); indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); debug!(?liberated_region, ?region_vid); @@ -843,7 +838,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { where T: TypeFoldable<'tcx>, { - tcx.fold_regions(value, |region, _| tcx.mk_region(ty::ReVar(self.to_region_vid(region)))) + tcx.fold_regions(value, |region, _| tcx.mk_re_var(self.to_region_vid(region))) } } @@ -883,8 +878,7 @@ fn for_each_late_bound_region_in_item<'tcx>( for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) { let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; - let liberated_region = tcx - .mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region })); + let liberated_region = tcx.mk_re_free(mir_def_id.to_def_id(), bound_region); f(liberated_region); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index e8a353b1c8f..d30e8ba4b93 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -135,19 +135,17 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> } // `let names: &'static _ = &["field1", "field2"];` - let names_let = if is_struct { + let names_let = is_struct.then(|| { let lt_static = Some(cx.lifetime_static(span)); let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not); - Some(cx.stmt_let_ty( + cx.stmt_let_ty( span, false, Ident::new(sym::names, span), Some(ty_static_ref), cx.expr_array_ref(span, name_exprs), - )) - } else { - None - }; + ) + }); // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];` let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug])); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 970b9115d8d..7fc735dbafa 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -942,13 +942,11 @@ impl<'a> MethodDef<'a> { let mut nonself_arg_tys = Vec::new(); let span = trait_.span; - let explicit_self = if self.explicit_self { + let explicit_self = self.explicit_self.then(|| { let (self_expr, explicit_self) = ty::get_explicit_self(cx, span); selflike_args.push(self_expr); - Some(explicit_self) - } else { - None - }; + explicit_self + }); for (ty, name) in self.nonself_args.iter() { let ast_ty = ty.to_ty(cx, span, type_ident, generics); diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index f73f20c84a3..e67c0dba685 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -62,7 +62,7 @@ pub fn inject( // the one with the prelude. let name = names[0]; - let root = (edition == Edition2015).then(|| kw::PathRoot); + let root = (edition == Edition2015).then_some(kw::PathRoot); let import_path = root .iter() diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 58b01dfb5b0..7c6fd9f6f1e 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -248,17 +248,13 @@ fn reuse_workproduct_for_cgu( dwarf_object: None, bytecode: None, }, - module_global_asm: if has_global_asm { - Some(CompiledModule { - name: cgu.name().to_string(), - kind: ModuleKind::Regular, - object: Some(obj_out_global_asm), - dwarf_object: None, - bytecode: None, - }) - } else { - None - }, + module_global_asm: has_global_asm.then(|| CompiledModule { + name: cgu.name().to_string(), + kind: ModuleKind::Regular, + object: Some(obj_out_global_asm), + dwarf_object: None, + bytecode: None, + }), existing_work_product: Some((cgu.work_product_id(), work_product)), }) } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 38f8733763d..fb160669436 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -412,11 +412,7 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> { } fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> { - if config.instrument_coverage { - Some(CString::new("default_%m_%p.profraw").unwrap()) - } else { - None - } + config.instrument_coverage.then(|| CString::new("default_%m_%p.profraw").unwrap()) } pub(crate) unsafe fn llvm_optimize( @@ -451,11 +447,10 @@ pub(crate) unsafe fn llvm_optimize( None }; - let mut llvm_profiler = if cgcx.prof.llvm_recording_enabled() { - Some(LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap())) - } else { - None - }; + let mut llvm_profiler = cgcx + .prof + .llvm_recording_enabled() + .then(|| LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap())); let llvm_selfprofiler = llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut()); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 120dc59dfb3..8848ea3bb9a 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -402,12 +402,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod()); - let coverage_cx = if tcx.sess.instrument_coverage() { - let covctx = coverageinfo::CrateCoverageContext::new(); - Some(covctx) - } else { - None - }; + let coverage_cx = + tcx.sess.instrument_coverage().then(coverageinfo::CrateCoverageContext::new); let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None { let dctx = debuginfo::CodegenUnitDebugContext::new(llmod); diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 0cb4bc806a1..cc8ff947fc3 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -154,7 +154,7 @@ fn struct_llfields<'a, 'tcx>( } else { debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size); } - let field_remapping = if padding_used { Some(field_remapping) } else { None }; + let field_remapping = padding_used.then_some(field_remapping); (result, packed, field_remapping) } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6fe8527ada6..8aa744ce935 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2024,7 +2024,7 @@ fn linker_with_args<'a>( .native_libraries .iter() .filter_map(|(cnum, libraries)| { - (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries) + (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then_some(libraries) }) .flatten(); for (raw_dylib_name, raw_dylib_imports) in diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 6e136db3895..023d38e9312 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -579,7 +579,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>( } } - let metadata_module = if need_metadata_module { + let metadata_module = need_metadata_module.then(|| { // Emit compressed metadata object. let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string(); @@ -594,17 +594,15 @@ pub fn codegen_crate<B: ExtraBackendMethods>( if let Err(error) = std::fs::write(&file_name, data) { tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error }); } - Some(CompiledModule { + CompiledModule { name: metadata_cgu_name, kind: ModuleKind::Metadata, object: Some(file_name), dwarf_object: None, bytecode: None, - }) + } }) - } else { - None - }; + }); let ongoing_codegen = start_async_codegen( backend.clone(), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index de1734332d4..eec91ffa44a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -167,8 +167,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( start_bx.set_personality_fn(cx.eh_personality()); } - let cleanup_kinds = - if base::wants_msvc_seh(cx.tcx().sess) { Some(analyze::cleanup_kinds(&mir)) } else { None }; + let cleanup_kinds = base::wants_msvc_seh(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir)); let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> = mir.basic_blocks diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a6afbad5b24..0432a9c5a12 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -286,6 +286,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[ ("mutable-globals", Some(sym::wasm_target_feature)), ("nontrapping-fptoint", Some(sym::wasm_target_feature)), ("reference-types", Some(sym::wasm_target_feature)), + ("relaxed-simd", Some(sym::wasm_target_feature)), ("sign-ext", Some(sym::wasm_target_feature)), ("simd128", None), // tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 3aca03f6e5c..44331683694 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -207,8 +207,7 @@ impl SelfProfilerRef { /// a measureme event, "verbose" generic activities also print a timing entry to /// stderr if the compiler is invoked with -Ztime-passes. pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> { - let message = - if self.print_verbose_generic_activities { Some(event_label.to_owned()) } else { None }; + let message = self.print_verbose_generic_activities.then(|| event_label.to_owned()); VerboseTimingGuard::start(message, self.generic_activity(event_label)) } @@ -222,11 +221,9 @@ impl SelfProfilerRef { where A: Borrow<str> + Into<String>, { - let message = if self.print_verbose_generic_activities { - Some(format!("{}({})", event_label, event_arg.borrow())) - } else { - None - }; + let message = self + .print_verbose_generic_activities + .then(|| format!("{}({})", event_label, event_arg.borrow())); VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg)) } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 4f2cc8b0351..211bbf4f50e 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1768,7 +1768,7 @@ impl EmitterWriter { // Render the replacements for each suggestion let suggestions = suggestion.splice_lines(sm); - debug!("emit_suggestion_default: suggestions={:?}", suggestions); + debug!(?suggestions); if suggestions.is_empty() { // Suggestions coming from macros can have malformed spans. This is a heavy handed @@ -1797,6 +1797,7 @@ impl EmitterWriter { for (complete, parts, highlights, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) { + debug!(?complete, ?parts, ?highlights); notice_capitalization |= only_capitalization; let has_deletion = parts.iter().any(|p| p.is_deletion(sm)); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 83b733d4c06..4b3c0c055ad 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1066,29 +1066,26 @@ impl Handler { } pub fn has_errors(&self) -> Option<ErrorGuaranteed> { - if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None } + self.inner.borrow().has_errors().then(ErrorGuaranteed::unchecked_claim_error_was_emitted) } pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> { - if self.inner.borrow().has_errors_or_lint_errors() { - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) - } else { - None - } + self.inner + .borrow() + .has_errors_or_lint_errors() + .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) } pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { - if self.inner.borrow().has_errors_or_delayed_span_bugs() { - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) - } else { - None - } + self.inner + .borrow() + .has_errors_or_delayed_span_bugs() + .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) } pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> { - if self.inner.borrow().is_compilation_going_to_fail() { - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) - } else { - None - } + self.inner + .borrow() + .is_compilation_going_to_fail() + .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) } pub fn print_error_count(&self, registry: &Registry) { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 1fcbdfd9be5..5c845ae6d0b 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -238,12 +238,10 @@ macro_rules! configure { impl<'a> StripUnconfigured<'a> { pub fn configure<T: HasAttrs + HasTokens>(&self, mut node: T) -> Option<T> { self.process_cfg_attrs(&mut node); - if self.in_cfg(node.attrs()) { + self.in_cfg(node.attrs()).then(|| { self.try_configure_tokens(&mut node); - Some(node) - } else { - None - } + node + }) } fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) { @@ -257,7 +255,7 @@ impl<'a> StripUnconfigured<'a> { fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> { attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); - if self.in_cfg(&attrs) { Some(attrs) } else { None } + self.in_cfg(&attrs).then_some(attrs) } /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 21d211eefbe..7122ccdcd2e 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -164,8 +164,6 @@ declare_features! ( (active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None), /// Allows using `#[omit_gdb_pretty_printer_section]`. (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), - /// Allows using `+bundled,+whole-archive` native libs. - (active, packed_bundled_libs, "1.67.0", None, None), /// Allows using `#[prelude_import]` on glob `use` items. (active, prelude_import, "1.2.0", None, None), /// Used to identify crates that contain the profiler runtime. @@ -217,6 +215,8 @@ declare_features! ( (active, linkage, "1.0.0", Some(29603), None), /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. (active, needs_panic_runtime, "1.10.0", Some(32837), None), + /// Allows using `+bundled,+whole-archive` native libs. + (active, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None), /// Allows using the `#![panic_runtime]` attribute. (active, panic_runtime, "1.10.0", Some(32837), None), /// Allows using `#[rustc_allow_const_fn_unstable]`. @@ -473,6 +473,8 @@ declare_features! ( (active, no_sanitize, "1.42.0", Some(39699), None), /// Allows using the `non_exhaustive_omitted_patterns` lint. (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None), + /// Allows `for<T>` binders in where-clauses + (incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(1), None), /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe. /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7cb3b6e1525..80ec1caf521 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -574,14 +574,11 @@ impl<'hir> Generics<'hir> { /// If there are generic parameters, return where to introduce a new one. pub fn span_for_param_suggestion(&self) -> Option<Span> { - if self.params.iter().any(|p| self.span.contains(p.span)) { + self.params.iter().any(|p| self.span.contains(p.span)).then(|| { // `fn foo<A>(t: impl Trait)` // ^ suggest `, T: Trait` here - let span = self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo(); - Some(span) - } else { - None - } + self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo() + }) } /// `Span` where further predicates would be suggested, accounting for trailing commas, like @@ -639,7 +636,7 @@ impl<'hir> Generics<'hir> { // We include bounds that come from a `#[derive(_)]` but point at the user's code, // as we use this method to get a span appropriate for suggestions. let bs = bound.span(); - if bs.can_be_used_for_suggestions() { Some(bs.shrink_to_hi()) } else { None } + bs.can_be_used_for_suggestions().then(|| bs.shrink_to_hi()) }, ) } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 46dc4141e66..221721f5909 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -14,7 +14,7 @@ use crate::errors::{ AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits, TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified, }; -use crate::middle::resolve_lifetime as rl; +use crate::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -225,32 +225,29 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id)); - match tcx.named_region(lifetime.hir_id) { - Some(rl::Region::Static) => tcx.lifetimes.re_static, + match tcx.named_bound_var(lifetime.hir_id) { + Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static, - Some(rl::Region::LateBound(debruijn, index, def_id)) => { + Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => { let name = lifetime_name(def_id.expect_local()); let br = ty::BoundRegion { var: ty::BoundVar::from_u32(index), kind: ty::BrNamed(def_id, name), }; - tcx.mk_region(ty::ReLateBound(debruijn, br)) + tcx.mk_re_late_bound(debruijn, br) } - Some(rl::Region::EarlyBound(def_id)) => { + Some(rbv::ResolvedArg::EarlyBound(def_id)) => { let name = tcx.hir().ty_param_name(def_id.expect_local()); 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]; - tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name })) + tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id, index, name }) } - Some(rl::Region::Free(scope, id)) => { + Some(rbv::ResolvedArg::Free(scope, id)) => { let name = lifetime_name(id.expect_local()); - tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope, - bound_region: ty::BrNamed(id, name), - })) + tcx.mk_re_free(scope, ty::BrNamed(id, name)) // (*) -- not late-bound, won't change } @@ -263,7 +260,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // elision. `resolve_lifetime` should have // reported an error in this case -- but if // not, let's error out. - tcx.re_error_with_message(lifetime.ident.span, "unelided lifetime in signature") + tcx.mk_re_error_with_message( + lifetime.ident.span, + "unelided lifetime in signature", + ) }) } } @@ -477,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?param, "unelided lifetime in signature"); // This indicates an illegal lifetime in a non-assoc-trait position - tcx.re_error_with_message(self.span, "unelided lifetime in signature") + tcx.mk_re_error_with_message( + self.span, + "unelided lifetime in signature", + ) }) .into(), GenericParamDefKind::Type { has_default, .. } => { @@ -1604,7 +1607,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ast_region_to_region(lifetime, None) } else { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { - if tcx.named_region(lifetime.hir_id).is_some() { + if tcx.named_bound_var(lifetime.hir_id).is_some() { self.ast_region_to_region(lifetime, None) } else { self.re_infer(None, span).unwrap_or_else(|| { @@ -1622,7 +1625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.emit() }; - tcx.re_error(e) + tcx.mk_re_error(e) }) } }) @@ -2597,6 +2600,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, opt_self_ty: Option<Ty<'tcx>>, path: &hir::Path<'_>, + hir_id: hir::HirId, permit_variants: bool, ) -> Ty<'tcx> { let tcx = self.tcx(); @@ -2660,11 +2664,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } }); - let def_id = def_id.expect_local(); - let item_def_id = tcx.hir().ty_param_owner(def_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) + match tcx.named_bound_var(hir_id) { + Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => { + let name = + tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local())); + let br = ty::BoundTy { + var: ty::BoundVar::from_u32(index), + kind: ty::BoundTyKind::Param(def_id, name), + }; + tcx.mk_ty(ty::Bound(debruijn, br)) + } + Some(rbv::ResolvedArg::EarlyBound(_)) => { + let def_id = def_id.expect_local(); + let item_def_id = tcx.hir().ty_param_owner(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id.to_def_id()]; + tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) + } + arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), + } } Res::SelfTyParam { .. } => { // `Self` in trait or type alias. @@ -2867,14 +2885,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TyKind::BareFn(bf) => { require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span); - tcx.mk_fn_ptr(self.ty_of_fn( + let fn_ptr_ty = tcx.mk_fn_ptr(self.ty_of_fn( ast_ty.hir_id, bf.unsafety, bf.abi, bf.decl, None, Some(ast_ty), - )) + )); + + if let Some(guar) = + deny_non_region_late_bound(tcx, bf.generic_params, "function pointer") + { + tcx.ty_error_with_guaranteed(guar) + } else { + fn_ptr_ty + } } hir::TyKind::TraitObject(bounds, lifetime, repr) => { self.maybe_lint_bare_trait(ast_ty, in_path); @@ -2882,12 +2908,27 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn, TraitObjectSyntax::DynStar => ty::DynStar, }; - self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr) + + let object_ty = self.conv_object_ty_poly_trait_ref( + ast_ty.span, + bounds, + lifetime, + borrowed, + repr, + ); + + if let Some(guar) = bounds.iter().find_map(|trait_ref| { + deny_non_region_late_bound(tcx, trait_ref.bound_generic_params, "trait object") + }) { + tcx.ty_error_with_guaranteed(guar) + } else { + object_ty + } } hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself)); - self.res_to_ty(opt_self_ty, path, false) + self.res_to_ty(opt_self_ty, path, ast_ty.hir_id, false) } &hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => { let opaque_ty = tcx.hir().item(item_id); @@ -3343,3 +3384,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } + +fn deny_non_region_late_bound( + tcx: TyCtxt<'_>, + params: &[hir::GenericParam<'_>], + where_: &str, +) -> Option<ErrorGuaranteed> { + params.iter().find_map(|bad_param| { + let what = match bad_param.kind { + hir::GenericParamKind::Type { .. } => "type", + hir::GenericParamKind::Const { .. } => "const", + hir::GenericParamKind::Lifetime { .. } => return None, + }; + + let mut diag = tcx.sess.struct_span_err( + bad_param.span, + format!("late-bound {what} parameter not allowed on {where_} types"), + ); + + Some(if tcx.features().non_lifetime_binders { diag.emit() } else { diag.delay_as_bug() }) + }) +} 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 6b0eade2d32..94e1fcebccd 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -464,14 +464,10 @@ 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 { - self.tcx.mk_region(ty::ReFree(ty::FreeRegion { - bound_region: self - .mapping - .get(&fr.bound_region) - .copied() - .unwrap_or(fr.bound_region), - ..fr - })) + self.tcx.mk_re_free( + fr.scope, + self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region), + ) } else { r } @@ -777,13 +773,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( } let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind()) else { - return tcx.re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound") + return tcx.mk_re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound") }; - tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { + tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id: e.def_id, name: e.name, index: (e.index as usize - num_trait_substs + num_impl_substs) as u32, - })) + }) }); debug!(%ty); collected_tys.insert(def_id, ty); @@ -1920,10 +1916,10 @@ pub(super) fn check_type_bounds<'tcx>( let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); let bound_var = ty::BoundVariableKind::Region(kind); bound_vars.push(bound_var); - tcx.mk_region(ty::ReLateBound( + tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, - )) + ) .into() } GenericParamDefKind::Const { .. } => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 955cacf03b1..4fc37856dfc 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -149,14 +149,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ); let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { - let region = tcx.mk_region(ty::ReLateBound( + let region = tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }, - )); - let env_region = tcx.mk_region(ty::ReLateBound( + ); + let env_region = tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv }, - )); + ); let va_list_ty = tcx.bound_type_of(did).subst(tcx, &[region.into()]); (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) @@ -377,9 +377,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }; ( 1, - vec![ - tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)), - ], + vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))], tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())), ) } @@ -430,8 +428,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::raw_eq => { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }; - let param_ty = - tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)); + let param_ty = tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0)); (1, vec![param_ty; 2], tcx.types.bool) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c64d507f828..ee39fde1dcb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -607,12 +607,11 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'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 = - tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion { - def_id: region_param.def_id, - index: region_param.index, - name: region_param.name, - })); + let region_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion { + def_id: region_param.def_id, + index: region_param.index, + name: region_param.name, + }); // The predicate we expect to see. (In our example, // `Self: 'me`.) let clause = ty::PredicateKind::Clause(ty::Clause::TypeOutlives( @@ -645,20 +644,18 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'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 = - tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion { - def_id: region_a_param.def_id, - index: region_a_param.index, - name: region_a_param.name, - })); + let region_a_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion { + def_id: region_a_param.def_id, + index: region_a_param.index, + name: region_a_param.name, + }); // Same for the region. let region_b_param = gat_generics.param_at(*region_b_idx, tcx); - let region_b_param = - tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion { - def_id: region_b_param.def_id, - index: region_b_param.index, - name: region_b_param.name, - })); + let region_b_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion { + def_id: region_b_param.def_id, + index: region_b_param.index, + name: region_b_param.name, + }); // The predicate we expect to see. let clause = ty::PredicateKind::Clause(ty::Clause::RegionOutlives( ty::OutlivesPredicate(region_a_param, region_b_param), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9f33d84ab52..8ebe576a224 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -41,8 +41,8 @@ use std::iter; mod generics_of; mod item_bounds; -mod lifetimes; mod predicates_of; +mod resolve_bound_vars; mod type_of; /////////////////////////////////////////////////////////////////////////// @@ -53,7 +53,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { } pub fn provide(providers: &mut Providers) { - lifetimes::provide(providers); + resolve_bound_vars::provide(providers); *providers = Providers { opt_const_param_of: type_of::opt_const_param_of, type_of: type_of::type_of, @@ -458,13 +458,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { self.tcx.replace_late_bound_regions_uncached( poly_trait_ref, |_| { - self.tcx.mk_region(ty::ReEarlyBound( - ty::EarlyBoundRegion { - def_id: item_def_id, - index: 0, - name: Symbol::intern(<_name), - }, - )) + self.tcx.mk_re_early_bound(ty::EarlyBoundRegion { + def_id: item_def_id, + index: 0, + name: Symbol::intern(<_name), + }) } ), ), diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 014ee9fcc20..7bcaeadbcf6 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -1,4 +1,4 @@ -use crate::middle::resolve_lifetime as rl; +use crate::middle::resolve_bound_vars as rbv; use hir::{ intravisit::{self, Visitor}, GenericParamKind, HirId, Node, @@ -394,10 +394,11 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S return; } - match self.tcx.named_region(lt.hir_id) { - Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {} - Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {} - Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => { + match self.tcx.named_bound_var(lt.hir_id) { + Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {} + Some(rbv::ResolvedArg::LateBound(debruijn, _, _)) + if debruijn < self.outer_index => {} + Some(rbv::ResolvedArg::LateBound(..) | rbv::ResolvedArg::Free(..)) | None => { self.has_late_bound_regions = Some(lt.ident.span); } } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d0d67ae9257..5ac9003556d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -284,11 +284,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() }; - let dup_region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { + let dup_region = tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id: dup_def, index: dup_index, name: duplicate.name.ident().name, - })); + }); predicates.push(( ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives( ty::OutlivesPredicate(orig_region, dup_region), diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d8606f759b2..8c388040fbf 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -16,7 +16,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::resolve_lifetime::*; +use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; @@ -24,59 +24,61 @@ use rustc_span::Span; use std::fmt; trait RegionExt { - fn early(param: &GenericParam<'_>) -> (LocalDefId, Region); + fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg); - fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, Region); + fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg); fn id(&self) -> Option<DefId>; - fn shifted(self, amount: u32) -> Region; + fn shifted(self, amount: u32) -> ResolvedArg; } -impl RegionExt for Region { - fn early(param: &GenericParam<'_>) -> (LocalDefId, Region) { - debug!("Region::early: def_id={:?}", param.def_id); - (param.def_id, Region::EarlyBound(param.def_id.to_def_id())) +impl RegionExt for ResolvedArg { + fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) { + debug!("ResolvedArg::early: def_id={:?}", param.def_id); + (param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id())) } - fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, Region) { + fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) { let depth = ty::INNERMOST; debug!( - "Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}", + "ResolvedArg::late: idx={:?}, param={:?} depth={:?} def_id={:?}", idx, param, depth, param.def_id, ); - (param.def_id, Region::LateBound(depth, idx, param.def_id.to_def_id())) + (param.def_id, ResolvedArg::LateBound(depth, idx, param.def_id.to_def_id())) } fn id(&self) -> Option<DefId> { match *self { - Region::Static => None, + ResolvedArg::StaticLifetime => None, - Region::EarlyBound(id) | Region::LateBound(_, _, id) | Region::Free(_, id) => Some(id), + ResolvedArg::EarlyBound(id) + | ResolvedArg::LateBound(_, _, id) + | ResolvedArg::Free(_, id) => Some(id), } } - fn shifted(self, amount: u32) -> Region { + fn shifted(self, amount: u32) -> ResolvedArg { match self { - Region::LateBound(debruijn, idx, id) => { - Region::LateBound(debruijn.shifted_in(amount), idx, id) + ResolvedArg::LateBound(debruijn, idx, id) => { + ResolvedArg::LateBound(debruijn.shifted_in(amount), idx, id) } _ => self, } } } -/// Maps the id of each lifetime reference to the lifetime decl +/// Maps the id of each bound variable reference to the variable decl /// that it corresponds to. /// -/// FIXME. This struct gets converted to a `ResolveLifetimes` for +/// FIXME. This struct gets converted to a `ResolveBoundVars` for /// actual use. It has the same data, but indexed by `LocalDefId`. This /// is silly. #[derive(Debug, Default)] -struct NamedRegionMap { - // maps from every use of a named (not anonymous) lifetime to a - // `Region` describing how that region is bound - defs: HirIdMap<Region>, +struct NamedVarMap { + // maps from every use of a named (not anonymous) bound var to a + // `ResolvedArg` describing how that variable is bound + defs: HirIdMap<ResolvedArg>, // Maps relevant hir items to the bound vars on them. These include: // - function defs @@ -87,9 +89,9 @@ struct NamedRegionMap { late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>, } -struct LifetimeContext<'a, 'tcx> { +struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, - map: &'a mut NamedRegionMap, + map: &'a mut NamedVarMap, scope: ScopeRef<'a>, } @@ -102,7 +104,7 @@ enum Scope<'a> { Binder { /// We use an IndexMap here because we want these lifetimes in order /// for diagnostics. - lifetimes: FxIndexMap<LocalDefId, Region>, + bound_vars: FxIndexMap<LocalDefId, ResolvedArg>, scope_type: BinderScopeType, @@ -141,7 +143,7 @@ enum Scope<'a> { /// inferred in a function body or potentially error outside one), /// for the default choice of lifetime in a trait object type. ObjectLifetimeDefault { - lifetime: Option<Region>, + lifetime: Option<ResolvedArg>, s: ScopeRef<'a>, }, @@ -150,7 +152,7 @@ enum Scope<'a> { /// lifetimes encountered when identifying the trait that an associated type /// is declared on. Supertrait { - lifetimes: Vec<ty::BoundVariableKind>, + bound_vars: Vec<ty::BoundVariableKind>, s: ScopeRef<'a>, }, @@ -185,9 +187,9 @@ struct TruncatedScopeDebug<'a>(&'a Scope<'a>); impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.0 { - Scope::Binder { lifetimes, scope_type, hir_id, where_bound_origin, s: _ } => f + Scope::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f .debug_struct("Binder") - .field("lifetimes", lifetimes) + .field("bound_vars", bound_vars) .field("scope_type", scope_type) .field("hir_id", hir_id) .field("where_bound_origin", where_bound_origin) @@ -202,9 +204,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("lifetime", lifetime) .field("s", &"..") .finish(), - Scope::Supertrait { lifetimes, s: _ } => f + Scope::Supertrait { bound_vars, s: _ } => f .debug_struct("Supertrait") - .field("lifetimes", lifetimes) + .field("bound_vars", bound_vars) .field("s", &"..") .finish(), Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(), @@ -219,27 +221,27 @@ type ScopeRef<'a> = &'a Scope<'a>; pub(crate) fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { - resolve_lifetimes, + resolve_bound_vars, - named_region_map: |tcx, id| tcx.resolve_lifetimes(id).defs.get(&id), + named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id), is_late_bound_map, object_lifetime_default, - late_bound_vars_map: |tcx, id| tcx.resolve_lifetimes(id).late_bound_vars.get(&id), + late_bound_vars_map: |tcx, id| tcx.resolve_bound_vars(id).late_bound_vars.get(&id), ..*providers }; } -/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`. +/// Computes the `ResolveBoundVars` map that contains data for an entire `Item`. /// You should not read the result of this query directly, but rather use -/// `named_region_map`, `is_late_bound_map`, etc. +/// `named_variable_map`, `is_late_bound_map`, etc. #[instrument(level = "debug", skip(tcx))] -fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLifetimes { - let mut named_region_map = - NamedRegionMap { defs: Default::default(), late_bound_vars: Default::default() }; - let mut visitor = LifetimeContext { +fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars { + let mut named_variable_map = + NamedVarMap { defs: Default::default(), late_bound_vars: Default::default() }; + let mut visitor = BoundVarContext { tcx, - map: &mut named_region_map, + map: &mut named_variable_map, scope: &Scope::Root { opt_parent_item: None }, }; match tcx.hir().owner(local_def_id) { @@ -260,13 +262,13 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLife hir::OwnerNode::Crate(_) => {} } - let mut rl = ResolveLifetimes::default(); + let mut rl = ResolveBoundVars::default(); - for (hir_id, v) in named_region_map.defs { + for (hir_id, v) in named_variable_map.defs { let map = rl.defs.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); } - for (hir_id, v) in named_region_map.late_bound_vars { + for (hir_id, v) in named_variable_map.late_bound_vars { let map = rl.late_bound_vars.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); } @@ -276,21 +278,33 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLife rl } -fn late_region_as_bound_region(tcx: TyCtxt<'_>, region: &Region) -> ty::BoundVariableKind { - match region { - Region::LateBound(_, _, def_id) => { +fn late_arg_as_bound_arg<'tcx>( + tcx: TyCtxt<'tcx>, + arg: &ResolvedArg, + param: &GenericParam<'tcx>, +) -> ty::BoundVariableKind { + match arg { + ResolvedArg::LateBound(_, _, def_id) => { let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local())); - ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name)) + match param.kind { + GenericParamKind::Lifetime { .. } => { + ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name)) + } + GenericParamKind::Type { .. } => { + ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(*def_id, name)) + } + GenericParamKind::Const { .. } => ty::BoundVariableKind::Const, + } } - _ => bug!("{:?} is not a late region", region), + _ => bug!("{:?} is not a late argument", arg), } } -impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { +impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { /// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref. fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) { let mut scope = self.scope; - let mut supertrait_lifetimes = vec![]; + let mut supertrait_bound_vars = vec![]; loop { match scope { Scope::Body { .. } | Scope::Root { .. } => { @@ -301,14 +315,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Supertrait { s, lifetimes } => { - supertrait_lifetimes = lifetimes.clone(); + Scope::Supertrait { s, bound_vars } => { + supertrait_bound_vars = bound_vars.clone(); scope = s; } Scope::TraitRefBoundary { .. } => { // We should only see super trait lifetimes if there is a `Binder` above - assert!(supertrait_lifetimes.is_empty()); + assert!(supertrait_bound_vars.is_empty()); break (vec![], BinderScopeType::Normal); } @@ -316,14 +330,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // Nested poly trait refs have the binders concatenated let mut full_binders = self.map.late_bound_vars.entry(*hir_id).or_default().clone(); - full_binders.extend(supertrait_lifetimes.into_iter()); + full_binders.extend(supertrait_bound_vars.into_iter()); break (full_binders, BinderScopeType::Concatenating); } } } } } -impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Self::Map { @@ -386,14 +400,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } - let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = + let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = bound_generic_params .iter() - .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) .enumerate() .map(|(late_bound_idx, param)| { - let pair = Region::late(late_bound_idx as u32, param); - let r = late_region_as_bound_region(self.tcx, &pair.1); + let pair = ResolvedArg::late(late_bound_idx as u32, param); + let r = late_arg_as_bound_arg(self.tcx, &pair.1, param); (pair, r) }) .unzip(); @@ -401,7 +414,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.record_late_bound_vars(e.hir_id, binders); let scope = Scope::Binder { hir_id: e.hir_id, - lifetimes, + bound_vars, s: self.scope, scope_type: BinderScopeType::Normal, where_bound_origin: None, @@ -461,7 +474,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // conservatively add all resolved lifetimes. Otherwise we run into problems in // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`. let parent_item = self.tcx.hir().get_parent_item(item.hir_id()); - let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(parent_item); + let resolved_lifetimes: &ResolveBoundVars = + self.tcx.resolve_bound_vars(parent_item); // We need to add *all* deps, since opaque tys may want them from *us* for (&owner, defs) in resolved_lifetimes.defs.iter() { defs.iter().for_each(|(&local_id, region)| { @@ -478,35 +492,33 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_), + origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent), generics, .. }) => { // We want to start our early-bound indices at the end of the parent scope, // not including any parent `impl Trait`s. - let mut lifetimes = FxIndexMap::default(); + let mut bound_vars = FxIndexMap::default(); debug!(?generics.params); for param in generics.params { - match param.kind { - GenericParamKind::Lifetime { .. } => { - let (def_id, reg) = Region::early(¶m); - lifetimes.insert(def_id, reg); - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {} - } + let (def_id, reg) = ResolvedArg::early(¶m); + bound_vars.insert(def_id, reg); } - let scope = Scope::Binder { - hir_id: item.hir_id(), - lifetimes, - s: self.scope, - scope_type: BinderScopeType::Normal, - where_bound_origin: None, - }; + let scope = Scope::Root { opt_parent_item: Some(parent) }; self.with(scope, |this| { - let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |this| intravisit::walk_item(this, item)) - }); + let scope = Scope::Binder { + hir_id: item.hir_id(), + bound_vars, + s: this.scope, + scope_type: BinderScopeType::Normal, + where_bound_origin: None, + }; + this.with(scope, |this| { + let scope = Scope::TraitRefBoundary { s: this.scope }; + this.with(scope, |this| intravisit::walk_item(this, item)) + }); + }) } hir::ItemKind::TyAlias(_, generics) | hir::ItemKind::Enum(_, generics) @@ -516,18 +528,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::TraitAlias(generics, ..) | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => { // These kinds of items have only early-bound lifetime parameters. - let lifetimes = generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => Some(Region::early(param)), - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, - }) - .collect(); + let bound_vars = generics.params.iter().map(ResolvedArg::early).collect(); self.record_late_bound_vars(item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: item.hir_id(), - lifetimes, + bound_vars, scope_type: BinderScopeType::Normal, s: self.scope, where_bound_origin: None, @@ -562,21 +567,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { match ty.kind { hir::TyKind::BareFn(c) => { - let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c + let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c .generic_params .iter() - .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) .enumerate() .map(|(late_bound_idx, param)| { - let pair = Region::late(late_bound_idx as u32, param); - let r = late_region_as_bound_region(self.tcx, &pair.1); + let pair = ResolvedArg::late(late_bound_idx as u32, param); + let r = late_arg_as_bound_arg(self.tcx, &pair.1, param); (pair, r) }) .unzip(); self.record_late_bound_vars(ty.hir_id, binders); let scope = Scope::Binder { hir_id: ty.hir_id, - lifetimes, + bound_vars, s: self.scope, scope_type: BinderScopeType::Normal, where_bound_origin: None, @@ -674,7 +678,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // well-supported at the moment, so this doesn't work. // In the future, this should be fixed and this error should be removed. let def = self.map.defs.get(&lifetime.hir_id).cloned(); - let Some(Region::LateBound(_, _, def_id)) = def else { + let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue }; let Some(def_id) = def_id.as_local() else { @@ -722,18 +726,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } Type(bounds, ty) => { let generics = &trait_item.generics; - let lifetimes = generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => Some(Region::early(param)), - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, - }) - .collect(); + let bound_vars = generics.params.iter().map(ResolvedArg::early).collect(); self.record_late_bound_vars(trait_item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: trait_item.hir_id(), - lifetimes, + bound_vars, s: self.scope, scope_type: BinderScopeType::Normal, where_bound_origin: None, @@ -768,18 +765,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }), Type(ty) => { let generics = &impl_item.generics; - let lifetimes: FxIndexMap<LocalDefId, Region> = generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => Some(Region::early(param)), - GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None, - }) - .collect(); + let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = + generics.params.iter().map(ResolvedArg::early).collect(); self.record_late_bound_vars(impl_item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: impl_item.hir_id(), - lifetimes, + bound_vars, s: self.scope, scope_type: BinderScopeType::Normal, where_bound_origin: None, @@ -803,7 +794,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { match lifetime_ref.res { - hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), + hir::LifetimeName::Static => { + self.insert_lifetime(lifetime_ref, ResolvedArg::StaticLifetime) + } hir::LifetimeName::Param(param_def_id) => { self.resolve_lifetime_ref(param_def_id, lifetime_ref) } @@ -814,13 +807,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } - fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: hir::HirId) { for (i, segment) in path.segments.iter().enumerate() { let depth = path.segments.len() - i - 1; if let Some(args) = segment.args { self.visit_segment_args(path.res, depth, args); } } + if let Res::Def(DefKind::TyParam | DefKind::ConstParam, param_def_id) = path.res { + self.resolve_type_ref(param_def_id.expect_local(), hir_id); + } } fn visit_fn( @@ -869,24 +865,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { origin, .. }) => { - let lifetimes: FxIndexMap<LocalDefId, Region> = + + let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = bound_generic_params - .iter() - .filter(|param| { - matches!(param.kind, GenericParamKind::Lifetime { .. }) - }) - .enumerate() - .map(|(late_bound_idx, param)| { - Region::late(late_bound_idx as u32, param) - }) - .collect(); - let binders: Vec<_> = - lifetimes - .iter() - .map(|(_, region)| { - late_region_as_bound_region(this.tcx, region) - }) - .collect(); + .iter() + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = ResolvedArg::late(late_bound_idx as u32, param); + let r = late_arg_as_bound_arg(this.tcx, &pair.1, param); + (pair, r) + }) + .unzip(); this.record_late_bound_vars(hir_id, binders.clone()); // Even if there are no lifetimes defined here, we still wrap it in a binder // scope. If there happens to be a nested poly trait ref (an error), that @@ -894,7 +883,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // being wrong. let scope = Scope::Binder { hir_id, - lifetimes, + bound_vars, s: this.scope, scope_type: BinderScopeType::Normal, where_bound_origin: Some(origin), @@ -920,7 +909,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { if lt.res != hir::LifetimeName::Static { continue; } - this.insert_lifetime(lt, Region::Static); + this.insert_lifetime(lt, ResolvedArg::StaticLifetime); this.tcx .sess .struct_span_warn( @@ -964,7 +953,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.record_late_bound_vars(*hir_id, binders); let scope = Scope::Binder { hir_id: *hir_id, - lifetimes: FxIndexMap::default(), + bound_vars: FxIndexMap::default(), s: self.scope, scope_type, where_bound_origin: None, @@ -983,16 +972,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); let initial_bound_vars = binders.len() as u32; - let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default(); - let binders_iter = trait_ref - .bound_generic_params - .iter() - .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) - .enumerate() - .map(|(late_bound_idx, param)| { - let pair = Region::late(initial_bound_vars + late_bound_idx as u32, param); - let r = late_region_as_bound_region(self.tcx, &pair.1); - lifetimes.insert(pair.0, pair.1); + let mut bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = FxIndexMap::default(); + let binders_iter = + trait_ref.bound_generic_params.iter().enumerate().map(|(late_bound_idx, param)| { + let pair = ResolvedArg::late(initial_bound_vars + late_bound_idx as u32, param); + let r = late_arg_as_bound_arg(self.tcx, &pair.1, param); + bound_vars.insert(pair.0, pair.1); r }); binders.extend(binders_iter); @@ -1006,7 +991,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // refs. let scope = Scope::Binder { hir_id: trait_ref.trait_ref.hir_ref_id, - lifetimes, + bound_vars, s: self.scope, scope_type, where_bound_origin: None, @@ -1063,13 +1048,13 @@ fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: DefId) -> ObjectLifeti } } -impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { +impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F) where - F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>), + F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let LifetimeContext { tcx, map, .. } = self; - let mut this = LifetimeContext { tcx: *tcx, map, scope: &wrap_scope }; + let BoundVarContext { tcx, map, .. } = self; + let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope)); { let _enter = span.enter(); @@ -1110,23 +1095,25 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { generics: &'tcx hir::Generics<'tcx>, walk: F, ) where - F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), + F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>), { let mut named_late_bound_vars = 0; - let lifetimes: FxIndexMap<LocalDefId, Region> = generics + let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = generics .params .iter() - .filter_map(|param| match param.kind { + .map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { if self.tcx.is_late_bound(param.hir_id) { let late_bound_idx = named_late_bound_vars; named_late_bound_vars += 1; - Some(Region::late(late_bound_idx, param)) + ResolvedArg::late(late_bound_idx, param) } else { - Some(Region::early(param)) + ResolvedArg::early(param) } } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { + ResolvedArg::early(param) + } }) .collect(); @@ -1139,14 +1126,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }) .enumerate() .map(|(late_bound_idx, param)| { - let pair = Region::late(late_bound_idx as u32, param); - late_region_as_bound_region(self.tcx, &pair.1) + let pair = ResolvedArg::late(late_bound_idx as u32, param); + late_arg_as_bound_arg(self.tcx, &pair.1, param) }) .collect(); self.record_late_bound_vars(hir_id, binders); let scope = Scope::Binder { hir_id, - lifetimes, + bound_vars, s: self.scope, scope_type: BinderScopeType::Normal, where_bound_origin: None, @@ -1177,15 +1164,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root { opt_parent_item } => { if let Some(parent_item) = opt_parent_item && let parent_generics = self.tcx.generics_of(parent_item) - && parent_generics.param_def_id_to_index.contains_key(®ion_def_id.to_def_id()) + && parent_generics.param_def_id_to_index(self.tcx, region_def_id.to_def_id()).is_some() { - break Some(Region::EarlyBound(region_def_id.to_def_id())); + break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id())); } break None; } - Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => { - if let Some(&def) = lifetimes.get(®ion_def_id) { + Scope::Binder { ref bound_vars, scope_type, s, where_bound_origin, .. } => { + if let Some(&def) = bound_vars.get(®ion_def_id) { break Some(def.shifted(late_depth)); } match scope_type { @@ -1259,7 +1246,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; if let Some(mut def) = result { - if let Region::EarlyBound(..) = def { + if let ResolvedArg::EarlyBound(..) = def { // Do not free early-bound regions, only late-bound ones. } else if let Some(body_id) = outermost_body { let fn_id = self.tcx.hir().body_owner(body_id); @@ -1275,10 +1262,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { kind: hir::ImplItemKind::Fn(..), .. }) => { - def = Region::Free(owner_id.to_def_id(), def.id().unwrap()); + def = ResolvedArg::Free(owner_id.to_def_id(), def.id().unwrap()); } Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) => { - def = Region::Free(closure.def_id.to_def_id(), def.id().unwrap()); + def = ResolvedArg::Free(closure.def_id.to_def_id(), def.id().unwrap()); } _ => {} } @@ -1329,6 +1316,57 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ); } + fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: hir::HirId) { + // Walk up the scope chain, tracking the number of fn scopes + // that we pass through, until we find a lifetime with the + // given name or we run out of scopes. + // search. + let mut late_depth = 0; + let mut scope = self.scope; + let result = loop { + match *scope { + Scope::Body { s, .. } => { + scope = s; + } + + Scope::Root { opt_parent_item } => { + if let Some(parent_item) = opt_parent_item + && let parent_generics = self.tcx.generics_of(parent_item) + && parent_generics.param_def_id_to_index(self.tcx, param_def_id.to_def_id()).is_some() + { + break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id())); + } + break None; + } + + Scope::Binder { ref bound_vars, scope_type, s, .. } => { + if let Some(&def) = bound_vars.get(¶m_def_id) { + break Some(def.shifted(late_depth)); + } + match scope_type { + BinderScopeType::Normal => late_depth += 1, + BinderScopeType::Concatenating => {} + } + scope = s; + } + + Scope::Elision { s, .. } + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::Supertrait { s, .. } + | Scope::TraitRefBoundary { s, .. } => { + scope = s; + } + } + }; + + if let Some(def) = result { + self.map.defs.insert(hir_id, def); + return; + } + + span_bug!(self.tcx.hir().span(hir_id), "could not resolve {param_def_id:?}",); + } + #[instrument(level = "debug", skip(self))] fn visit_segment_args( &mut self, @@ -1415,10 +1453,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if in_body { None } else { - Some(Region::Static) + Some(ResolvedArg::StaticLifetime) } } - ObjectLifetimeDefault::Static => Some(Region::Static), + ObjectLifetimeDefault::Static => Some(ResolvedArg::StaticLifetime), ObjectLifetimeDefault::Param(param_def_id) => { // This index can be used with `generic_args` since `parent_count == 0`. let index = generics.param_def_id_to_index[¶m_def_id] as usize; @@ -1507,18 +1545,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // in the trait ref `YY<...>` in `Item: YY<...>`. for binding in generic_args.bindings { let scope = Scope::ObjectLifetimeDefault { - lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) }, + lifetime: if has_lifetime_parameter { + None + } else { + Some(ResolvedArg::StaticLifetime) + }, s: self.scope, }; if let Some(type_def_id) = type_def_id { - let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes( - self.tcx, - type_def_id, - binding.ident, - ); + let bound_vars = + BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident); self.with(scope, |this| { let scope = Scope::Supertrait { - lifetimes: lifetimes.unwrap_or_default(), + bound_vars: bound_vars.unwrap_or_default(), s: this.scope, }; this.with(scope, |this| this.visit_assoc_type_binding(binding)); @@ -1541,7 +1580,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// ``` /// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on /// the starting trait `Bar`, we would return `Some(['b, 'a])`. - fn supertrait_hrtb_lifetimes( + fn supertrait_hrtb_vars( tcx: TyCtxt<'tcx>, def_id: DefId, assoc_name: Ident, @@ -1626,7 +1665,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Root { .. } | Scope::Elision { .. } => break Region::Static, + Scope::Root { .. } | Scope::Elision { .. } => break ResolvedArg::StaticLifetime, Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return, @@ -1641,7 +1680,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } #[instrument(level = "debug", skip(self))] - fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) { + fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) { debug!(span = ?lifetime_ref.ident.span); self.map.defs.insert(lifetime_ref.hir_id, def); } @@ -1649,7 +1688,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// Sometimes we resolve a lifetime, but later find that it is an /// error (esp. around impl trait). In that case, we remove the /// entry into `map.defs` so as not to confuse later code. - fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) { + fn uninsert_lifetime_on_error( + &mut self, + lifetime_ref: &'tcx hir::Lifetime, + bad_def: ResolvedArg, + ) { let old_value = self.map.defs.remove(&lifetime_ref.hir_id); assert_eq!(old_value, Some(bad_def)); } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 54fcccb0c11..600a4efd308 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -259,13 +259,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } TraitItemKind::Const(ty, body_id) => body_id .and_then(|body_id| { - if is_suggestable_infer_ty(ty) { - Some(infer_placeholder_type( - tcx, def_id, body_id, ty.span, item.ident, "constant", - )) - } else { - None - } + is_suggestable_infer_ty(ty) + .then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",)) }) .unwrap_or_else(|| icx.to_ty(ty)), TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty), diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index c2fa46e563e..a0f738a2799 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -204,7 +204,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); match tcx.hir().find(hir_id) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { - generics.params.is_empty().not().then(|| generics.span) + generics.params.is_empty().not().then_some(generics.span) } _ => { span_bug!(tcx.def_span(def_id), "main has a non-function type"); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 05f6d8e6072..dbd0c5abeac 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -74,15 +74,13 @@ pub(super) fn check_fn<'a, 'tcx>( // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). - let maybe_va_list = if fn_sig.c_variadic { + let maybe_va_list = fn_sig.c_variadic.then(|| { let span = body.params.last().unwrap().span; let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); - Some(tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()])) - } else { - None - }; + tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()]) + }); // Add formal parameters. let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 7173239ba61..ba503bf47e7 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ) .may_apply() - .then(|| deref_ty) + .then_some(deref_ty) }) } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 76e87a9e566..de7819e3c6a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1269,10 +1269,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` let ref_ty = match mutability { hir::Mutability::Mut => { - self.tcx.mk_mut_ref(self.tcx.mk_region(ty::ReStatic), checked_ty) + self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, checked_ty) } hir::Mutability::Not => { - self.tcx.mk_imm_ref(self.tcx.mk_region(ty::ReStatic), checked_ty) + self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, checked_ty) } }; if self.can_coerce(ref_ty, expected) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f434fb92289..d13d8ff8270 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -477,12 +477,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This is the "trait" (meaning, the predicate "proved" by this `impl`) which provides the `Self` type we care about. // For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of // that struct type. - let impl_trait_self_ref: Option<ty::TraitRef<'tcx>> = - self.tcx.impl_trait_ref(obligation.impl_def_id).map(|impl_def| impl_def.skip_binder()); - - let Some(impl_trait_self_ref) = impl_trait_self_ref else { - // It is possible that this is absent. In this case, we make no progress. - return Err(expr); + let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_def_id) { + self.tcx.mk_trait_ref( + obligation.impl_def_id, + ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_def_id), + ) + } else { + self.tcx + .impl_trait_ref(obligation.impl_def_id) + .map(|impl_def| impl_def.skip_binder()) + // It is possible that this is absent. In this case, we make no progress. + .ok_or(expr)? }; // We only really care about the `Self` type itself, which we extract from the ref. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9c7a84ce198..69a7235802b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -755,15 +755,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } errors.drain_filter(|error| { - let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false }; - let (provided_ty, provided_span) = provided_arg_tys[*provided_idx]; - let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); - if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) { - self.err_ctxt().report_and_explain_type_error(trace, *e).emit(); - return true; - } - false - }); + let Error::Invalid( + provided_idx, + expected_idx, + Compatibility::Incompatible(Some(e)), + ) = error else { return false }; + let (provided_ty, provided_span) = provided_arg_tys[*provided_idx]; + let trace = + mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); + if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) { + self.err_ctxt().report_and_explain_type_error(trace, *e).emit(); + return true; + } + false + }); // We're done if we found errors, but we already emitted them. if errors.is_empty() { @@ -864,7 +869,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut suggestion_text = SuggestionText::None; + let ty_to_snippet = |ty: Ty<'tcx>, expected_idx: ExpectedIdx| { + if ty.is_unit() { + "()".to_string() + } else if ty.is_suggestable(tcx, false) { + format!("/* {} */", ty) + } else if let Some(fn_def_id) = fn_def_id + && self.tcx.def_kind(fn_def_id).is_fn_like() + && let self_implicit = + matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize + && let Some(arg) = self.tcx.fn_arg_names(fn_def_id) + .get(expected_idx.as_usize() + self_implicit) + && arg.name != kw::SelfLower + { + format!("/* {} */", arg.name) + } else { + "/* value */".to_string() + } + }; + let mut errors = errors.into_iter().peekable(); + let mut suggestions = vec![]; while let Some(error) = errors.next() { match error { Error::Invalid(provided_idx, expected_idx, compatibility) => { @@ -905,7 +930,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "".to_string() }; labels - .push((provided_span, format!("argument{} unexpected", provided_ty_name))); + .push((provided_span, format!("unexpected argument{}", provided_ty_name))); + let mut span = provided_span; + if arg_idx.index() > 0 + && let Some((_, prev)) = provided_arg_tys + .get(ProvidedIdx::from_usize(arg_idx.index() - 1) + ) { + // Include previous comma + span = span.with_lo(prev.hi()); + } else if let Some((_, next)) = provided_arg_tys.get( + ProvidedIdx::from_usize(arg_idx.index() + 1), + ) { + // Include next comma + span = span.until(*next); + } + suggestions.push((span, String::new())); + suggestion_text = match suggestion_text { SuggestionText::None => SuggestionText::Remove(false), SuggestionText::Remove(_) => SuggestionText::Remove(true), @@ -1095,6 +1135,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + // Incorporate the argument changes in the removal suggestion. + // When a type is *missing*, and the rest are additional, we want to suggest these with a + // multipart suggestion, but in order to do so we need to figure out *where* the arg that + // was provided but had the wrong type should go, because when looking at `expected_idx` + // that is the position in the argument list in the definition, while `provided_idx` will + // not be present. So we have to look at what the *last* provided position was, and point + // one after to suggest the replacement. FIXME(estebank): This is hacky, and there's + // probably a better more involved change we can make to make this work. + // For example, if we have + // ``` + // fn foo(i32, &'static str) {} + // foo((), (), ()); + // ``` + // what should be suggested is + // ``` + // foo(/* i32 */, /* &str */); + // ``` + // which includes the replacement of the first two `()` for the correct type, and the + // removal of the last `()`. + let mut prev = -1; + for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() { + // We want to point not at the *current* argument expression index, but rather at the + // index position where it *should have been*, which is *after* the previous one. + if let Some(provided_idx) = provided_idx { + prev = provided_idx.index() as i64; + } + let idx = ProvidedIdx::from_usize((prev + 1) as usize); + if let None = provided_idx + && let Some((_, arg_span)) = provided_arg_tys.get(idx) + { + // There is a type that was *not* found anywhere, so it isn't a move, but a + // replacement and we look at what type it should have been. This will allow us + // To suggest a multipart suggestion when encountering `foo(1, "")` where the def + // was `fn foo(())`. + let (_, expected_ty) = formal_and_expected_inputs[expected_idx]; + suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx))); + } + } + // If we have less than 5 things to say, it would be useful to call out exactly what's wrong if labels.len() <= 5 { for (span, label) in labels { @@ -1112,7 +1191,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(format!("provide the argument{}", if plural { "s" } else { "" })) } SuggestionText::Remove(plural) => { - Some(format!("remove the extra argument{}", if plural { "s" } else { "" })) + err.multipart_suggestion( + &format!("remove the extra argument{}", if plural { "s" } else { "" }), + suggestions, + Applicability::HasPlaceholders, + ); + None } SuggestionText::Swap => Some("swap these arguments".to_string()), SuggestionText::Reorder => Some("reorder these arguments".to_string()), @@ -1151,20 +1235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Propose a placeholder of the correct type let (_, expected_ty) = formal_and_expected_inputs[expected_idx]; - if expected_ty.is_unit() { - "()".to_string() - } else if expected_ty.is_suggestable(tcx, false) { - format!("/* {} */", expected_ty) - } else if let Some(fn_def_id) = fn_def_id - && self.tcx.def_kind(fn_def_id).is_fn_like() - && let self_implicit = matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize - && let Some(arg) = self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit) - && arg.name != kw::SelfLower - { - format!("/* {} */", arg.name) - } else { - "/* value */".to_string() - } + ty_to_snippet(expected_ty, expected_idx) }; suggestion += &suggestion_text; } @@ -1669,7 +1740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *qpath { QPath::Resolved(ref maybe_qself, ref path) => { let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw); - let ty = self.astconv().res_to_ty(self_ty, path, true); + let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true); (path.res, self.handle_raw_ty(path_span, ty)) } QPath::TypeRelative(ref qself, ref segment) => { diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 29ed9a24ecf..3f61a1a83e5 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -271,15 +271,13 @@ pub fn resolve_interior<'a, 'tcx>( }, _ => mk_bound_region(None), }; - let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); + let r = fcx.tcx.mk_re_late_bound(current_depth, br); r }); - if captured_tys.insert(ty) { + captured_tys.insert(ty).then(|| { cause.ty = ty; - Some(cause) - } else { - None - } + cause + }) }) .collect(); @@ -302,7 +300,7 @@ pub fn resolve_interior<'a, 'tcx>( let var = ty::BoundVar::from_usize(bound_vars.len()); bound_vars.push(ty::BoundVariableKind::Region(kind)); counter += 1; - fcx.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var, kind })) + fcx.tcx.mk_re_late_bound(ty::INNERMOST, ty::BoundRegion { var, kind }) }, types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"), consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"), @@ -364,7 +362,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { let ty = tcx.mk_ref( // Use `ReErased` as `resolve_interior` is going to replace all the // regions anyway. - tcx.mk_region(ty::ReErased), + tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Not }, ); self.interior_visitor.record( diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 6bfdeda3a24..2b33d31994f 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -363,7 +363,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { opportunistically resolved to {:?}", vid, resolved_vid ); - let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid)); + let r = self.tcx.mk_re_var(resolved_vid); self.canonicalize_mode.canonicalize_free_region(self, r) } @@ -737,8 +737,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) }; - let region = ty::ReLateBound(self.binder_index, br); - self.interner().mk_region(region) + self.interner().mk_re_late_bound(self.binder_index, br) } /// Given a type variable `ty_var` of the given kind, first check diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index d5cb3fb2498..4552256545b 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -137,7 +137,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, name }; - self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into() + self.tcx.mk_re_placeholder(placeholder_mapped).into() } CanonicalVarKind::Const(ui, ty) => self diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 0c97217bd6a..b9cb9732ca3 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -642,15 +642,14 @@ pub fn make_query_region_constraints<'tcx>( let constraint = match *k { // Swap regions because we are going from sub (<=) to outlives // (>=). - Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( - tcx.mk_region(ty::ReVar(v2)).into(), - tcx.mk_region(ty::ReVar(v1)), - ), + Constraint::VarSubVar(v1, v2) => { + ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), tcx.mk_re_var(v1)) + } Constraint::VarSubReg(v1, r2) => { - ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1))) + ty::OutlivesPredicate(r2.into(), tcx.mk_re_var(v1)) } Constraint::RegSubVar(r1, v2) => { - ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1) + ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), r1) } Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), }; @@ -690,7 +689,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { } fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { - self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder)) + self.infcx.tcx.mk_re_placeholder(placeholder) } fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 39f4d502259..4fe6c6618f6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::resolve_lifetime as rl; +use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::ty::{self, Region, TyCtxt}; /// This function calls the `visit_ty` method for the parameters @@ -99,11 +99,11 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { hir::TyKind::Ref(ref lifetime, _) => { // the lifetime of the Ref let hir_id = lifetime.hir_id; - match (self.tcx.named_region(hir_id), self.bound_region) { + match (self.tcx.named_bound_var(hir_id), self.bound_region) { // Find the index of the named region that was part of the // error. We will then search the function parameters for a bound // region at the right depth with the same index - (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => { + (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_type = Some(arg); @@ -115,7 +115,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // error. We will then search the function parameters for a bound // region at the right depth with the same index ( - Some(rl::Region::LateBound(debruijn_index, _, id)), + Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)), ty::BrNamed(def_id, _), ) => { debug!( @@ -131,10 +131,10 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { ( Some( - rl::Region::Static - | rl::Region::Free(_, _) - | rl::Region::EarlyBound(_) - | rl::Region::LateBound(_, _, _), + rbv::ResolvedArg::StaticLifetime + | rbv::ResolvedArg::Free(_, _) + | rbv::ResolvedArg::EarlyBound(_) + | rbv::ResolvedArg::LateBound(_, _, _), ) | None, _, @@ -186,9 +186,9 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { } fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { - match (self.tcx.named_region(lifetime.hir_id), self.bound_region) { + match (self.tcx.named_bound_var(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! - (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => { + (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_it = true; @@ -196,7 +196,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { } } - (Some(rl::Region::LateBound(debruijn_index, _, id)), ty::BrNamed(def_id, _)) => { + (Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)), ty::BrNamed(def_id, _)) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,); debug!("id={:?}", id); debug!("def_id={:?}", def_id); @@ -208,10 +208,10 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { ( Some( - rl::Region::Static - | rl::Region::EarlyBound(_) - | rl::Region::LateBound(_, _, _) - | rl::Region::Free(_, _), + rbv::ResolvedArg::StaticLifetime + | rbv::ResolvedArg::EarlyBound(_) + | rbv::ResolvedArg::LateBound(_, _, _) + | rbv::ResolvedArg::Free(_, _), ) | None, _, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 99431567eda..c1ea0a0d95e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -14,7 +14,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, RePlaceholder, ReVar, Region, TyCtxt}; +use rustc_middle::ty::{self, RePlaceholder, Region, TyCtxt}; use std::fmt; @@ -79,7 +79,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sup_placeholder @ Region(Interned(RePlaceholder(_), _)), _, )) => self.try_report_trait_placeholder_mismatch( - Some(self.tcx().mk_region(ReVar(*vid))), + Some(self.tcx().mk_re_var(*vid)), cause, Some(*sub_placeholder), Some(*sup_placeholder), @@ -95,7 +95,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { _, _, )) => self.try_report_trait_placeholder_mismatch( - Some(self.tcx().mk_region(ReVar(*vid))), + Some(self.tcx().mk_re_var(*vid)), cause, Some(*sub_placeholder), None, @@ -111,7 +111,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sup_placeholder @ Region(Interned(RePlaceholder(_), _)), _, )) => self.try_report_trait_placeholder_mismatch( - Some(self.tcx().mk_region(ReVar(*vid))), + Some(self.tcx().mk_re_var(*vid)), cause, None, Some(*sup_placeholder), @@ -127,7 +127,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sup_placeholder @ Region(Interned(RePlaceholder(_), _)), _, )) => self.try_report_trait_placeholder_mismatch( - Some(self.tcx().mk_region(ReVar(*vid))), + Some(self.tcx().mk_re_var(*vid)), cause, None, Some(*sup_placeholder), @@ -141,7 +141,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { SubregionOrigin::Subtype(box TypeTrace { cause, values }), sup_placeholder @ Region(Interned(RePlaceholder(_), _)), )) => self.try_report_trait_placeholder_mismatch( - Some(self.tcx().mk_region(ReVar(*vid))), + Some(self.tcx().mk_re_var(*vid)), cause, None, Some(*sup_placeholder), 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 4c0f457b46a..5643d1d9f74 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 @@ -90,20 +90,18 @@ pub fn find_param_with_region<'tcx>( r } }); - if found_anon_region { + found_anon_region.then(|| { let ty_hir_id = fn_decl.inputs[index].hir_id; let param_ty_span = hir.span(ty_hir_id); let is_first = index == 0; - Some(AnonymousParamInfo { + AnonymousParamInfo { param, param_ty: new_param_ty, param_ty_span, bound_region, is_first, - }) - } else { - None - } + } + }) }) } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 39940f4592d..82a1bb1fd16 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -82,10 +82,10 @@ impl<'tcx> InferCtxt<'tcx> { let delegate = FnMutDelegate { regions: &mut |br: ty::BoundRegion| { - self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion { + self.tcx.mk_re_placeholder(ty::PlaceholderRegion { universe: next_universe, name: br.kind, - })) + }) }, types: &mut |bound_ty: ty::BoundTy| { self.tcx.mk_placeholder(ty::PlaceholderType { 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 4a2210bdb68..ac203c4eb0b 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -382,7 +382,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // name the placeholder, then the placeholder is // larger; otherwise, the only ancestor is `'static`. Err(placeholder) if empty_ui.can_name(placeholder.universe) => { - self.tcx().mk_region(RePlaceholder(placeholder)) + self.tcx().mk_re_placeholder(placeholder) } Err(_) => self.tcx().lifetimes.re_static, }; @@ -1046,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, - VarValue::ErrorValue => tcx.re_error_misc(), + VarValue::ErrorValue => tcx.mk_re_error_misc(), }, _ => r, }; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 17e734f0700..bb734ccb20e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1093,7 +1093,7 @@ impl<'tcx> InferCtxt<'tcx> { ) -> ty::Region<'tcx> { let region_var = self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin); - self.tcx.mk_region(ty::ReVar(region_var)) + self.tcx.mk_re_var(region_var) } /// Return the universe that the region `r` was created in. For diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index c46edc33ff4..e413b2bb570 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -280,7 +280,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> { placeholder1: ty::PlaceholderRegion, placeholder2: ty::PlaceholderRegion, ) -> TypeError<'tcx> { - self.error(placeholder1, self.tcx.mk_region(ty::RePlaceholder(placeholder2))) + self.error(placeholder1, self.tcx.mk_re_placeholder(placeholder2)) } fn error( @@ -413,19 +413,19 @@ impl<'tcx> MiniGraph<'tcx> { for undo_entry in undo_log { match undo_entry { &AddConstraint(Constraint::VarSubVar(a, b)) => { - each_edge(tcx.mk_region(ReVar(a)), tcx.mk_region(ReVar(b))); + each_edge(tcx.mk_re_var(a), tcx.mk_re_var(b)); } &AddConstraint(Constraint::RegSubVar(a, b)) => { - each_edge(a, tcx.mk_region(ReVar(b))); + each_edge(a, tcx.mk_re_var(b)); } &AddConstraint(Constraint::VarSubReg(a, b)) => { - each_edge(tcx.mk_region(ReVar(a)), b); + each_edge(tcx.mk_re_var(a), b); } &AddConstraint(Constraint::RegSubReg(a, b)) => { each_edge(a, b); } &AddGiven(a, b) => { - each_edge(a, tcx.mk_region(ReVar(b))); + each_edge(a, tcx.mk_re_var(b)); } &AddVerify(i) => span_bug!( verifys[i].origin.span(), diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index cb24375c7a3..33514eedfc3 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -651,7 +651,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { let unified_region = self.unification_table().probe_value(rid); unified_region.0.unwrap_or_else(|| { let root = self.unification_table().find(rid).vid; - tcx.reuse_or_mk_region(region, ty::ReVar(root)) + tcx.mk_re_var(root) }) } _ => region, @@ -675,7 +675,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { ) -> Region<'tcx> { let vars = TwoRegions { a, b }; if let Some(&c) = self.combine_map(t).get(&vars) { - return tcx.mk_region(ReVar(c)); + return tcx.mk_re_var(c); } let a_universe = self.universe(a); let b_universe = self.universe(b); @@ -683,7 +683,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { let c = self.new_region_var(c_universe, MiscVariable(origin.span())); self.combine_map(t).insert(vars, c); self.undo_log.push(AddCombination(t, vars)); - let new_r = tcx.mk_region(ReVar(c)); + let new_r = tcx.mk_re_var(c); for old_r in [a, b] { match t { Glb => self.make_subregion(origin.clone(), new_r, old_r), diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 008bf1e9c5d..2c246a5787c 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx .borrow_mut() .unwrap_region_constraints() .opportunistic_resolve_var(rid); - TypeFolder::interner(self).reuse_or_mk_region(r, ty::ReVar(resolved)) + TypeFolder::interner(self).mk_re_var(resolved) } _ => r, } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f18c0aa377f..cd793d36de6 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2007,7 +2007,7 @@ impl ExplicitOutlivesRequirements { inferred_outlives: &[ty::Region<'tcx>], predicate_span: Span, ) -> Vec<(usize, Span)> { - use rustc_middle::middle::resolve_lifetime::Region; + use rustc_middle::middle::resolve_bound_vars::ResolvedArg; bounds .iter() @@ -2017,8 +2017,8 @@ impl ExplicitOutlivesRequirements { return None; }; - let is_inferred = match tcx.named_region(lifetime.hir_id) { - Some(Region::EarlyBound(def_id)) => inferred_outlives + 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 })), _ => false, @@ -2097,7 +2097,7 @@ impl ExplicitOutlivesRequirements { impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - use rustc_middle::middle::resolve_lifetime::Region; + use rustc_middle::middle::resolve_bound_vars::ResolvedArg; let def_id = item.owner_id.def_id; if let hir::ItemKind::Struct(_, hir_generics) @@ -2120,8 +2120,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { let (relevant_lifetimes, bounds, predicate_span, in_where_clause) = match where_predicate { hir::WherePredicate::RegionPredicate(predicate) => { - if let Some(Region::EarlyBound(region_def_id)) = - cx.tcx.named_region(predicate.lifetime.hir_id) + if let Some(ResolvedArg::EarlyBound(region_def_id)) = + cx.tcx.named_bound_var(predicate.lifetime.hir_id) { ( Self::lifetimes_outliving_lifetime( @@ -2308,11 +2308,8 @@ impl EarlyLintPass for IncompleteFeatures { .for_each(|(&name, &span)| { let note = rustc_feature::find_feature_issue(name, GateIssue::Language) .map(|n| BuiltinIncompleteFeaturesNote { n }); - let help = if HAS_MIN_FEATURES.contains(&name) { - Some(BuiltinIncompleteFeaturesHelp) - } else { - None - }; + let help = + HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp); cx.emit_spanned_lint( INCOMPLETE_FEATURES, span, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 972240f42cf..9a9e2de7b5c 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -487,7 +487,7 @@ impl LintStore { let mut groups: Vec<_> = self .lint_groups .iter() - .filter_map(|(k, LintGroup { depr, .. })| if depr.is_none() { Some(k) } else { None }) + .filter_map(|(k, LintGroup { depr, .. })| depr.is_none().then_some(k)) .collect(); groups.sort(); let groups = groups.iter().map(|k| Symbol::intern(k)); @@ -1112,11 +1112,9 @@ impl<'tcx> LateContext<'tcx> { .maybe_typeck_results() .filter(|typeck_results| typeck_results.hir_owner == id.owner) .or_else(|| { - if self.tcx.has_typeck_results(id.owner.to_def_id()) { - Some(self.tcx.typeck(id.owner.def_id)) - } else { - None - } + self.tcx + .has_typeck_results(id.owner.to_def_id()) + .then(|| self.tcx.typeck(id.owner.def_id)) }) .and_then(|typeck_results| typeck_results.type_dependent_def(id)) .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 1add352e0c4..a3367ae4a9f 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -65,11 +65,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { } else { ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), end_span: pat.span.between(arg.span), var } } ; - let question_mark = if suggest_question_mark(cx, adt, substs, expr.span) { - Some(ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() }) - } else { - None - }; + let question_mark = suggest_question_mark(cx, adt, substs, expr.span) + .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() }); let suggestion = ForLoopsOverFalliblesSuggestion { var, start_span: expr.span.with_hi(pat.span.lo()), diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 9227609cc8b..a9fb8b246c6 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -18,7 +18,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; -use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; +use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::query::Providers; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ba93330d581..2eafc356dc3 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1062,7 +1062,7 @@ impl<'hir> Map<'hir> { } pub fn span_if_local(self, id: DefId) -> Option<Span> { - if id.is_local() { Some(self.tcx.def_span(id)) } else { None } + id.is_local().then(|| self.tcx.def_span(id)) } pub fn res_span(self, res: Res) -> Option<Span> { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index ada516aa032..bb617e692cc 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -353,7 +353,7 @@ impl<'tcx> CanonicalVarValues<'tcx> { var: ty::BoundVar::from_usize(i), kind: ty::BrAnon(i as u32, None), }; - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() + tcx.mk_re_late_bound(ty::INNERMOST, br).into() } CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => tcx diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 8dc68b1f5a8..0b6774f1b1f 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -29,7 +29,7 @@ pub mod lib_features { pub mod limits; pub mod privacy; pub mod region; -pub mod resolve_lifetime; +pub mod resolve_bound_vars; pub mod stability; pub fn provide(providers: &mut crate::ty::query::Providers) { diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs index c3bf1c717d9..b96d07e7dc8 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -1,4 +1,4 @@ -//! Name resolution for lifetimes: type declarations. +//! Name resolution for lifetimes and late-bound type and const variables: type declarations. use crate::ty; @@ -8,10 +8,10 @@ use rustc_hir::{ItemLocalId, OwnerId}; use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] -pub enum Region { - Static, - EarlyBound(/* lifetime decl */ DefId), - LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* lifetime decl */ DefId), +pub enum ResolvedArg { + StaticLifetime, + EarlyBound(/* decl */ DefId), + LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ DefId), Free(DefId, /* lifetime decl */ DefId), } @@ -46,10 +46,10 @@ pub enum ObjectLifetimeDefault { /// Maps the id of each lifetime reference to the lifetime decl /// that it corresponds to. #[derive(Default, HashStable, Debug)] -pub struct ResolveLifetimes { +pub struct ResolveBoundVars { /// Maps from every use of a named (not anonymous) lifetime to a /// `Region` describing how that region is bound - pub defs: FxHashMap<OwnerId, FxHashMap<ItemLocalId, Region>>, + pub defs: FxHashMap<OwnerId, FxHashMap<ItemLocalId, ResolvedArg>>, pub late_bound_vars: FxHashMap<OwnerId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>, } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c596e91160c..3cb07b5b41e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -414,7 +414,7 @@ impl<'tcx> Body<'tcx> { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); let decl = &self.local_decls[local]; - (decl.is_user_variable() && decl.mutability.is_mut()).then(|| local) + (decl.is_user_variable() && decl.mutability.is_mut()).then_some(local) }) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4b34f6b4881..c793676146d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1641,12 +1641,12 @@ rustc_queries! { /// Does lifetime resolution on items. Importantly, we can't resolve /// lifetimes directly on things like trait methods, because of trait params. /// See `rustc_resolve::late::lifetimes for details. - query resolve_lifetimes(_: hir::OwnerId) -> &'tcx ResolveLifetimes { + query resolve_bound_vars(_: hir::OwnerId) -> &'tcx ResolveBoundVars { arena_cache desc { "resolving lifetimes" } } - query named_region_map(_: hir::OwnerId) -> - Option<&'tcx FxHashMap<ItemLocalId, Region>> { + query named_variable_map(_: hir::OwnerId) -> + Option<&'tcx FxHashMap<ItemLocalId, ResolvedArg>> { desc { "looking up a named region" } } query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 927f18f59b9..c7268d561e5 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,7 +1,9 @@ +use crate::middle::resolve_bound_vars as rbv; use crate::mir::interpret::LitToConstInput; use crate::ty::{self, DefIdTree, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::HashStable; use std::fmt; @@ -125,16 +127,27 @@ impl<'tcx> Const<'tcx> { } } - use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; match expr.kind { - ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { - // Find the name and index of the const parameter by indexing the generics of - // the parent item and construct a `ParamConst`. - let item_def_id = tcx.parent(def_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&def_id]; - let name = tcx.item_name(def_id); - Some(tcx.mk_const(ty::ParamConst::new(index, name), ty)) + hir::ExprKind::Path(hir::QPath::Resolved( + _, + &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }, + )) => { + match tcx.named_bound_var(expr.hir_id) { + Some(rbv::ResolvedArg::EarlyBound(_)) => { + // Find the name and index of the const parameter by indexing the generics of + // the parent item and construct a `ParamConst`. + let item_def_id = tcx.parent(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.item_name(def_id); + Some(tcx.mk_const(ty::ParamConst::new(index, name), ty)) + } + Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => Some(tcx.mk_const( + ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)), + ty, + )), + arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id), + } } _ => None, } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4aef071cd98..f5322006bec 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -9,7 +9,7 @@ use crate::dep_graph::{DepGraph, DepKindStruct}; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::struct_lint_level; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::resolve_lifetime; +use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{ @@ -243,11 +243,20 @@ impl<'tcx> CtxtInterners<'tcx> { } } +// For these preinterned values, an alternative would be to have +// variable-length vectors that grow as needed. But that turned out to be +// slightly more complex and no faster. + const NUM_PREINTERNED_TY_VARS: u32 = 100; const NUM_PREINTERNED_FRESH_TYS: u32 = 20; const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3; const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3; +// This number may seem high, but it is reached in all but the smallest crates. +const NUM_PREINTERNED_RE_VARS: u32 = 500; +const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2; +const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20; + pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, pub bool: Ty<'tcx>, @@ -295,6 +304,14 @@ pub struct CommonLifetimes<'tcx> { /// Erased region, used outside of type inference. pub re_erased: Region<'tcx>, + + /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`. + pub re_vars: Vec<Region<'tcx>>, + + /// Pre-interned values of the form: + /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(v, None) }) + /// for small values of `i` and `v`. + pub re_late_bounds: Vec<Vec<Region<'tcx>>>, } pub struct CommonConsts<'tcx> { @@ -358,7 +375,31 @@ impl<'tcx> CommonLifetimes<'tcx> { )) }; - CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) } + let re_vars = + (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect(); + + let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I) + .map(|i| { + (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V) + .map(|v| { + mk(ty::ReLateBound( + ty::DebruijnIndex::from(i), + ty::BoundRegion { + var: ty::BoundVar::from(v), + kind: ty::BrAnon(v, None), + }, + )) + }) + .collect() + }) + .collect(); + + CommonLifetimes { + re_static: mk(ty::ReStatic), + re_erased: mk(ty::ReErased), + re_vars, + re_late_bounds, + } } } @@ -697,15 +738,15 @@ impl<'tcx> TyCtxt<'tcx> { /// Constructs a `RegionKind::ReError` lifetime. #[track_caller] - pub fn re_error(self, reported: ErrorGuaranteed) -> Region<'tcx> { - self.mk_region(ty::ReError(reported)) + pub fn mk_re_error(self, reported: ErrorGuaranteed) -> Region<'tcx> { + self.intern_region(ty::ReError(reported)) } /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` to ensure it /// gets used. #[track_caller] - pub fn re_error_misc(self) -> Region<'tcx> { - self.re_error_with_message( + pub fn mk_re_error_misc(self) -> Region<'tcx> { + self.mk_re_error_with_message( DUMMY_SP, "RegionKind::ReError constructed but no error reported", ) @@ -714,9 +755,9 @@ impl<'tcx> TyCtxt<'tcx> { /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` with the given /// `msg` to ensure it gets used. #[track_caller] - pub fn re_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Region<'tcx> { + pub fn mk_re_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Region<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - self.re_error(reported) + self.mk_re_error(reported) } /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` @@ -1113,13 +1154,11 @@ impl<'tcx> TyCtxt<'tcx> { ty::FnDef(_, _) => { let sig = ret_ty.fn_sig(self); let output = self.erase_late_bound_regions(sig.output()); - if output.is_impl_trait() { + output.is_impl_trait().then(|| { let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); - Some((output, fn_decl.output.span())) - } else { - None - } + (output, fn_decl.output.span()) + }) } _ => None, } @@ -1225,13 +1264,12 @@ macro_rules! nop_lift { impl<'a, 'tcx> Lift<'tcx> for $ty { type Lifted = $lifted; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) { + tcx.interners + .$set + .contains_pointer_to(&InternedInSet(&*self.0.0)) // SAFETY: `self` is interned and therefore valid // for the entire lifetime of the `TyCtxt`. - Some(unsafe { mem::transmute(self) }) - } else { - None - } + .then(|| unsafe { mem::transmute(self) }) } } }; @@ -1246,13 +1284,13 @@ impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> { if self.is_empty() { return Some(List::empty()); } - if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) { + + tcx.interners + .substs + .contains_pointer_to(&InternedInSet(self.as_substs())) // SAFETY: `self` is interned and therefore valid // for the entire lifetime of the `TyCtxt`. - Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) }) - } else { - None - } + .then(|| unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) }) } } @@ -1264,11 +1302,10 @@ macro_rules! nop_list_lift { if self.is_empty() { return Some(List::empty()); } - if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) { - Some(unsafe { mem::transmute(self) }) - } else { - None - } + tcx.interners + .$set + .contains_pointer_to(&InternedInSet(self)) + .then(|| unsafe { mem::transmute(self) }) } } }; @@ -1517,7 +1554,7 @@ macro_rules! direct_interners { } direct_interners! { - region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>, + region: intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>, const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, layout: intern_layout(LayoutS): Layout -> Layout<'tcx>, @@ -1631,13 +1668,6 @@ impl<'tcx> TyCtxt<'tcx> { }) } - /// Same a `self.mk_region(kind)`, but avoids accessing the interners if - /// `*r == kind`. - #[inline] - pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { - if *r == kind { r } else { self.mk_region(kind) } - } - // Avoid this in favour of more specific `mk_*` methods, where possible. #[allow(rustc::usage_of_ty_tykind)] #[inline] @@ -1966,7 +1996,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { match param.kind { GenericParamDefKind::Lifetime => { - self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into() + self.mk_re_early_bound(param.to_early_bound_region_data()).into() } GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(), GenericParamDefKind::Const { .. } => self @@ -1998,6 +2028,66 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_alias(ty::Opaque, self.mk_alias_ty(def_id, substs)) } + #[inline] + pub fn mk_re_early_bound(self, early_bound_region: ty::EarlyBoundRegion) -> Region<'tcx> { + self.intern_region(ty::ReEarlyBound(early_bound_region)) + } + + #[inline] + pub fn mk_re_late_bound( + self, + debruijn: ty::DebruijnIndex, + bound_region: ty::BoundRegion, + ) -> Region<'tcx> { + // Use a pre-interned one when possible. + if let ty::BoundRegion { var, kind: ty::BrAnon(v, None) } = bound_region + && var.as_u32() == v + && let Some(inner) = self.lifetimes.re_late_bounds.get(debruijn.as_usize()) + && let Some(re) = inner.get(v as usize).copied() + { + re + } else { + self.intern_region(ty::ReLateBound(debruijn, bound_region)) + } + } + + #[inline] + pub fn mk_re_free(self, scope: DefId, bound_region: ty::BoundRegionKind) -> Region<'tcx> { + self.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region })) + } + + #[inline] + pub fn mk_re_var(self, v: ty::RegionVid) -> Region<'tcx> { + // Use a pre-interned one when possible. + self.lifetimes + .re_vars + .get(v.as_usize()) + .copied() + .unwrap_or_else(|| self.intern_region(ty::ReVar(v))) + } + + #[inline] + pub fn mk_re_placeholder(self, placeholder: ty::PlaceholderRegion) -> Region<'tcx> { + self.intern_region(ty::RePlaceholder(placeholder)) + } + + // Avoid this in favour of more specific `mk_re_*` methods, where possible, + // to avoid the cost of the `match`. + pub fn mk_region(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> { + match kind { + ty::ReEarlyBound(region) => self.mk_re_early_bound(region), + ty::ReLateBound(debruijn, region) => self.mk_re_late_bound(debruijn, region), + ty::ReFree(ty::FreeRegion { scope, bound_region }) => { + self.mk_re_free(scope, bound_region) + } + ty::ReStatic => self.lifetimes.re_static, + ty::ReVar(vid) => self.mk_re_var(vid), + ty::RePlaceholder(region) => self.mk_re_placeholder(region), + ty::ReErased => self.lifetimes.re_erased, + ty::ReError(reported) => self.mk_re_error(reported), + } + } + pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { self.mk_place_elem(place, PlaceElem::Field(f, ty)) } @@ -2278,9 +2368,9 @@ impl<'tcx> TyCtxt<'tcx> { Some(&*candidates) } - pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> { + pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> { debug!(?id, "named_region"); - self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned()) + self.named_variable_map(id.owner).and_then(|map| map.get(&id.local_id).cloned()) } pub fn is_late_bound(self, id: HirId) -> bool { diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 9afa37e9ef3..106ce9990e1 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -290,7 +290,7 @@ impl DeepRejectCtxt { // Impls cannot contain these types as these cannot be named directly. ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false, - ty::Placeholder(..) => false, + ty::Placeholder(..) | ty::Bound(..) => false, // Depending on the value of `treat_obligation_params`, we either // treat generic parameters like placeholders or like inference variables. @@ -310,7 +310,7 @@ impl DeepRejectCtxt { ty::Error(_) => true, - ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Bound(..) => { + ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => { bug!("unexpected obligation type: {:?}", obligation_ty) } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 352daa8fc29..ee36e60bff1 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -234,7 +234,7 @@ where // debruijn index. Then we adjust it to the // correct depth. assert_eq!(debruijn1, ty::INNERMOST); - self.tcx.reuse_or_mk_region(region, ty::ReLateBound(debruijn, br)) + self.tcx.mk_re_late_bound(debruijn, br) } else { region } @@ -349,10 +349,7 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<'tcx>, { self.replace_late_bound_regions_uncached(value, |br| { - self.mk_region(ty::ReFree(ty::FreeRegion { - scope: all_outlive_scope, - bound_region: br.kind, - })) + self.mk_re_free(all_outlive_scope, br.kind) }) } @@ -365,10 +362,10 @@ impl<'tcx> TyCtxt<'tcx> { value, FnMutDelegate { regions: &mut |r: ty::BoundRegion| { - self.mk_region(ty::ReLateBound( + self.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: shift_bv(r.var), kind: r.kind }, - )) + ) }, types: &mut |t: ty::BoundTy| { self.mk_bound(ty::INNERMOST, ty::BoundTy { var: shift_bv(t.var), kind: t.kind }) @@ -409,7 +406,7 @@ impl<'tcx> TyCtxt<'tcx> { }) .expect_region(); let br = ty::BoundRegion { var, kind }; - self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) + self.tcx.mk_re_late_bound(ty::INNERMOST, br) } fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> { let entry = self.map.entry(bt.var); @@ -479,8 +476,7 @@ impl<'tcx> ir::TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> { match *r { ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - let shifted = ty::ReLateBound(debruijn, br); - self.tcx.mk_region(shifted) + self.tcx.mk_re_late_bound(debruijn, br) } _ => r, } @@ -521,7 +517,7 @@ pub fn shift_region<'tcx>( ) -> ty::Region<'tcx> { match *region { ty::ReLateBound(debruijn, br) if amount > 0 => { - tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), br)) + tcx.mk_re_late_bound(debruijn.shifted_in(amount), br) } _ => region, } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index ea95a38f272..c29a94c9714 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -100,7 +100,7 @@ impl GenericParamDef { preceding_substs: &[ty::GenericArg<'tcx>], ) -> ty::GenericArg<'tcx> { match &self.kind { - ty::GenericParamDefKind::Lifetime => tcx.re_error_misc().into(), + ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(), ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into() diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 55f2395e531..c6c3c1f08de 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -584,7 +584,7 @@ impl<'tcx> Instance<'tcx> { /// this function returns `None`, then the MIR body does not require substitution during /// codegen. fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> { - if self.def.has_polymorphic_mir_body() { Some(self.substs) } else { None } + self.def.has_polymorphic_mir_body().then_some(self.substs) } pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 66c878c8b63..8aeef4684b3 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -143,7 +143,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { ) .emit(); - self.interner().re_error(e) + self.interner().mk_re_error(e) } } } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 303675d3ca5..8849e7eab33 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -57,7 +57,7 @@ trivially_parameterized_over_tcx! { crate::metadata::ModChild, crate::middle::codegen_fn_attrs::CodegenFnAttrs, crate::middle::exported_symbols::SymbolExportInfo, - crate::middle::resolve_lifetime::ObjectLifetimeDefault, + crate::middle::resolve_bound_vars::ObjectLifetimeDefault, crate::mir::ConstQualifs, ty::AssocItemContainer, ty::DeducedParamAttrs, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f50a5d89d3d..1a228e99eff 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -182,7 +182,7 @@ impl<'tcx> RegionHighlightMode<'tcx> { /// Convenience wrapper for `highlighting_region`. pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) { - self.highlighting_region(self.tcx.mk_region(ty::ReVar(vid)), number) + self.highlighting_region(self.tcx.mk_re_var(vid), number) } /// Returns `Some(n)` with the number to use for the given region, if any. @@ -2271,7 +2271,7 @@ impl<'a, 'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { }; if let ty::ReLateBound(debruijn1, br) = *region { assert_eq!(debruijn1, ty::INNERMOST); - self.tcx.mk_region(ty::ReLateBound(self.current_index, br)) + self.tcx.mk_re_late_bound(self.current_index, br) } else { region } @@ -2383,10 +2383,10 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { if let Some(lt_idx) = lifetime_idx { if lt_idx > binder_level_idx { let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name); - return tcx.mk_region(ty::ReLateBound( + return tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: br.var, kind }, - )); + ); } } @@ -2398,10 +2398,10 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { if let Some(lt_idx) = lifetime_idx { if lt_idx > binder_level_idx { let kind = ty::BrNamed(def_id, name); - return tcx.mk_region(ty::ReLateBound( + return tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: br.var, kind }, - )); + ); } } @@ -2411,10 +2411,10 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { if let Some(lt_idx) = lifetime_idx { if lt_idx > binder_level_idx { let kind = br.kind; - return tcx.mk_region(ty::ReLateBound( + return tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: br.var, kind }, - )); + ); } } @@ -2426,7 +2426,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { start_or_continue(&mut self, "for<", ", "); do_continue(&mut self, name); } - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) + tcx.mk_re_late_bound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }) }; let mut folder = RegionFolder { tcx, diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index ed54aa96f5b..f1128d7c8bb 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -6,7 +6,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use crate::middle::lib_features::LibFeatures; use crate::middle::privacy::EffectiveVisibilities; -use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes}; +use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c613b3627f2..85c63131bff 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1187,7 +1187,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> { if index == self.index { Err(()) } else { - Ok(self.interner().mk_region(ty::ReLateBound(index.shifted_out(1), bv))) + Ok(self.interner().mk_re_late_bound(index.shifted_out(1), bv)) } } else { r.try_super_fold_with(self) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a6ab7440c8e..6b4a6a17aef 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -267,13 +267,11 @@ pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>; impl<'tcx> InternalSubsts<'tcx> { /// Checks whether all elements of this list are types, if so, transmute. pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> { - if self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))) { + self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))).then(|| { assert_eq!(TYPE_TAG, 0); // SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`. - Some(unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) }) - } else { - None - } + unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) } + }) } /// Interpret these substitutions as the substitutions of a closure type. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 35831ff8706..7f5ffe6f27a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -564,14 +564,14 @@ impl<'tcx> TyCtxt<'tcx> { self, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - env_region: ty::RegionKind<'tcx>, + env_region: ty::Region<'tcx>, ) -> Option<Ty<'tcx>> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind = closure_kind_ty.to_opt_closure_kind()?; let env_ty = match closure_kind { - ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty), - ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty), + ty::ClosureKind::Fn => self.mk_imm_ref(env_region, closure_ty), + ty::ClosureKind::FnMut => self.mk_mut_ref(env_region, closure_ty), ty::ClosureKind::FnOnce => closure_ty, }; Some(env_ty) diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 38b1fa91d0a..dac9bf0a883 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // See the notes for `ExprKind::Array` in `as_rvalue` and for // `ExprKind::Borrow` above. let is_union = adt_def.is_union(); - let active_field_index = if is_union { Some(fields[0].name.index()) } else { None }; + let active_field_index = is_union.then(|| fields[0].name.index()); let scope = this.local_scope(); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index ad7a568a231..8859f5002e4 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -563,14 +563,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let not_contained = self.values_not_contained_in_range(&*range, options).unwrap_or(false); - if not_contained { + not_contained.then(|| { // No switch values are contained in the pattern range, // so the pattern can be matched only if this test fails. - let otherwise = options.len(); - Some(otherwise) - } else { - None - } + options.len() + }) } (&TestKind::SwitchInt { .. }, _) => None, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 10df4b22952..c9fa599f52d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -140,7 +140,7 @@ impl<'tcx> Cx<'tcx> { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_region = self.tcx.mk_re_late_bound(ty::INNERMOST, br); let closure_env_ty = self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap(); let liberated_closure_env_ty = self.tcx.erase_late_bound_regions( diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 977c4b4ae6c..e5b7d685c49 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -172,7 +172,7 @@ impl IntRange { ty: Ty<'tcx>, end: &RangeEnd, ) -> Option<IntRange> { - if Self::is_integral(ty) { + Self::is_integral(ty).then(|| { // Perform a shift if the underlying types are signed, // which makes the interval arithmetic simpler. let bias = IntRange::signed_bias(tcx, ty); @@ -182,10 +182,8 @@ impl IntRange { // This should have been caught earlier by E0030. bug!("malformed range pattern: {}..={}", lo, (hi - offset)); } - Some(IntRange { range: lo..=(hi - offset), bias }) - } else { - None - } + IntRange { range: lo..=(hi - offset), bias } + }) } // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 47ca0a87fcc..41306dd80fb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -203,11 +203,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if !lower_overflow && !higher_overflow { self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper { span, - teach: if self.tcx.sess.teach(&error_code!(E0030)) { - Some(()) - } else { - None - }, + teach: self.tcx.sess.teach(&error_code!(E0030)).then_some(()), }); } PatKind::Wild diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 2890fa32cc9..633a5674f1f 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -254,13 +254,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { ) { // Compute the place that we are storing to, if any let destination = match &statement.kind { - StatementKind::Assign(assign) => { - if assign.1.is_safe_to_remove() { - Some(assign.0) - } else { - None - } - } + StatementKind::Assign(assign) => assign.1.is_safe_to_remove().then_some(assign.0), StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { Some(**place) } diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index aa19b1fdb5e..66d32b954e4 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -111,11 +111,9 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { /// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type. fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option<Ty<'tcx>> { if let ty::PredicateKind::Clause(ty::Clause::Trait(predicate)) = bound { - if self.tcx.is_diagnostic_item(sym::Pointer, predicate.def_id()) { - Some(predicate.trait_ref.self_ty()) - } else { - None - } + self.tcx + .is_diagnostic_item(sym::Pointer, predicate.def_id()) + .then(|| predicate.trait_ref.self_ty()) } else { None } diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 194c41c6ba1..2ca33a624e2 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -3,7 +3,7 @@ use crate::MirPass; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; -use rustc_middle::ty::{self, AdtDef, Const, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt}; use rustc_session::Session; use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; @@ -141,10 +141,7 @@ impl EnumSizeOpt { self.candidate(tcx, param_env, ty, &mut alloc_cache)?; let alloc = tcx.global_alloc(alloc_id).unwrap_memory(); - let tmp_ty = tcx.mk_ty(ty::Array( - tcx.types.usize, - Const::from_target_usize(tcx, num_variants as u64), - )); + let tmp_ty = tcx.mk_array(tcx.types.usize, num_variants as u64); let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); let store_live = Statement { diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 65c15d9c674..c1e7f62dea5 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -2,7 +2,7 @@ use either::Either; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; -use rustc_middle::middle::resolve_lifetime::Set1; +use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{ParamEnv, TyCtxt}; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0cb88f3c3a9..a74f408d774 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1283,22 +1283,16 @@ impl<'a> Parser<'a> { } fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> { - if self.check(&token::OpenDelim(Delimiter::Parenthesis)) + let delimited = self.check(&token::OpenDelim(Delimiter::Parenthesis)) || self.check(&token::OpenDelim(Delimiter::Bracket)) - || self.check(&token::OpenDelim(Delimiter::Brace)) - { - match self.parse_token_tree() { - // We've confirmed above that there is a delimiter so unwrapping is OK. - TokenTree::Delimited(dspan, delim, tokens) => Some(DelimArgs { - dspan, - delim: MacDelimiter::from_token(delim).unwrap(), - tokens, - }), - _ => unreachable!(), - } - } else { - None - } + || self.check(&token::OpenDelim(Delimiter::Brace)); + + delimited.then(|| { + // We've confirmed above that there is a delimiter so unwrapping is OK. + let TokenTree::Delimited(dspan, delim, tokens) = self.parse_token_tree() else { unreachable!() }; + + DelimArgs { dspan, delim: MacDelimiter::from_token(delim).unwrap(), tokens } + }) } fn parse_or_use_outer_attributes( diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 2e706a00cf7..49959a8981c 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -404,7 +404,7 @@ impl<'a> Parser<'a> { let is_first_invocation = style == PathStyle::Expr; // Take a snapshot before attempting to parse - we can restore this later. - let snapshot = if is_first_invocation { Some(self.clone()) } else { None }; + let snapshot = is_first_invocation.then(|| self.clone()); debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)"); match self.parse_angle_args(ty_generics) { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 5b92563fc35..4f4252b532e 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -450,8 +450,7 @@ impl<'a> Parser<'a> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { let and_span = self.prev_token.span; - let mut opt_lifetime = - if self.check_lifetime() { Some(self.expect_lifetime()) } else { None }; + let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime()); let mut mutbl = self.parse_mutability(); if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires @@ -871,7 +870,7 @@ impl<'a> Parser<'a> { None }; - let maybe = if self.eat(&token::Question) { Some(self.prev_token.span) } else { None }; + let maybe = self.eat(&token::Question).then_some(self.prev_token.span); Ok(BoundModifiers { maybe, maybe_const }) } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 34a4fd02ea6..8a3cedfee79 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -835,7 +835,7 @@ impl<'a> Parser<'a> { ); } - if found { Some(cur) } else { None } + found.then_some(cur) } fn suggest_format(&mut self) { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 225095948af..7cff8996d24 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -18,7 +18,7 @@ use rustc_hir::{ }; use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; +use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnv, TyCtxt}; diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 10ffa87efe3..0ae7096642c 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -32,11 +32,8 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) { if original_def_id != item_def_id { let orig_span = tcx.hir().span_if_local(original_def_id); - let orig_crate_name = if orig_span.is_some() { - None - } else { - Some(tcx.crate_name(original_def_id.krate)) - }; + let orig_crate_name = + orig_span.is_none().then(|| tcx.crate_name(original_def_id.krate)); match tcx.hir().span_if_local(item_def_id) { Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 7299fc9705c..13a576014a2 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -281,7 +281,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { self.recurse_with_stability_attrs( depr.map(|(d, _)| DeprecationEntry::local(d, def_id)), stab, - if inherit_const_stability.yes() { const_stab } else { None }, + inherit_const_stability.yes().then_some(const_stab).flatten(), visit_children, ); } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4675bd79c46..0a0c94e1dfb 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -270,10 +270,11 @@ where | ty::Ref(..) | ty::FnPtr(..) | ty::Param(..) + | ty::Bound(..) | ty::Error(_) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {} - ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => { + ty::Placeholder(..) | ty::Infer(..) => { bug!("unexpected type: {:?}", ty) } } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a81595b2420..29513df460f 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -242,8 +242,7 @@ impl<K: DepKind + Encodable<FileEncoder>> GraphEncoder<K> { record_graph: bool, record_stats: bool, ) -> Self { - let record_graph = - if record_graph { Some(Lock::new(DepGraphQuery::new(prev_node_count))) } else { None }; + let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count))); let status = Lock::new(EncoderState::new(encoder, record_stats)); GraphEncoder { status, record_graph } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d3bcbbabf55..324de7461cd 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -21,7 +21,7 @@ use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate}; -use rustc_middle::middle::resolve_lifetime::Set1; +use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::ty::DefIdTree; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; @@ -2505,7 +2505,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let res = match kind { ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()), - NormalRibKind => Res::Err, + NormalRibKind => { + if self.r.session.features_untracked().non_lifetime_binders { + Res::Def(def_kind, def_id.to_def_id()) + } else { + Res::Err + } + } _ => span_bug!(param.ident.span, "Unexpected rib kind {:?}", kind), }; self.r.record_partial_res(param.id, PartialRes::new(res)); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a3195a64366..5205d055cf9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1700,11 +1700,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let crate_mod = Res::Def(DefKind::Mod, crate_id.as_def_id()); - if filter_fn(crate_mod) { - Some(TypoSuggestion::typo_from_ident(*ident, crate_mod)) - } else { - None - } + filter_fn(crate_mod).then(|| { + TypoSuggestion::typo_from_ident(*ident, crate_mod) + }) }) })); diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index a967f4b940c..3425e24585c 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -344,7 +344,7 @@ fn preprocess_link(link: &str) -> String { let link = link.strip_suffix("()").unwrap_or(link); let link = link.strip_suffix("{}").unwrap_or(link); let link = link.strip_suffix("[]").unwrap_or(link); - let link = if link != "!" { link.strip_suffix("!").unwrap_or(link) } else { link }; + let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link }; strip_generics_from_path(link).unwrap_or_else(|_| link.to_string()) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e8bc19f88e3..4da6acad2c0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2544,7 +2544,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } // Only use this directory if it has a file we can expect to always find. - if candidate.join("library/std/src/lib.rs").is_file() { Some(candidate) } else { None } + candidate.join("library/std/src/lib.rs").is_file().then_some(candidate) }; let working_dir = std::env::current_dir().unwrap_or_else(|e| { diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index c851145440b..bd32adbbdbb 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -4,7 +4,7 @@ use crate::cgu_reuse_tracker::CguReuse; use crate::parse::ParseSess; use rustc_ast::token; use rustc_ast::util::literal::LitError; -use rustc_errors::MultiSpan; +use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan}; use rustc_macros::Diagnostic; use rustc_span::{Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; @@ -27,12 +27,22 @@ pub struct CguNotRecorded<'a> { pub cgu_name: &'a str, } -#[derive(Diagnostic)] -#[diag(session_feature_gate_error, code = "E0658")] -pub struct FeatureGateError<'a> { - #[primary_span] +pub struct FeatureGateError { pub span: MultiSpan, - pub explain: &'a str, + pub explain: DiagnosticMessage, +} + +impl<'a, T: EmissionGuarantee> IntoDiagnostic<'a, T> for FeatureGateError { + #[track_caller] + fn into_diagnostic( + self, + handler: &'a rustc_errors::Handler, + ) -> rustc_errors::DiagnosticBuilder<'a, T> { + let mut diag = handler.struct_diagnostic(self.explain); + diag.set_span(self.span); + diag.code(error_code!(E0658)); + diag + } } #[derive(Subdiagnostic)] @@ -322,11 +332,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: .take_while(|c| *c != 'i' && *c != 'u') .all(|c| c.to_digit(base).is_some()); - if valid { - Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..])) - } else { - None - } + valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..])) } let token::Lit { kind, symbol, suffix, .. } = lit; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index b6a328908ce..2075ed57a94 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -217,7 +217,7 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> { // Look for the target rustlib directory in the suspected sysroot. let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy"); rustlib_path.pop(); // pop off the dummy target. - if rustlib_path.exists() { Some(p) } else { None } + rustlib_path.exists().then_some(p) } None => None, } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d9e68320f8f..c784582012a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -809,7 +809,7 @@ mod parse { if v.is_some() { let mut bool_arg = None; if parse_opt_bool(&mut bool_arg, v) { - *slot = if bool_arg.unwrap() { Some(MirSpanview::Statement) } else { None }; + *slot = bool_arg.unwrap().then_some(MirSpanview::Statement); return true; } } @@ -850,7 +850,7 @@ mod parse { if v.is_some() { let mut bool_arg = None; if parse_opt_bool(&mut bool_arg, v) { - *slot = if bool_arg.unwrap() { Some(InstrumentCoverage::All) } else { None }; + *slot = bool_arg.unwrap().then_some(InstrumentCoverage::All); return true; } } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 2aa8ca9e4a9..cbdcc5581e5 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -88,7 +88,7 @@ pub fn feature_err<'a>( sess: &'a ParseSess, feature: Symbol, span: impl Into<MultiSpan>, - explain: &str, + explain: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { feature_err_issue(sess, feature, span, GateIssue::Language, explain) } @@ -103,7 +103,7 @@ pub fn feature_err_issue<'a>( feature: Symbol, span: impl Into<MultiSpan>, issue: GateIssue, - explain: &str, + explain: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let span = span.into(); @@ -114,7 +114,7 @@ pub fn feature_err_issue<'a>( .map(|err| err.cancel()); } - let mut err = sess.create_err(FeatureGateError { span, explain }); + let mut err = sess.create_err(FeatureGateError { span, explain: explain.into() }); add_feature_diagnostics_for_issue(&mut err, sess, feature, issue); err } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index cdda052f529..2340d501d5a 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -299,7 +299,7 @@ impl DefId { #[inline] pub fn as_local(self) -> Option<LocalDefId> { - if self.is_local() { Some(LocalDefId { local_def_index: self.index }) } else { None } + self.is_local().then(|| LocalDefId { local_def_index: self.index }) } #[inline] @@ -320,7 +320,7 @@ impl DefId { #[inline] pub fn as_crate_root(self) -> Option<CrateNum> { - if self.is_crate_root() { Some(self.krate) } else { None } + self.is_crate_root().then_some(self.krate) } #[inline] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 56835a2466a..37d2aea42ad 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1016,6 +1016,7 @@ symbols! { non_ascii_idents, non_exhaustive, non_exhaustive_omitted_patterns_lint, + non_lifetime_binders, non_modrs_mods, nontemporal_store, noop_method_borrow, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 547a5907660..d81722e59a6 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -244,8 +244,7 @@ fn compute_symbol_name<'tcx>( // project. let avoid_cross_crate_conflicts = is_generic(substs) || is_globally_shared_function; - let instantiating_crate = - if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None }; + let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate); // Pick the crate responsible for the symbol mangling version, which has to: // 1. be stable for each instance, whether it's being defined or imported diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 52ed64868c0..91d96655b64 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -60,7 +60,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> Option<(DefId, SubstsRef<'tcx>)> { let tcx = self.tcx; let param_env = obligation.param_env; - let trait_ref = tcx.erase_late_bound_regions(trait_ref); + let trait_ref = self.instantiate_binder_with_placeholders(trait_ref); let trait_self_ty = trait_ref.self_ty(); let mut self_match_impls = vec![]; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 135232d1b20..45a4cf2a083 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -82,11 +82,8 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> { upvars.iter().find_map(|(upvar_id, upvar)| { let upvar_ty = typeck_results.node_type(*upvar_id); let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty); - if ty_matches(ty::Binder::dummy(upvar_ty)) { - Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) - } else { - None - } + ty_matches(ty::Binder::dummy(upvar_ty)) + .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span)) }) }) } @@ -770,15 +767,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.param_env, real_trait_pred_and_ty, ); - if obligations + let may_hold = obligations .iter() .chain([&obligation]) .all(|obligation| self.predicate_may_hold(obligation)) - { - Some(steps) - } else { - None - } + .then_some(steps); + + may_hold }) { if steps > 0 { @@ -1061,7 +1056,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); - let ty = self.tcx.erase_late_bound_regions(self_ty); + let ty = self.instantiate_binder_with_placeholders(self_ty); let Some(generics) = self.tcx.hir().get_generics(obligation.cause.body_id) else { return false }; let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false }; let ty::Param(param) = inner_ty.kind() else { return false }; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 41ee8cd9d3f..2d299486ee6 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -523,16 +523,14 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { - if pred.visit_with(&mut visitor).is_continue() { - Some(Obligation::new( + pred.visit_with(&mut visitor).is_continue().then(|| { + Obligation::new( tcx, ObligationCause::dummy_with_span(*span), param_env, ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs), - )) - } else { - None - } + ) + }) }); let infcx = tcx.infer_ctxt().ignoring_regions().build(); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 7ef39b20107..4963f2d75fa 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -307,7 +307,7 @@ fn predicate_references_self<'tcx>( match predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => { // In the case of a trait predicate, we can skip the "self" type. - if data.trait_ref.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None } + data.trait_ref.substs[1..].iter().any(has_self_ty).then_some(sp) } ty::PredicateKind::Clause(ty::Clause::Projection(ref data)) => { // And similarly for projections. This should be redundant with @@ -325,7 +325,7 @@ fn predicate_references_self<'tcx>( // // This is ALT2 in issue #56288, see that for discussion of the // possible alternatives. - if data.projection_ty.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None } + data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp) } ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"), @@ -527,8 +527,7 @@ fn virtual_call_violation_for_method<'tcx>( } } - let trait_object_ty = - object_ty_for_trait(tcx, trait_def_id, tcx.mk_region(ty::ReStatic)); + let trait_object_ty = object_ty_for_trait(tcx, trait_def_id, tcx.lifetimes.re_static); // e.g., `Rc<dyn Trait>` let trait_object_receiver = diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a380d4697ea..7ddffe595be 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -767,7 +767,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderRegion { universe, name: br.kind }; self.mapped_regions.insert(p, br); - self.infcx.tcx.mk_region(ty::RePlaceholder(p)) + self.infcx.tcx.mk_re_placeholder(p) } _ => r, } @@ -888,7 +888,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.interner().mk_region(ty::ReLateBound(db, *replace_var)) + self.interner().mk_re_late_bound(db, *replace_var) } None => r1, } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index 0d42cd8250a..21ef4e24fdb 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -21,11 +21,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>, ) -> Option<Self::QueryResponse> { - if trivial_dropck_outlives(tcx, key.value.dropped_ty) { - Some(DropckOutlivesResult::default()) - } else { - None - } + trivial_dropck_outlives(tcx, key.value.dropped_ty).then(DropckOutlivesResult::default) } fn perform_query( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index e9f7c3bc4cc..dae602908a3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -396,7 +396,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // still be provided by a manual implementation for // this trait and type. } - ty::Param(..) | ty::Alias(ty::Projection, ..) => { + ty::Param(..) + | ty::Alias(ty::Projection, ..) + | ty::Placeholder(..) + | ty::Bound(..) => { // In these cases, we don't know what the actual // type is. Therefore, we cannot break it down // into its constituent types. So we don't @@ -448,6 +451,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); self.infcx.probe(|_snapshot| { + if obligation.has_non_region_late_bound() { + return; + } + // The code below doesn't care about regions, and the // self-ty here doesn't escape this probe, so just erase // any LBR. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index dc5bcb48cad..9770813e86d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -540,13 +540,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); let bound_var = ty::BoundVariableKind::Region(kind); bound_vars.push(bound_var); - tcx.mk_region(ty::ReLateBound( + tcx.mk_re_late_bound( ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind, }, - )) + ) .into() } GenericParamDefKind::Const { .. } => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fc9678233c3..27feedc48be 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -378,11 +378,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = trait_ref.self_ty(); let (trait_desc, self_desc) = with_no_trimmed_paths!({ let trait_desc = trait_ref.print_only_trait_path().to_string(); - let self_desc = if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }; + let self_desc = + self_ty.has_concrete_skeleton().then(|| self_ty.to_string()); (trait_desc, self_desc) }); let cause = if let Conflict::Upstream = conflict { @@ -3023,7 +3020,7 @@ fn bind_generator_hidden_types_above<'tcx>( kind: ty::BrAnon(counter, None), }; counter += 1; - r = tcx.mk_region(ty::ReLateBound(current_depth, br)); + r = tcx.mk_re_late_bound(current_depth, br); } r }) diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 0f9196de4fb..c3dcd64b2c2 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -113,7 +113,7 @@ impl<'tcx> ChildrenExt<'tcx> for Children { // Only report the `Self` type if it has at least // some outer concrete shell; otherwise, it's // not adding much information. - self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } else { None }, + self_ty: self_ty.has_concrete_skeleton().then_some(self_ty), intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes, involves_placeholder: overlap.involves_placeholder, } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 20725c656de..bb2b3ac6609 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -732,7 +732,7 @@ fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { var: ty::BoundVar::from_usize(substs.len()), kind: ty::BrAnon(substs.len() as u32, None), }; - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() + tcx.mk_re_late_bound(ty::INNERMOST, br).into() } ty::GenericParamDefKind::Const { .. } => tcx diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 2978fc4ed8c..9abbd0c5b34 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -521,8 +521,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'tcx>> { fn lower_into(self, interner: RustInterner<'tcx>) -> Region<'tcx> { - let kind = match self.data(interner) { - chalk_ir::LifetimeData::BoundVar(var) => ty::ReLateBound( + let tcx = interner.tcx; + match self.data(interner) { + chalk_ir::LifetimeData::BoundVar(var) => tcx.mk_re_late_bound( ty::DebruijnIndex::from_u32(var.debruijn.depth()), ty::BoundRegion { var: ty::BoundVar::from_usize(var.index), @@ -530,15 +531,14 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t }, ), chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), - chalk_ir::LifetimeData::Placeholder(p) => ty::RePlaceholder(ty::Placeholder { + chalk_ir::LifetimeData::Placeholder(p) => tcx.mk_re_placeholder(ty::Placeholder { universe: ty::UniverseIndex::from_usize(p.ui.counter), name: ty::BoundRegionKind::BrAnon(p.idx as u32, None), }), - chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static, - chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased, + chalk_ir::LifetimeData::Static => tcx.lifetimes.re_static, + chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased, chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, - }; - interner.tcx.mk_region(kind) + } } } @@ -1025,7 +1025,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> { ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { Some(idx) => { let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx, None) }; - return self.tcx.mk_region(ty::ReLateBound(index, new_br)); + return self.tcx.mk_re_late_bound(index, new_br); } None => panic!("Missing `BrNamed`."), }, @@ -1107,7 +1107,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { var: ty::BoundVar::from_u32(*idx), kind: ty::BrAnon(*idx, None), }; - self.tcx.mk_region(ty::ReLateBound(self.binder_index, br)) + self.tcx.mk_re_late_bound(self.binder_index, br) } None => { let idx = self.named_regions.len() as u32; @@ -1116,7 +1116,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { kind: ty::BrAnon(idx, None), }; self.named_regions.insert(_re.def_id, idx); - self.tcx.mk_region(ty::ReLateBound(self.binder_index, br)) + self.tcx.mk_re_late_bound(self.binder_index, br) } }, diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index ad5527f5a77..8b32c0119e0 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -70,7 +70,7 @@ fn fn_sig_for_fn_abi<'tcx>( var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BoundRegionKind::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br); let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); let sig = sig.skip_binder(); @@ -95,8 +95,7 @@ fn fn_sig_for_fn_abi<'tcx>( var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BoundRegionKind::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); - let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); + let env_ty = tcx.mk_mut_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), ty); let pin_did = tcx.require_lang_item(LangItem::Pin, None); let pin_adt_ref = tcx.adt_def(pin_did); @@ -207,11 +206,8 @@ fn fn_abi_of_instance<'tcx>( let sig = fn_sig_for_fn_abi(tcx, instance, param_env); - let caller_location = if instance.def.requires_caller_location(tcx) { - Some(tcx.caller_location_ty()) - } else { - None - }; + let caller_location = + instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()); fn_abi_new_uncached( &LayoutCx { tcx, param_env }, diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 5a0b8594104..9e3e13e7004 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3502,8 +3502,10 @@ pub trait Iterator { } } - /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those - /// of another. + /// [Lexicographically](Ord#lexicographical-comparison) compares the [`PartialOrd`] elements of + /// this [`Iterator`] with those of another. The comparison works like short-circuit + /// evaluation, returning a result without comparing the remaining elements. + /// As soon as an order can be determined, the evaluation stops and a result is returned. /// /// # Examples /// @@ -3513,9 +3515,25 @@ pub trait Iterator { /// assert_eq!([1.].iter().partial_cmp([1.].iter()), Some(Ordering::Equal)); /// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less)); /// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater)); + /// ``` /// + /// For floating-point numbers, NaN does not have a total order and will result + /// in `None` when compared: + /// + /// ``` /// assert_eq!([f64::NAN].iter().partial_cmp([1.].iter()), None); /// ``` + /// + /// The results are determined by the order of evaluation. + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// assert_eq!([1.0, f64::NAN].iter().partial_cmp([2.0, f64::NAN].iter()), Some(Ordering::Less)); + /// assert_eq!([2.0, f64::NAN].iter().partial_cmp([1.0, f64::NAN].iter()), Some(Ordering::Greater)); + /// assert_eq!([f64::NAN, 1.0].iter().partial_cmp([f64::NAN, 2.0].iter()), None); + /// ``` + /// #[stable(feature = "iter_order", since = "1.5.0")] fn partial_cmp<I>(self, other: I) -> Option<Ordering> where diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 1675ed158c9..ff7821fb9ff 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -58,9 +58,10 @@ fn args(builder: &Builder<'_>) -> Vec<String> { clippy_lint_warn.iter().for_each(|v| clippy_lint_levels.push(format!("-W{}", v))); clippy_lint_forbid.iter().for_each(|v| clippy_lint_levels.push(format!("-F{}", v))); args.extend(clippy_lint_levels); + args.extend(builder.config.free_args.clone()); args } else { - vec![] + builder.config.free_args.clone() } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e5fad538969..cd027a4abb7 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -97,6 +97,10 @@ pub struct Config { pub cmd: Subcommand, pub incremental: bool, pub dry_run: DryRun, + /// Arguments appearing after `--` to be forwarded to tools, + /// e.g. `--fix-broken` or test arguments. + pub free_args: Vec<String>, + /// `None` if we shouldn't download CI compiler artifacts, or the commit to download if we should. #[cfg(not(test))] download_rustc_commit: Option<String>, @@ -866,6 +870,7 @@ impl Config { config.keep_stage = flags.keep_stage; config.keep_stage_std = flags.keep_stage_std; config.color = flags.color; + config.free_args = flags.free_args.clone().unwrap_or_default(); if let Some(value) = flags.deny_warnings { config.deny_warnings = value; } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index ff927ed561b..f07e710a9e6 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -80,6 +80,10 @@ pub struct Flags { pub llvm_profile_generate: bool, pub llvm_bolt_profile_generate: bool, pub llvm_bolt_profile_use: Option<String>, + + /// Arguments appearing after `--` to be forwarded to tools, + /// e.g. `--fix-broken` or test arguments. + pub free_args: Option<Vec<String>>, } #[derive(Debug)] @@ -157,6 +161,12 @@ impl Default for Subcommand { impl Flags { pub fn parse(args: &[String]) -> Flags { + let (args, free_args) = if let Some(pos) = args.iter().position(|s| s == "--") { + let (args, free) = args.split_at(pos); + (args, Some(free[1..].to_vec())) + } else { + (args, None) + }; let mut subcommand_help = String::from( "\ Usage: x.py <subcommand> [options] [<paths>...] @@ -709,6 +719,7 @@ Arguments: llvm_profile_generate: matches.opt_present("llvm-profile-generate"), llvm_bolt_profile_generate: matches.opt_present("llvm-bolt-profile-generate"), llvm_bolt_profile_use: matches.opt_str("llvm-bolt-profile-use"), + free_args, } } } diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index e0280854541..e14440f57a8 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -183,6 +183,7 @@ impl Step for Miri { // Forward arguments. miri.arg("--").arg("--target").arg(target.rustc_target_arg()); miri.args(builder.config.cmd.args()); + miri.args(&builder.config.free_args); // miri tests need to know about the stage sysroot miri.env("MIRI_SYSROOT", &miri_sysroot); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f8835fe11a8..9cd6107b43a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1588,6 +1588,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the .collect(); test_args.append(&mut builder.config.cmd.test_args()); + test_args.extend(builder.config.free_args.iter().map(|s| s.as_str())); // On Windows, replace forward slashes in test-args by backslashes // so the correct filters are passed to libtest diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 65736bb16fc..10af968e34f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -11,6 +11,8 @@ pub(crate) mod types; pub(crate) mod utils; use rustc_ast as ast; +use rustc_ast::token::{Token, TokenKind}; +use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_hir as hir; @@ -19,7 +21,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE}; use rustc_hir::PredicateOrigin; use rustc_hir_analysis::hir_ty_to_ty; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; -use rustc_middle::middle::resolve_lifetime as rl; +use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::ty::fold::ir::TypeFolder; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::TypeVisitable; @@ -198,11 +200,11 @@ fn clean_poly_trait_ref_with_bindings<'tcx>( } fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { - let def = cx.tcx.named_region(lifetime.hir_id); + let def = cx.tcx.named_bound_var(lifetime.hir_id); if let Some( - rl::Region::EarlyBound(node_id) - | rl::Region::LateBound(_, _, node_id) - | rl::Region::Free(_, node_id), + rbv::ResolvedArg::EarlyBound(node_id) + | rbv::ResolvedArg::LateBound(_, _, node_id) + | rbv::ResolvedArg::Free(_, node_id), ) = def { if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() { @@ -2079,8 +2081,8 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> { fn visit_item(&mut self, item: &'hir hir::Item<'hir>) { if self.item.is_none() && item.ident == self.looking_for - && matches!(item.kind, hir::ItemKind::Use(_, _)) - || item.owner_id.def_id == self.target_def_id + && (matches!(item.kind, hir::ItemKind::Use(_, _)) + || item.owner_id.def_id == self.target_def_id) { self.item = Some(item); } @@ -2096,34 +2098,149 @@ fn get_all_import_attributes<'hir>( tcx: TyCtxt<'hir>, target_def_id: LocalDefId, attributes: &mut Vec<ast::Attribute>, + is_inline: bool, ) { let hir_map = tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visited = FxHashSet::default(); // If the item is an import and has at least a path with two parts, we go into it. - while let hir::ItemKind::Use(path, _) = item.kind && - path.segments.len() > 1 && - let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res && - visited.insert(def_id) - { - if let Some(hir::Node::Item(parent_item)) = hir_map.get_if_local(def_id) { - // We add the attributes from this import into the list. - attributes.extend_from_slice(hir_map.attrs(item.hir_id())); - // We get the `Ident` we will be looking for into `item`. - let looking_for = path.segments[path.segments.len() - 1].ident; - visitor.reset(looking_for); - hir::intravisit::walk_item(&mut visitor, parent_item); - if let Some(i) = visitor.item { - item = i; - } else { - break; + while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) { + // We add the attributes from this import into the list. + add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + + let def_id = if path.segments.len() > 1 { + match path.segments[path.segments.len() - 2].res { + hir::def::Res::Def(_, def_id) => def_id, + _ => break, + } + } else { + // If the path doesn't have a parent, then the parent is the current module. + tcx.parent(item.owner_id.def_id.to_def_id()) + }; + + let Some(parent) = hir_map.get_if_local(def_id) else { break }; + + // We get the `Ident` we will be looking for into `item`. + let looking_for = path.segments[path.segments.len() - 1].ident; + visitor.reset(looking_for); + + match parent { + hir::Node::Item(parent_item) => { + hir::intravisit::walk_item(&mut visitor, parent_item); + } + hir::Node::Crate(m) => { + hir::intravisit::walk_mod( + &mut visitor, + m, + tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()), + ); } + _ => break, + } + if let Some(i) = visitor.item { + item = i; } else { break; } } } +fn filter_tokens_from_list( + args_tokens: TokenStream, + should_retain: impl Fn(&TokenTree) -> bool, +) -> Vec<TokenTree> { + let mut tokens = Vec::with_capacity(args_tokens.len()); + let mut skip_next_comma = false; + for token in args_tokens.into_trees() { + match token { + TokenTree::Token(Token { kind: TokenKind::Comma, .. }, _) if skip_next_comma => { + skip_next_comma = false; + } + token if should_retain(&token) => { + skip_next_comma = false; + tokens.push(token); + } + _ => { + skip_next_comma = true; + } + } + } + tokens +} + +/// When inlining items, we merge its attributes (and all the reexports attributes too) with the +/// final reexport. For example: +/// +/// ```ignore (just an example) +/// #[doc(hidden, cfg(feature = "foo"))] +/// pub struct Foo; +/// +/// #[doc(cfg(feature = "bar"))] +/// #[doc(hidden, no_inline)] +/// pub use Foo as Foo1; +/// +/// #[doc(inline)] +/// pub use Foo2 as Bar; +/// ``` +/// +/// So `Bar` at the end will have both `cfg(feature = "...")`. However, we don't want to merge all +/// attributes so we filter out the following ones: +/// * `doc(inline)` +/// * `doc(no_inline)` +/// * `doc(hidden)` +fn add_without_unwanted_attributes( + attrs: &mut Vec<ast::Attribute>, + new_attrs: &[ast::Attribute], + is_inline: bool, +) { + // If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything. + if !is_inline { + attrs.extend_from_slice(new_attrs); + return; + } + for attr in new_attrs { + let mut attr = attr.clone(); + match attr.kind { + ast::AttrKind::Normal(ref mut normal) => { + if let [ident] = &*normal.item.path.segments && + let ident = ident.ident.name && + ident == sym::doc + { + match normal.item.args { + ast::AttrArgs::Delimited(ref mut args) => { + let tokens = + filter_tokens_from_list(args.tokens.clone(), |token| { + !matches!( + token, + TokenTree::Token( + Token { + kind: TokenKind::Ident( + sym::hidden | sym::inline | sym::no_inline, + _, + ), + .. + }, + _, + ), + ) + }); + args.tokens = TokenStream::new(tokens); + attrs.push(attr); + } + ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => { + attrs.push(attr); + continue; + } + } + } + } + ast::AttrKind::DocComment(..) => { + attrs.push(attr); + } + } + } +} + fn clean_maybe_renamed_item<'tcx>( cx: &mut DocContext<'tcx>, item: &hir::Item<'tcx>, @@ -2212,19 +2329,20 @@ fn clean_maybe_renamed_item<'tcx>( { // First, we add the attributes from the current import. extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id())); + let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some(); // Then we get all the various imports' attributes. - get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs); + get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline); + add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline); + } else { + // We only keep the item's attributes. + extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id)); } - let mut item = if !extra_attrs.is_empty() { - extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id)); - let attrs = Attributes::from_ast(&extra_attrs); - let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); + let attrs = Attributes::from_ast(&extra_attrs); + let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); - Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg) - } else { - Item::from_def_id_and_parts(def_id, Some(name), kind, cx) - }; + let mut item = + Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg); item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id()); vec![item] }) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1ed0b0bc2d5..aa406f30cbe 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -361,7 +361,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( for _ in 0..padding_amout { br_with_padding.push_str(" "); } - let where_preds = where_preds.to_string().replace("\n", &br_with_padding); + let where_preds = where_preds.to_string().replace('\n', &br_with_padding); if ending == Ending::Newline { let mut clause = " ".repeat(indent.saturating_sub(1)); @@ -1419,12 +1419,12 @@ impl clean::FnDecl { format!( "({pad}{args}{close}){arrow}", pad = if self.inputs.values.is_empty() { "" } else { &full_pad }, - args = args.replace("\n", &full_pad), + args = args.replace('\n', &full_pad), close = close_pad, arrow = arrow ) } else { - format!("({args}){arrow}", args = args.replace("\n", " "), arrow = arrow) + format!("({args}){arrow}", args = args.replace('\n', " "), arrow = arrow) }; write!(f, "{}", output) diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index d88409c356e..fc550936165 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -505,13 +505,13 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio if let FnRetTy::Return(ty) = sig.decl.output && let Some((out, Mutability::Mut, _)) = get_ref_lm(ty) { - let out_region = cx.tcx.named_region(out.hir_id); + let out_region = cx.tcx.named_bound_var(out.hir_id); let args: Option<Vec<_>> = sig .decl .inputs .iter() .filter_map(get_ref_lm) - .filter(|&(lt, _, _)| cx.tcx.named_region(lt.hir_id) == out_region) + .filter(|&(lt, _, _)| cx.tcx.named_bound_var(lt.hir_id) == out_region) .map(|(_, mutability, span)| (mutability == Mutability::Not).then_some(span)) .collect(); if let Some(args) = args diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index ef3abb9514f..409f7563184 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. const ROOT_ENTRY_LIMIT: usize = 940; -const ISSUES_ENTRY_LIMIT: usize = 2001; +const ISSUES_ENTRY_LIMIT: usize = 1978; fn check_entries(path: &Path, bad: &mut bool) { for dir in Walk::new(&path.join("ui")) { diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs new file mode 100644 index 00000000000..f6c23a1365f --- /dev/null +++ b/tests/rustdoc/reexport-attr-merge.rs @@ -0,0 +1,33 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/59368>. +// The goal is to ensure that `doc(hidden)`, `doc(inline)` and `doc(no_inline)` +// are not copied from an item when inlined. + +#![crate_name = "foo"] +#![feature(doc_cfg)] + +// @has 'foo/index.html' + +#[doc(hidden, cfg(feature = "foo"))] +pub struct Foo; + +#[doc(hidden, no_inline, cfg(feature = "bar"))] +pub use Foo as Foo1; + +#[doc(hidden, inline)] +pub use Foo1 as Foo2; + +// First we ensure that only the reexport `Bar2` and the inlined struct `Bar` +// are inlined. +// @count - '//a[@class="struct"]' 2 +// Then we check that both `cfg` are displayed. +// @has - '//*[@class="stab portability"]' 'foo' +// @has - '//*[@class="stab portability"]' 'bar' +// And finally we check that the only element displayed is `Bar`. +// @has - '//a[@class="struct"]' 'Bar' +#[doc(inline)] +pub use Foo2 as Bar; + +// This one should appear but `Bar2` won't be linked because there is no +// `#[doc(inline)]`. +// @has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;' +pub use Foo2 as Bar2; diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr index 77ea8ef0520..d1b9d7a40b4 100644 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr @@ -7,7 +7,10 @@ LL | fn oom() -> ! { | _-^^^^^^^^^^^^ LL | | loop {} LL | | } - | |_- argument of type `core::alloc::Layout` unexpected + | | - + | | | + | |_unexpected argument of type `core::alloc::Layout` + | help: remove the extra argument | note: function defined here --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4 @@ -15,10 +18,6 @@ note: function defined here LL | fn oom() -> ! { | ^^^ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) -help: remove the extra argument - | -LL | fn oom() -> !() { - | ++ error: aborting due to previous error diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index 062b3768858..c74186285f9 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -16,17 +16,16 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/basic.rs:21:5 | LL | extra(""); - | ^^^^^ -- argument of type `&'static str` unexpected + | ^^^^^ -- + | | + | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/basic.rs:14:4 | LL | fn extra() {} | ^^^^^ -help: remove the extra argument - | -LL | extra(); - | ~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/basic.rs:22:5 diff --git a/tests/ui/argument-suggestions/exotic-calls.stderr b/tests/ui/argument-suggestions/exotic-calls.stderr index 0580e53c510..ff795b507f2 100644 --- a/tests/ui/argument-suggestions/exotic-calls.stderr +++ b/tests/ui/argument-suggestions/exotic-calls.stderr @@ -2,65 +2,61 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:2:5 | LL | t(1i32); - | ^ ---- argument of type `i32` unexpected + | ^ ---- + | | + | unexpected argument of type `i32` + | help: remove the extra argument | note: callable defined here --> $DIR/exotic-calls.rs:1:11 | LL | fn foo<T: Fn()>(t: T) { | ^^^^ -help: remove the extra argument - | -LL | t(); - | ~~ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:7:5 | LL | t(1i32); - | ^ ---- argument of type `i32` unexpected + | ^ ---- + | | + | unexpected argument of type `i32` + | help: remove the extra argument | note: type parameter defined here --> $DIR/exotic-calls.rs:6:11 | LL | fn bar(t: impl Fn()) { | ^^^^^^^^^ -help: remove the extra argument - | -LL | t(); - | ~~ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:16:5 | LL | baz()(1i32) - | ^^^^^ ---- argument of type `i32` unexpected + | ^^^^^ ---- + | | + | unexpected argument of type `i32` + | help: remove the extra argument | note: opaque type defined here --> $DIR/exotic-calls.rs:11:13 | LL | fn baz() -> impl Fn() { | ^^^^^^^^^ -help: remove the extra argument - | -LL | baz()() - | ~~ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:22:5 | LL | x(1i32); - | ^ ---- argument of type `i32` unexpected + | ^ ---- + | | + | unexpected argument of type `i32` + | help: remove the extra argument | note: closure defined here --> $DIR/exotic-calls.rs:21:13 | LL | let x = || {}; | ^^ -help: remove the extra argument - | -LL | x(); - | ~~ error: aborting due to 4 previous errors diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr index 48787b0c352..0911685b428 100644 --- a/tests/ui/argument-suggestions/extra_arguments.stderr +++ b/tests/ui/argument-suggestions/extra_arguments.stderr @@ -2,57 +2,54 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/extra_arguments.rs:7:3 | LL | empty(""); - | ^^^^^ -- argument of type `&'static str` unexpected + | ^^^^^ -- + | | + | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:1:4 | LL | fn empty() {} | ^^^^^ -help: remove the extra argument - | -LL | empty(); - | ~~ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:9:3 | LL | one_arg(1, 1); - | ^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- -help: remove the extra argument - | -LL | one_arg(1); - | ~~~ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:10:3 | LL | one_arg(1, ""); - | ^^^^^^^ -- argument of type `&'static str` unexpected + | ^^^^^^^ ---- + | | | + | | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- -help: remove the extra argument - | -LL | one_arg(1); - | ~~~ error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/extra_arguments.rs:11:3 | LL | one_arg(1, "", 1.0); - | ^^^^^^^ -- --- argument of type `{float}` unexpected + | ^^^^^^^ -- --- unexpected argument of type `{float}` | | - | argument of type `&'static str` unexpected + | unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -61,80 +58,77 @@ LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- help: remove the extra arguments | -LL | one_arg(1); - | ~~~ +LL - one_arg(1, "", 1.0); +LL + one_arg(1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:13:3 | LL | two_arg_same(1, 1, 1); - | ^^^^^^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- -help: remove the extra argument - | -LL | two_arg_same(1, 1); - | ~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:14:3 | LL | two_arg_same(1, 1, 1.0); - | ^^^^^^^^^^^^ --- argument of type `{float}` unexpected + | ^^^^^^^^^^^^ ----- + | | | + | | unexpected argument of type `{float}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- -help: remove the extra argument - | -LL | two_arg_same(1, 1); - | ~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:16:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- -help: remove the extra argument - | -LL | two_arg_diff(1, ""); - | ~~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:17:3 | LL | two_arg_diff(1, "", ""); - | ^^^^^^^^^^^^ -- argument of type `&'static str` unexpected + | ^^^^^^^^^^^^ ---- + | | | + | | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- -help: remove the extra argument - | -LL | two_arg_diff(1, ""); - | ~~~~~~~ error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:18:3 | LL | two_arg_diff(1, 1, "", ""); - | ^^^^^^^^^^^^ - -- argument of type `&'static str` unexpected + | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` | | - | argument of type `{integer}` unexpected + | unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -143,16 +137,17 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- help: remove the extra arguments | -LL | two_arg_diff(1, ""); - | ~~~~~~~ +LL - two_arg_diff(1, 1, "", ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:19:3 | LL | two_arg_diff(1, "", 1, ""); - | ^^^^^^^^^^^^ - -- argument of type `&'static str` unexpected + | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` | | - | argument of type `{integer}` unexpected + | unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -161,78 +156,78 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- help: remove the extra arguments | -LL | two_arg_diff(1, ""); - | ~~~~~~~ +LL - two_arg_diff(1, "", 1, ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:22:3 | LL | two_arg_same(1, 1, ""); - | ^^^^^^^^^^^^ -- argument of type `&'static str` unexpected + | ^^^^^^^^^^^^ -------- + | | | + | | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- -help: remove the extra argument - | -LL | two_arg_same(1, 1); - | ~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:23:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- -help: remove the extra argument - | -LL | two_arg_diff(1, ""); - | ~~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:24:3 | -LL | two_arg_same( - | ^^^^^^^^^^^^ -... -LL | "" - | -- argument of type `&'static str` unexpected +LL | two_arg_same( + | ^^^^^^^^^^^^ +LL | 1, +LL | 1, + | ______- +LL | | "" + | | -- + | |_____|| + | |help: remove the extra argument + | unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- -help: remove the extra argument - | -LL | two_arg_same(1, 1); - | ~~~~~~ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:30:3 | -LL | two_arg_diff( - | ^^^^^^^^^^^^ -LL | 1, -LL | 1, - | - argument of type `{integer}` unexpected +LL | two_arg_diff( + | ^^^^^^^^^^^^ +LL | 1, + | ______- +LL | | 1, + | | - + | | | + | |_____unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- -help: remove the extra argument - | -LL | two_arg_diff(1, ""); - | ~~~~~~~ error: aborting due to 14 previous errors diff --git a/tests/ui/argument-suggestions/issue-101097.stderr b/tests/ui/argument-suggestions/issue-101097.stderr index 7582082ac72..061f510144b 100644 --- a/tests/ui/argument-suggestions/issue-101097.stderr +++ b/tests/ui/argument-suggestions/issue-101097.stderr @@ -4,7 +4,7 @@ error[E0061]: this function takes 6 arguments but 7 arguments were supplied LL | f(C, A, A, A, B, B, C); | ^ - - - - expected `C`, found `B` | | | | - | | | argument of type `A` unexpected + | | | unexpected argument of type `A` | | expected `B`, found `A` | expected `A`, found `C` | @@ -64,8 +64,8 @@ error[E0308]: arguments to this function are incorrect LL | f(A, A, D, D, B, B); | ^ - - ---- two arguments of type `C` and `C` are missing | | | - | | argument of type `D` unexpected - | argument of type `D` unexpected + | | unexpected argument of type `D` + | unexpected argument of type `D` | note: function defined here --> $DIR/issue-101097.rs:6:4 diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr index c2e6e001b17..a86cbbf1802 100644 --- a/tests/ui/argument-suggestions/issue-97484.stderr +++ b/tests/ui/argument-suggestions/issue-97484.stderr @@ -2,11 +2,11 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied --> $DIR/issue-97484.rs:12:5 | LL | foo(&&A, B, C, D, E, F, G); - | ^^^ - - - - argument of type `F` unexpected + | ^^^ - - - - unexpected argument of type `F` | | | | | | | expected `&E`, found `E` - | | argument of type `C` unexpected - | argument of type `B` unexpected + | | unexpected argument of type `C` + | unexpected argument of type `B` | note: function defined here --> $DIR/issue-97484.rs:9:4 @@ -19,8 +19,9 @@ LL | foo(&&A, B, C, D, &E, F, G); | ~~ help: remove the extra arguments | -LL | foo(&&A, D, /* &E */, G); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - foo(&&A, B, C, D, E, F, G); +LL + foo(&&A, D, /* &E */, G); + | error: aborting due to previous error diff --git a/tests/ui/argument-suggestions/mixed_cases.stderr b/tests/ui/argument-suggestions/mixed_cases.stderr index 8cf48060a63..c645dd38179 100644 --- a/tests/ui/argument-suggestions/mixed_cases.stderr +++ b/tests/ui/argument-suggestions/mixed_cases.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/mixed_cases.rs:10:3 | LL | two_args(1, "", X {}); - | ^^^^^^^^ -- ---- argument of type `X` unexpected + | ^^^^^^^^ -- ---- unexpected argument of type `X` | | | expected `f32`, found `&str` | @@ -13,16 +13,17 @@ LL | fn two_args(_a: i32, _b: f32) {} | ^^^^^^^^ ------- ------- help: remove the extra argument | -LL | two_args(1, /* f32 */); - | ~~~~~~~~~~~~~~ +LL - two_args(1, "", X {}); +LL + two_args(1, /* f32 */); + | error[E0061]: this function takes 3 arguments but 4 arguments were supplied --> $DIR/mixed_cases.rs:11:3 | LL | three_args(1, "", X {}, ""); - | ^^^^^^^^^^ -- ---- -- argument of type `&'static str` unexpected + | ^^^^^^^^^^ -- ---- -- unexpected argument of type `&'static str` | | | - | | argument of type `X` unexpected + | | unexpected argument of type `X` | an argument of type `f32` is missing | note: function defined here @@ -58,7 +59,7 @@ error[E0308]: arguments to this function are incorrect --> $DIR/mixed_cases.rs:17:3 | LL | three_args(1, "", X {}); - | ^^^^^^^^^^ -- ---- argument of type `X` unexpected + | ^^^^^^^^^^ -- ---- unexpected argument of type `X` | | | an argument of type `f32` is missing | diff --git a/tests/ui/issues/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs index 6753860e9ff..6753860e9ff 100644 --- a/tests/ui/issues/issue-38821.rs +++ b/tests/ui/associated-types/issue-38821.rs diff --git a/tests/ui/issues/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index a52a9c138f1..a52a9c138f1 100644 --- a/tests/ui/issues/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr diff --git a/tests/ui/issues/issue-83924.fixed b/tests/ui/borrowck/issue-83924.fixed index aa40da12b87..aa40da12b87 100644 --- a/tests/ui/issues/issue-83924.fixed +++ b/tests/ui/borrowck/issue-83924.fixed diff --git a/tests/ui/issues/issue-83924.rs b/tests/ui/borrowck/issue-83924.rs index 22b80fe2f38..22b80fe2f38 100644 --- a/tests/ui/issues/issue-83924.rs +++ b/tests/ui/borrowck/issue-83924.rs diff --git a/tests/ui/issues/issue-83924.stderr b/tests/ui/borrowck/issue-83924.stderr index 572414df2bf..572414df2bf 100644 --- a/tests/ui/issues/issue-83924.stderr +++ b/tests/ui/borrowck/issue-83924.stderr diff --git a/tests/ui/bounds-lifetime.stderr b/tests/ui/bounds-lifetime.stderr index a0395ed4904..a3427e21cde 100644 --- a/tests/ui/bounds-lifetime.stderr +++ b/tests/ui/bounds-lifetime.stderr @@ -16,17 +16,24 @@ error: lifetime bounds cannot be used in this context LL | type C = for<'b, 'a: 'b +> fn(); | ^^ -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/bounds-lifetime.rs:4:18 | LL | type D = for<'a, T> fn(); | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/bounds-lifetime.rs:5:18 | LL | type E = dyn for<T> Fn(); | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/closures/binder/disallow-const.stderr b/tests/ui/closures/binder/disallow-const.stderr index 3c3b43d8cf3..9f4deaa774d 100644 --- a/tests/ui/closures/binder/disallow-const.stderr +++ b/tests/ui/closures/binder/disallow-const.stderr @@ -1,8 +1,12 @@ -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/disallow-const.rs:4:15 | LL | for<const N: i32> || -> () {}; | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/closures/binder/disallow-ty.stderr b/tests/ui/closures/binder/disallow-ty.stderr index 51b6773edea..22882ca2ba6 100644 --- a/tests/ui/closures/binder/disallow-ty.stderr +++ b/tests/ui/closures/binder/disallow-ty.stderr @@ -1,8 +1,12 @@ -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/disallow-ty.rs:4:9 | LL | for<T> || -> () {}; | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr index 4d6560e96e5..69b0f741156 100644 --- a/tests/ui/conditional-compilation/cfg-generic-params.stderr +++ b/tests/ui/conditional-compilation/cfg-generic-params.stderr @@ -1,21 +1,3 @@ -error: only lifetime parameters can be used in this context - --> $DIR/cfg-generic-params.rs:7:45 - | -LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn(); - | ^ - -error: only lifetime parameters can be used in this context - --> $DIR/cfg-generic-params.rs:11:51 - | -LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy; - | ^ - -error: only lifetime parameters can be used in this context - --> $DIR/cfg-generic-params.rs:15:54 - | -LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; - | ^ - error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:19:29 | @@ -46,5 +28,33 @@ error: cannot find attribute `unknown` in this scope LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; | ^^^^^^^ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/cfg-generic-params.rs:7:45 + | +LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn(); + | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/cfg-generic-params.rs:11:51 + | +LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy; + | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/cfg-generic-params.rs:15:54 + | +LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; + | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-33903.rs b/tests/ui/consts/issue-33903.rs index 613aa121a47..613aa121a47 100644 --- a/tests/ui/issues/issue-33903.rs +++ b/tests/ui/consts/issue-33903.rs diff --git a/tests/ui/issues/issue-54582.rs b/tests/ui/consts/issue-54582.rs index 8c50cac67f8..8c50cac67f8 100644 --- a/tests/ui/issues/issue-54582.rs +++ b/tests/ui/consts/issue-54582.rs diff --git a/tests/ui/issues/issue-2735-2.rs b/tests/ui/drop/issue-2735-2.rs index 70ebce9d35a..70ebce9d35a 100644 --- a/tests/ui/issues/issue-2735-2.rs +++ b/tests/ui/drop/issue-2735-2.rs diff --git a/tests/ui/issues/issue-2735-3.rs b/tests/ui/drop/issue-2735-3.rs index 23301537835..23301537835 100644 --- a/tests/ui/issues/issue-2735-3.rs +++ b/tests/ui/drop/issue-2735-3.rs diff --git a/tests/ui/issues/issue-2735.rs b/tests/ui/drop/issue-2735.rs index 20d3949a9f9..20d3949a9f9 100644 --- a/tests/ui/issues/issue-2735.rs +++ b/tests/ui/drop/issue-2735.rs diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 163737895fe..9b0cf069824 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -18,17 +18,16 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 | LL | let c = f(2, 3); - | ^ - argument of type `{integer}` unexpected + | ^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: closure defined here --> $DIR/E0057.rs:2:13 | LL | let f = |x| x * 3; | ^^^ -help: remove the extra argument - | -LL | let c = f(2); - | ~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-non_lifetime_binders.rs b/tests/ui/feature-gates/feature-gate-non_lifetime_binders.rs new file mode 100644 index 00000000000..221e9133fcc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-non_lifetime_binders.rs @@ -0,0 +1,4 @@ +fn foo() where for<T> T:, {} +//~^ ERROR only lifetime parameters can be used in this context + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-non_lifetime_binders.stderr b/tests/ui/feature-gates/feature-gate-non_lifetime_binders.stderr new file mode 100644 index 00000000000..75645e32401 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-non_lifetime_binders.stderr @@ -0,0 +1,12 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/feature-gate-non_lifetime_binders.rs:1:20 + | +LL | fn foo() where for<T> T:, {} + | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-75307.rs b/tests/ui/fmt/issue-75307.rs index cffa6bea8ed..cffa6bea8ed 100644 --- a/tests/ui/issues/issue-75307.rs +++ b/tests/ui/fmt/issue-75307.rs diff --git a/tests/ui/issues/issue-75307.stderr b/tests/ui/fmt/issue-75307.stderr index c5b0b11e7d0..c5b0b11e7d0 100644 --- a/tests/ui/issues/issue-75307.stderr +++ b/tests/ui/fmt/issue-75307.stderr diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr index f31aa554634..d605c9e0df7 100644 --- a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr +++ b/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr @@ -1,14 +1,21 @@ -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/hrtb-wrong-kind.rs:1:18 | LL | fn a() where for<T> T: Copy {} | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable -error: only lifetime parameters can be used in this context +error[E0658]: only lifetime parameters can be used in this context --> $DIR/hrtb-wrong-kind.rs:4:24 | LL | fn b() where for<const C: usize> [(); C]: Copy {} | ^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-39292.rs b/tests/ui/higher-rank-trait-bounds/issue-39292.rs index 968cf08916f..968cf08916f 100644 --- a/tests/ui/issues/issue-39292.rs +++ b/tests/ui/higher-rank-trait-bounds/issue-39292.rs diff --git a/tests/ui/issues/issue-16939.stderr b/tests/ui/issues/issue-16939.stderr index 76645645464..6db29bc61b1 100644 --- a/tests/ui/issues/issue-16939.stderr +++ b/tests/ui/issues/issue-16939.stderr @@ -2,17 +2,16 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-16939.rs:5:9 | LL | |t| f(t); - | ^ - argument unexpected + | ^ - + | | + | unexpected argument + | help: remove the extra argument | note: callable defined here --> $DIR/issue-16939.rs:4:12 | LL | fn _foo<F: Fn()> (f: F) { | ^^^^ -help: remove the extra argument - | -LL | |t| f(); - | ~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/issues/issue-26094.rs index d3d670aa92a..abf3543ddb9 100644 --- a/tests/ui/issues/issue-26094.rs +++ b/tests/ui/issues/issue-26094.rs @@ -1,6 +1,6 @@ macro_rules! some_macro { ($other: expr) => ({ - $other(None) //~ NOTE argument of type `Option<_>` unexpected + $other(None) //~ NOTE unexpected argument of type `Option<_>` }) } diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/issues/issue-26094.stderr index 881a6e538ee..608d2c7aff9 100644 --- a/tests/ui/issues/issue-26094.stderr +++ b/tests/ui/issues/issue-26094.stderr @@ -2,7 +2,10 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-26094.rs:10:17 | LL | $other(None) - | ---- argument of type `Option<_>` unexpected + | ---- + | | + | unexpected argument of type `Option<_>` + | help: remove the extra argument ... LL | some_macro!(some_function); | ^^^^^^^^^^^^^ @@ -12,10 +15,6 @@ note: function defined here | LL | fn some_function() {} | ^^^^^^^^^^^^^ -help: remove the extra argument - | -LL | some_function() - | ~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr index bb45fa08338..e544e424403 100644 --- a/tests/ui/issues/issue-4935.stderr +++ b/tests/ui/issues/issue-4935.stderr @@ -2,17 +2,16 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/issue-4935.rs:5:13 | LL | fn main() { foo(5, 6) } - | ^^^ - argument of type `{integer}` unexpected + | ^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/issue-4935.rs:3:4 | LL | fn foo(a: usize) {} | ^^^ -------- -help: remove the extra argument - | -LL | fn main() { foo(5) } - | ~~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-50576.rs b/tests/ui/loops/issue-50576.rs index e0c36b8273a..e0c36b8273a 100644 --- a/tests/ui/issues/issue-50576.rs +++ b/tests/ui/loops/issue-50576.rs diff --git a/tests/ui/issues/issue-50576.stderr b/tests/ui/loops/issue-50576.stderr index 4ec22fde910..4ec22fde910 100644 --- a/tests/ui/issues/issue-50576.stderr +++ b/tests/ui/loops/issue-50576.stderr diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 81269b73b9a..0f37e8f09a9 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -2,17 +2,16 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:13:7 | LL | x.zero(0) - | ^^^^ - argument of type `{integer}` unexpected + | ^^^^ - + | | + | unexpected argument of type `{integer}` + | help: remove the extra argument | note: associated function defined here --> $DIR/method-call-err-msg.rs:5:8 | LL | fn zero(self) -> Foo { self } | ^^^^ -help: remove the extra argument - | -LL | x.zero() - | ~~ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:14:7 diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr index 3a895acbdb5..cd483e7ad2c 100644 --- a/tests/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr @@ -32,7 +32,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/overloaded-calls-bad.rs:37:15 | LL | let ans = s("burma", "shave"); - | ^ ------- ------- argument of type `&'static str` unexpected + | ^ ------- ------- unexpected argument of type `&'static str` | | | expected `isize`, found `&str` | @@ -43,8 +43,9 @@ LL | impl FnMut<(isize,)> for S { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the extra argument | -LL | let ans = s(/* isize */); - | ~~~~~~~~~~~~~ +LL - let ans = s("burma", "shave"); +LL + let ans = s(/* isize */); + | error[E0308]: mismatched types --> $DIR/overloaded-calls-bad.rs:40:7 diff --git a/tests/ui/issues/issue-22536-copy-mustnt-zero.rs b/tests/ui/moves/issue-22536-copy-mustnt-zero.rs index 017f36484c1..017f36484c1 100644 --- a/tests/ui/issues/issue-22536-copy-mustnt-zero.rs +++ b/tests/ui/moves/issue-22536-copy-mustnt-zero.rs diff --git a/tests/ui/issues/issue-27583.rs b/tests/ui/nll/issue-27583.rs index 84c94c7c905..84c94c7c905 100644 --- a/tests/ui/issues/issue-27583.rs +++ b/tests/ui/nll/issue-27583.rs diff --git a/tests/ui/issues/issue-48179.rs b/tests/ui/nll/issue-48179.rs index f81203dc412..f81203dc412 100644 --- a/tests/ui/issues/issue-48179.rs +++ b/tests/ui/nll/issue-48179.rs diff --git a/tests/ui/issues/issue-75777.rs b/tests/ui/nll/issue-75777.rs index a1e438bc617..a1e438bc617 100644 --- a/tests/ui/issues/issue-75777.rs +++ b/tests/ui/nll/issue-75777.rs diff --git a/tests/ui/issues/issue-75777.stderr b/tests/ui/nll/issue-75777.stderr index 370cd72fd55..370cd72fd55 100644 --- a/tests/ui/issues/issue-75777.stderr +++ b/tests/ui/nll/issue-75777.stderr diff --git a/tests/ui/parser/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover-fn-ptr-with-generics.stderr index 1da9c18571b..069fcffe9a0 100644 --- a/tests/ui/parser/recover-fn-ptr-with-generics.stderr +++ b/tests/ui/parser/recover-fn-ptr-with-generics.stderr @@ -88,12 +88,6 @@ error: expected identifier, found `>` LL | type QuiteBroken = fn<const>(); | ^ expected identifier -error: lifetime bounds cannot be used in this context - --> $DIR/recover-fn-ptr-with-generics.rs:22:26 - | -LL | let _: extern fn<'a: 'static>(); - | ^^^^^^^ - error[E0412]: cannot find type `T` in this scope --> $DIR/recover-fn-ptr-with-generics.rs:5:27 | @@ -106,6 +100,12 @@ error[E0412]: cannot find type `T` in this scope LL | type Identity = fn<T>(T) -> T; | ^ not found in this scope +error: lifetime bounds cannot be used in this context + --> $DIR/recover-fn-ptr-with-generics.rs:22:26 + | +LL | let _: extern fn<'a: 'static>(); + | ^^^^^^^ + error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/issues/issue-40003.rs b/tests/ui/recursion_limit/issue-40003.rs index 5e61361f987..5e61361f987 100644 --- a/tests/ui/issues/issue-40003.rs +++ b/tests/ui/recursion_limit/issue-40003.rs diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index 964302e924c..f803f9da2af 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -24,14 +24,13 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 | LL | std::mem::size_of(u16); - | ^^^^^^^^^^^^^^^^^ --- argument unexpected + | ^^^^^^^^^^^^^^^^^ --- + | | + | unexpected argument + | help: remove the extra argument | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -help: remove the extra argument - | -LL | std::mem::size_of(); - | ~~ error: aborting due to 3 previous errors diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index 15179954adc..f0dea66f612 100644 --- a/tests/ui/span/issue-34264.stderr +++ b/tests/ui/span/issue-34264.stderr @@ -54,17 +54,16 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:7:5 | LL | foo(Some(42), 2, ""); - | ^^^ -- argument of type `&'static str` unexpected + | ^^^ ---- + | | | + | | unexpected argument of type `&'static str` + | help: remove the extra argument | note: function defined here --> $DIR/issue-34264.rs:1:4 | LL | fn foo(Option<i32>, String) {} | ^^^ ----------- ------ -help: remove the extra argument - | -LL | foo(Some(42), 2); - | ~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/issue-34264.rs:8:13 @@ -84,17 +83,16 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:10:5 | LL | bar(1, 2, 3); - | ^^^ - argument of type `{integer}` unexpected + | ^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: function defined here --> $DIR/issue-34264.rs:3:4 | LL | fn bar(x, y: usize) {} | ^^^ - -------- -help: remove the extra argument - | -LL | bar(1, 2); - | ~~~~~~ error: aborting due to 6 previous errors diff --git a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr index e9736363816..510b99bb5af 100644 --- a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:6:34 | LL | let _: Option<(i32, bool)> = Some(1, 2); - | ^^^^ - argument of type `{integer}` unexpected + | ^^^^ - unexpected argument of type `{integer}` | note: expected `(i32, bool)`, found integer --> $DIR/args-instead-of-tuple-errors.rs:6:39 @@ -22,14 +22,15 @@ note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: remove the extra argument | -LL | let _: Option<(i32, bool)> = Some(/* (i32, bool) */); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _: Option<(i32, bool)> = Some(1, 2); +LL + let _: Option<(i32, bool)> = Some(/* (i32, bool) */); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:8:5 | LL | int_bool(1, 2); - | ^^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^^ - unexpected argument of type `{integer}` | note: expected `(i32, bool)`, found integer --> $DIR/args-instead-of-tuple-errors.rs:8:14 @@ -45,8 +46,9 @@ LL | fn int_bool(_: (i32, bool)) { | ^^^^^^^^ -------------- help: remove the extra argument | -LL | int_bool(/* (i32, bool) */); - | ~~~~~~~~~~~~~~~~~~~ +LL - int_bool(1, 2); +LL + int_bool(/* (i32, bool) */); + | error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:11:28 diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs new file mode 100644 index 00000000000..d254c0ae3ef --- /dev/null +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs @@ -0,0 +1,11 @@ +// Regression test for #108072: do not ICE upon unmet trait alias constraint + +#![feature(trait_alias)] + +trait IteratorAlias = Iterator; + +fn f(_: impl IteratorAlias) {} + +fn main() { + f(()) //~ `()` is not an iterator +} diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr new file mode 100644 index 00000000000..39f974f962c --- /dev/null +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr @@ -0,0 +1,19 @@ +error[E0277]: `()` is not an iterator + --> $DIR/issue-108072-unmet-trait-alias-bound.rs:10:7 + | +LL | f(()) + | - ^^ `()` is not an iterator + | | + | required by a bound introduced by this call + | + = help: the trait `Iterator` is not implemented for `()` + = note: required for `()` to implement `IteratorAlias` +note: required by a bound in `f` + --> $DIR/issue-108072-unmet-trait-alias-bound.rs:7:14 + | +LL | fn f(_: impl IteratorAlias) {} + | ^^^^^^^^^^^^^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/non_lifetime_binders/basic.rs b/tests/ui/traits/non_lifetime_binders/basic.rs new file mode 100644 index 00000000000..a797aae65db --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/basic.rs @@ -0,0 +1,19 @@ +// check-pass +// Basic test that show's we can succesfully typeck a `for<T>` where clause. + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Trait {} + +impl<T: ?Sized> Trait for T {} + +fn foo() +where + for<T> T: Trait, +{ +} + +fn main() { + foo(); +} diff --git a/tests/ui/traits/non_lifetime_binders/basic.stderr b/tests/ui/traits/non_lifetime_binders/basic.stderr new file mode 100644 index 00000000000..fddc5d9fc25 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/basic.stderr @@ -0,0 +1,11 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/basic.rs:4:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/non_lifetime_binders/fail.rs b/tests/ui/traits/non_lifetime_binders/fail.rs new file mode 100644 index 00000000000..460f68907e8 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/fail.rs @@ -0,0 +1,23 @@ +// Error reporting for where `for<T> T: Trait` doesn't hold + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Trait {} + +fn fail() +where + for<T> T: Trait, +{} + +fn auto_trait() +where + for<T> T: Send, +{} + +fn main() { + fail(); + //~^ ERROR the trait bound `T: Trait` is not satisfied + auto_trait(); + //~^ ERROR `T` cannot be sent between threads safely +} diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr new file mode 100644 index 00000000000..ba5953193a4 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr @@ -0,0 +1,43 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/fail.rs:3:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/fail.rs:19:5 + | +LL | fail(); + | ^^^^ the trait `Trait` is not implemented for `T` + | +note: required by a bound in `fail` + --> $DIR/fail.rs:10:15 + | +LL | fn fail() + | ---- required by a bound in this +LL | where +LL | for<T> T: Trait, + | ^^^^^ required by this bound in `fail` + +error[E0277]: `T` cannot be sent between threads safely + --> $DIR/fail.rs:21:5 + | +LL | auto_trait(); + | ^^^^^^^^^^ `T` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `T` +note: required by a bound in `auto_trait` + --> $DIR/fail.rs:15:15 + | +LL | fn auto_trait() + | ---------- required by a bound in this +LL | where +LL | for<T> T: Send, + | ^^^^ required by this bound in `auto_trait` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/non_lifetime_binders/on-dyn.rs b/tests/ui/traits/non_lifetime_binders/on-dyn.rs new file mode 100644 index 00000000000..8fb7dd27605 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-dyn.rs @@ -0,0 +1,13 @@ +// Tests to make sure that we reject polymorphic dyn trait. + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Test<T> {} + +fn foo() -> &'static dyn for<T> Test<T> { + //~^ ERROR late-bound type parameter not allowed on trait object types + todo!() +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/on-dyn.stderr b/tests/ui/traits/non_lifetime_binders/on-dyn.stderr new file mode 100644 index 00000000000..44071107de4 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-dyn.stderr @@ -0,0 +1,17 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/on-dyn.rs:3:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: late-bound type parameter not allowed on trait object types + --> $DIR/on-dyn.rs:8:30 + | +LL | fn foo() -> &'static dyn for<T> Test<T> { + | ^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/traits/non_lifetime_binders/on-ptr.rs b/tests/ui/traits/non_lifetime_binders/on-ptr.rs new file mode 100644 index 00000000000..0aaff52b6d8 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-ptr.rs @@ -0,0 +1,13 @@ +// Tests to make sure that we reject polymorphic fn ptrs. + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +fn foo() -> for<T> fn(T) { + //~^ ERROR late-bound type parameter not allowed on function pointer types + todo!() +} + +fn main() { + foo()(1i32); +} diff --git a/tests/ui/traits/non_lifetime_binders/on-ptr.stderr b/tests/ui/traits/non_lifetime_binders/on-ptr.stderr new file mode 100644 index 00000000000..bb7dccaf07d --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-ptr.stderr @@ -0,0 +1,17 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/on-ptr.rs:3:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: late-bound type parameter not allowed on function pointer types + --> $DIR/on-ptr.rs:6:17 + | +LL | fn foo() -> for<T> fn(T) { + | ^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/tuple/wrong_argument_ice-3.stderr b/tests/ui/tuple/wrong_argument_ice-3.stderr index 75dfe716395..7143c959478 100644 --- a/tests/ui/tuple/wrong_argument_ice-3.stderr +++ b/tests/ui/tuple/wrong_argument_ice-3.stderr @@ -2,7 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | LL | groups.push(new_group, vec![process]); - | ^^^^ ------------- argument of type `Vec<&Process>` unexpected + | ^^^^ ------------- unexpected argument of type `Vec<&Process>` | note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>` --> $DIR/wrong_argument_ice-3.rs:9:21 @@ -15,8 +15,9 @@ note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: remove the extra argument | -LL | groups.push(/* (Vec<String>, Vec<Process>) */); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - groups.push(new_group, vec![process]); +LL + groups.push(/* (Vec<String>, Vec<Process>) */); + | error: aborting due to previous error diff --git a/tests/ui/tuple/wrong_argument_ice-4.stderr b/tests/ui/tuple/wrong_argument_ice-4.stderr index a2686ab9440..d8569ebf6b6 100644 --- a/tests/ui/tuple/wrong_argument_ice-4.stderr +++ b/tests/ui/tuple/wrong_argument_ice-4.stderr @@ -6,17 +6,16 @@ LL | (|| {})(|| { LL | | LL | | let b = 1; LL | | }); - | |_____- argument of type `[closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15]` unexpected + | | - + | | | + | |_____unexpected argument of type `[closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15]` + | help: remove the extra argument | note: closure defined here --> $DIR/wrong_argument_ice-4.rs:2:6 | LL | (|| {})(|| { | ^^ -help: remove the extra argument - | -LL | (|| {})(); - | ~~ error: aborting due to previous error diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr index ba8d15d0b73..429501c2762 100644 --- a/tests/ui/type/type-ascription-instead-of-initializer.stderr +++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr @@ -11,14 +11,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/type-ascription-instead-of-initializer.rs:2:12 | LL | let x: Vec::with_capacity(10, 20); - | ^^^^^^^^^^^^^^^^^^ -- argument of type `{integer}` unexpected + | ^^^^^^^^^^^^^^^^^^ ---- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -help: remove the extra argument - | -LL | let x: Vec::with_capacity(10); - | ~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-53712.rs b/tests/ui/typeck/issue-53712.rs index 2353904d79d..2353904d79d 100644 --- a/tests/ui/issues/issue-53712.rs +++ b/tests/ui/typeck/issue-53712.rs diff --git a/tests/ui/issues/issue-53712.stderr b/tests/ui/typeck/issue-53712.stderr index db85919afcb..db85919afcb 100644 --- a/tests/ui/issues/issue-53712.stderr +++ b/tests/ui/typeck/issue-53712.stderr diff --git a/tests/ui/issues/issue-7813.rs b/tests/ui/typeck/issue-7813.rs index ce549bde601..ce549bde601 100644 --- a/tests/ui/issues/issue-7813.rs +++ b/tests/ui/typeck/issue-7813.rs diff --git a/tests/ui/issues/issue-7813.stderr b/tests/ui/typeck/issue-7813.stderr index 2a747f679a8..2a747f679a8 100644 --- a/tests/ui/issues/issue-7813.stderr +++ b/tests/ui/typeck/issue-7813.stderr diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr index b734bcd4eb0..72ddebab486 100644 --- a/tests/ui/typeck/remove-extra-argument.stderr +++ b/tests/ui/typeck/remove-extra-argument.stderr @@ -2,17 +2,16 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/remove-extra-argument.rs:6:5 | LL | l(vec![], vec![]) - | ^ ------ argument of type `Vec<_>` unexpected + | ^ -------- + | | | + | | unexpected argument of type `Vec<_>` + | help: remove the extra argument | note: function defined here --> $DIR/remove-extra-argument.rs:3:4 | LL | fn l(_a: Vec<u8>) {} | ^ ----------- -help: remove the extra argument - | -LL | l(vec![]) - | ~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index fbced928a8a..57cbd1d2005 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -2,29 +2,29 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); - | ^^^^ - argument of type `{integer}` unexpected + | ^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL -help: remove the extra argument - | -LL | let _ = Some(3); - | ~~~ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:7:13 | LL | let _ = Ok(3, 6, 2); - | ^^ - - argument of type `{integer}` unexpected + | ^^ - - unexpected argument of type `{integer}` | | - | argument of type `{integer}` unexpected + | unexpected argument of type `{integer}` | note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: remove the extra arguments | -LL | let _ = Ok(3); - | ~~~ +LL - let _ = Ok(3, 6, 2); +LL + let _ = Ok(3); + | error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:8:13 @@ -59,17 +59,16 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); - | ^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 | LL | struct Wrapper(i32); | ^^^^^^^ -help: remove the extra argument - | -LL | let _ = Wrapper(5); - | ~~~ error[E0061]: this struct takes 2 arguments but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:11:13 @@ -107,17 +106,16 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); - | ^^^^^^^^^^^^^ - argument of type `{integer}` unexpected + | ^^^^^^^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ -help: remove the extra argument - | -LL | let _ = DoubleWrapper(5, 2); - | ~~~~~~ error: aborting due to 8 previous errors diff --git a/triagebot.toml b/triagebot.toml index 883bc8720e2..8a9d9403366 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -630,7 +630,7 @@ style-team = [ "/src/stage0.json" = ["bootstrap"] "/tests/ui" = ["compiler"] "/src/tools/cargo" = ["@ehuss", "@joshtriplett"] -"/src/tools/compiletest" = ["bootstrap"] +"/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk"] "/src/tools/linkchecker" = ["@ehuss"] "/src/tools/rust-installer" = ["bootstrap"] "/src/tools/rustbook" = ["@ehuss"] |
