diff --git a/Cargo.lock b/Cargo.lock index 6a1525f7530d..d02cab38ae8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -782,7 +782,7 @@ dependencies = [ "declare_clippy_lint", "if_chain", "itertools", - "pulldown-cmark 0.9.2", + "pulldown-cmark", "quine-mc_cluskey", "regex-syntax", "rustc-semver", @@ -2555,7 +2555,7 @@ dependencies = [ "memchr", "once_cell", "opener", - "pulldown-cmark 0.9.2", + "pulldown-cmark", "regex", "serde", "serde_json", @@ -2572,7 +2572,7 @@ dependencies = [ "anyhow", "handlebars 3.5.5", "pretty_assertions", - "pulldown-cmark 0.7.2", + "pulldown-cmark", "same-file", "serde_json", "url", @@ -3269,17 +3269,6 @@ dependencies = [ "cc", ] -[[package]] -name = "pulldown-cmark" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca36dea94d187597e104a5c8e4b07576a8a45aa5db48a65e12940d3eb7461f55" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - [[package]] name = "pulldown-cmark" version = "0.9.2" @@ -4583,7 +4572,7 @@ name = "rustc_resolve" version = "0.0.0" dependencies = [ "bitflags", - "pulldown-cmark 0.9.2", + "pulldown-cmark", "rustc_arena", "rustc_ast", "rustc_ast_pretty", diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index c88a60c62b9d..aa3a666b0b29 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -171,7 +171,9 @@ pub struct TargetDataLayout { pub instruction_address_space: AddressSpace, - /// Minimum size of #[repr(C)] enums (default I32 bits) + /// Minimum size of #[repr(C)] enums (default c_int::BITS, usually 32) + /// Note: This isn't in LLVM's data layout string, it is `short_enum` + /// so the only valid spec for LLVM is c_int::BITS or 8 pub c_enum_min_size: Integer, } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 902b4b1a1ecf..d1ae8c1fdbd9 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 89ba6f936d14..3af2ef4e7271 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 40531c1c164f..3d240108b4ab 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 1550958ab8ee..d51cc652bfd4 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 7b07c2a46337..b2d72654a2ac 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; @@ -2596,7 +2592,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if is_closure { None } else { - let ty = self.infcx.tcx.type_of(self.mir_def_id()); + let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity(); match ty.kind() { ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig( self.mir_def_id(), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c4e4e0517ece..f5bd99f15ab9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1185,7 +1185,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let parent_self_ty = matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) .then_some(parent_did) - .and_then(|did| match tcx.type_of(did).kind() { + .and_then(|did| match tcx.type_of(did).subst_identity().kind() { ty::Adt(def, ..) => Some(def.did()), _ => None, }); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 7901a5046aba..a2fa3018234c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -575,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() { - output_ty = self.infcx.tcx.type_of(def_id) + output_ty = self.infcx.tcx.type_of(def_id).subst_identity() }; debug!("report_fnmut_error: output_ty={:?}", output_ty); @@ -896,7 +896,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!(?fn_did, ?substs); // Only suggest this on function calls, not closures - let ty = tcx.type_of(fn_did); + let ty = tcx.type_of(fn_did).subst_identity(); debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); if let ty::Closure(_, _) = ty.kind() { return; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a82e695d6490..f6881a2e5bc8 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 }) @@ -856,8 +849,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { return None; }; - let found = tcx - .any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region)); + let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| { + *r == ty::ReEarlyBound(region) + }); Some(RegionName { name: self.synthesize_region_name(), diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index f2693bded590..83fdb6066c6b 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 c7b22d5f2e60..bb42301828d2 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 d5c401ae1c6e..a411aec518e9 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 5b7adae66acf..004b945eada1 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(), @@ -402,7 +402,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ); } } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { - let unnormalized_ty = tcx.type_of(static_def_id); + let unnormalized_ty = tcx.type_of(static_def_id).subst_identity(); let normalized_ty = self.cx.normalize(unnormalized_ty, locations); let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty; @@ -2589,7 +2589,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { DefKind::InlineConst => substs.as_inline_const().parent_substs(), other => bug!("unexpected item {:?}", other), }; - let parent_substs = tcx.mk_substs(parent_substs.iter()); + let parent_substs = tcx.intern_substs(parent_substs); assert_eq!(typeck_root_substs.len(), parent_substs.len()); if let Err(_) = self.eq_substs( diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 56930c89b2c6..efa5a29c5ddf 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -480,15 +480,10 @@ 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 va_list_ty = self - .infcx - .tcx - .bound_type_of(va_list_did) - .subst(self.infcx.tcx, &[region.into()]); + 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.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]); unnormalized_input_tys = self.infcx.tcx.mk_type_list( unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), @@ -531,7 +526,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { match tcx.hir().body_owner_kind(self.mir_def.did) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = if self.mir_def.did.to_def_id() == typeck_root_def_id { - tcx.type_of(typeck_root_def_id) + tcx.type_of(typeck_root_def_id).subst_identity() } else { let tables = tcx.typeck(self.mir_def.did); tables.node_type(self.mir_hir_id) @@ -636,7 +631,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 @@ -677,7 +672,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // For a constant body, there are no inputs, and one // "output" (the type of the constant). assert_eq!(self.mir_def.did.to_def_id(), def_id); - let ty = tcx.type_of(self.mir_def.def_id_for_type_of()); + let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); let ty = indices.fold_to_region_vids(tcx, ty); ty::Binder::dummy(tcx.intern_type_list(&[ty])) } @@ -748,10 +743,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 +835,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 +875,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 e8a353b1c8fc..d30e8ba4b93d 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 dd5c85531fd7..38878ba7012f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -941,13 +941,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 f73f20c84a39..e67c0dba6859 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/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index 638b2d573b5d..b4a2537b5ea9 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>( Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } } else { - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); @@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); let (param_types, args) = if fx.tcx.sess.target.is_like_windows { let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 58b01dfb5b0e..7c6fd9f6f1ec 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_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index d2ae6978ca2a..cbac2e667652 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>( // carry0 | carry1 -> carry or borrow respectively let cb_out = fx.bcx.ins().bor(cb0, cb1); - let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter())); + let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); let val = CValue::by_val_pair(cb_out, c, layout); ret.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 3e3b68571342..26327107df4c 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), report.def_id, - tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()), + tcx.intern_substs(&[GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap() diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index afacbec64458..05905a7bcdf3 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; - let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())); + let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); CValue::by_val_pair(res, has_overflow, out_layout) } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 7a4ec494c8e7..651d644ebb63 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -62,7 +62,7 @@ pub fn sanitize_attrs<'ll>( ) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize; - if enabled.contains(SanitizerSet::ADDRESS) { + if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) { attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx)); } if enabled.contains(SanitizerSet::MEMORY) { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 38f8733763df..40f0594b40db 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 { } fn get_instr_profile_output_path(config: &ModuleConfig) -> Option { - 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( @@ -446,16 +442,19 @@ pub(crate) unsafe fn llvm_optimize( sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD), sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS), sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS), + sanitize_kernel_address: config.sanitizer.contains(SanitizerSet::KERNELADDRESS), + sanitize_kernel_address_recover: config + .sanitizer_recover + .contains(SanitizerSet::KERNELADDRESS), }) } else { 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/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 92629aa18d45..9116e71beac8 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -521,7 +521,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { // The semantics of #[used] in Rust only require the symbol to make it into the // object file. It is explicitly allowed for the linker to strip the symbol if it - // is dead, which means we are allowed use `llvm.compiler.used` instead of + // is dead, which means we are allowed to use `llvm.compiler.used` instead of // `llvm.used` here. // // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique @@ -532,7 +532,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { // That said, we only ever emit these when compiling for ELF targets, unless // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage // on other targets, in particular MachO targets have *their* static constructor - // lists broken if `llvm.compiler.used` is emitted rather than llvm.used. However, + // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However, // that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`, // so we don't need to take care of it here. self.add_compiler_used_global(g); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 120dc59dfb3b..37ee0e14020c 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -145,8 +145,13 @@ pub unsafe fn create_module<'ll>( let llvm_version = llvm_util::get_version(); if llvm_version < (16, 0, 0) { if sess.target.arch == "s390x" { + // LLVM 16 data layout changed to always set 64-bit vector alignment, + // which is conditional in earlier LLVM versions. + // https://reviews.llvm.org/D131158 for the discussion. target_data_layout = target_data_layout.replace("-v128:64", ""); } else if sess.target.arch == "riscv64" { + // LLVM 16 introduced this change so as to produce more efficient code. + // See https://reviews.llvm.org/D116735 for the discussion. target_data_layout = target_data_layout.replace("-n32:64-", "-n64-"); } } @@ -402,12 +407,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/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index ace15cfb0247..3dc0ac03312e 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -27,8 +27,6 @@ use rustc_middle::ty::Instance; use std::cell::RefCell; use std::ffi::CString; -use std::iter; - pub mod mapgen; const UNUSED_FUNCTION_COUNTER_ID: CounterValueReference = CounterValueReference::START; @@ -201,7 +199,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance< tcx.symbol_name(instance).name, cx.fn_abi_of_fn_ptr( ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(tcx.mk_unit()), + [tcx.mk_unit()], tcx.mk_unit(), false, hir::Unsafety::Unsafe, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index ca7a07d8391b..cef403b9f8b8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -508,7 +508,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - cx.tcx.type_of(impl_def_id), + cx.tcx.type_of(impl_def_id).skip_binder(), ); // Only "class" methods are generally understood by LLVM, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b0295481ca5a..39afb4af6f68 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -22,7 +22,6 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use std::cmp::Ordering; -use std::iter; fn get_simple_intrinsic<'ll>( cx: &CodegenCx<'ll, '_>, @@ -798,7 +797,7 @@ fn get_rust_try_fn<'ll, 'tcx>( let i8p = tcx.mk_mut_ptr(tcx.types.i8); // `unsafe fn(*mut i8) -> ()` let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(i8p), + [i8p], tcx.mk_unit(), false, hir::Unsafety::Unsafe, @@ -806,7 +805,7 @@ fn get_rust_try_fn<'ll, 'tcx>( ))); // `unsafe fn(*mut i8, *mut i8) -> ()` let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - [i8p, i8p].iter().cloned(), + [i8p, i8p], tcx.mk_unit(), false, hir::Unsafety::Unsafe, @@ -814,7 +813,7 @@ fn get_rust_try_fn<'ll, 'tcx>( ))); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( - [try_fn_ty, i8p, catch_fn_ty].into_iter(), + [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, false, hir::Unsafety::Unsafe, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8b4861962b22..7aab666fc5e8 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -482,6 +482,8 @@ pub struct SanitizerOptions { pub sanitize_thread: bool, pub sanitize_hwaddress: bool, pub sanitize_hwaddress_recover: bool, + pub sanitize_kernel_address: bool, + pub sanitize_kernel_address_recover: bool, } /// LLVMRelocMode diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 0cb4bc806a13..cc8ff947fc31 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 6fe8527ada62..8aa744ce9353 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 6e136db38954..023d38e93128 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( } } - 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( 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/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 3ebbb2cbdfb8..7d5c0048626c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -295,7 +295,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { if let Some(list) = attr.meta_item_list() { for item in list.iter() { if item.has_name(sym::address) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS; + codegen_fn_attrs.no_sanitize |= + SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; } else if item.has_name(sym::cfi) { codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; } else if item.has_name(sym::kcfi) { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d5530c476807..7d51cee307e9 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -13,7 +13,7 @@ //! This crate contains codegen code that is used by all codegen backends (LLVM and others). //! The backend-agnostic functions of this crate use functions defined in various traits that -//! have to be implemented by each backends. +//! have to be implemented by each backend. #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index de1734332d44..eec91ffa44a0 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.basic_blocks diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a6afbad5b240..0432a9c5a129 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)] = &[ ("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_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 5042c6bac993..f6a3937870ed 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -95,8 +95,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Allocate memory for `CallerLocation` struct. let loc_ty = self .tcx - .bound_type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) - .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) + .subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()])); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 635987d039e0..f4e03ad8c593 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -690,7 +690,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!(self.tcx.is_static(def_id)); assert!(!self.tcx.is_thread_local_static(def_id)); // Use size and align of the type. - let ty = self.tcx.type_of(def_id); + let ty = self + .tcx + .type_of(def_id) + .no_bound_vars() + .expect("statics should not have generic parameters"); let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); assert!(layout.is_sized()); (layout.size, layout.align.abi, AllocKind::LiveData) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index e841500bf3e0..0e4501922f41 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -68,7 +68,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn fn_sig(&self) -> PolyFnSig<'tcx> { let did = self.def_id().to_def_id(); if self.tcx.is_closure(did) { - let ty = self.tcx.type_of(did); + let ty = self.tcx.type_of(did).subst_identity(); let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") }; substs.as_closure().sig() } else { diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 7009d3b38ae4..19367d708ee7 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -898,7 +898,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { assert_eq!(self.new_block(), START_BLOCK); self.visit_rvalue( &mut rvalue, - Location { block: BasicBlock::new(0), statement_index: usize::MAX }, + Location { block: START_BLOCK, statement_index: usize::MAX }, ); let span = self.promoted.span; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 56c60d59d285..67dbf29da3b0 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -334,7 +334,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let kind = match parent_ty.ty.kind() { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { - self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind() + self.tcx.type_of(def_id).subst(self.tcx, substs).kind() } kind => kind, }; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 3aca03f6e5c6..44331683694b 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 + Into, { - 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 4f2cc8b0351c..211bbf4f50e6 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 83b733d4c067..8c39feca88a0 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -471,6 +471,8 @@ pub enum StashKey { /// When an invalid lifetime e.g. `'2` should be reinterpreted /// as a char literal in the parser LifetimeIsChar, + /// When an invalid lifetime e.g. `'🐱` contains emoji. + LifetimeContainsEmoji, /// Maybe there was a typo where a comma was forgotten before /// FRU syntax MaybeFruTypo, @@ -1066,29 +1068,26 @@ impl Handler { } pub fn has_errors(&self) -> Option { - 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 { - 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 { - 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 { - 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 1fcbdfd9be5c..5c845ae6d0be 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(&self, mut node: T) -> Option { 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(&self, node: &mut T) { @@ -257,7 +255,7 @@ impl<'a> StripUnconfigured<'a> { fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option { 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 21d211eefbef..6d8f7e4a0f68 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` binders in where-clauses + (incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(108185), 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 7cb3b6e1525b..80ec1caf521e 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 { - if self.params.iter().any(|p| self.span.contains(p.span)) { + self.params.iter().any(|p| self.span.contains(p.span)).then(|| { // `fn foo(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/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 5e8f727df69d..e5e20aa78d9a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -77,7 +77,7 @@ fn generic_arg_mismatch_err( Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { let param_name = tcx.hir().ty_param_name(param_local_id); - let param_type = tcx.type_of(param.def_id); + let param_type = tcx.type_of(param.def_id).subst_identity(); if param_type.is_suggestable(tcx, false) { err.span_suggestion( tcx.def_span(src_def_id), @@ -97,7 +97,7 @@ fn generic_arg_mismatch_err( ( GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }), GenericParamDefKind::Const { .. }, - ) if tcx.type_of(param.def_id) == tcx.types.usize => { + ) if tcx.type_of(param.def_id).skip_binder() == tcx.types.usize => { let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id())); if let Ok(snippet) = snippet { err.span_suggestion( diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 46dc4141e661..2ff47237b1bf 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}; @@ -30,9 +30,9 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; +use rustc_middle::ty::DynKind; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitable}; -use rustc_middle::ty::{DynKind, EarlyBinder}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; @@ -225,36 +225,37 @@ 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 } + Some(rbv::ResolvedArg::Error(_)) => { + bug!("only ty/ct should resolve as ResolvedArg::Error") + } + None => { self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| { debug!(?lifetime, "unelided lifetime in signature"); @@ -263,7 +264,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", + ) }) } } @@ -450,7 +454,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { - let ty = tcx.at(self.span).type_of(param.def_id); + let ty = tcx + .at(self.span) + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"); if self.astconv.allow_ty_infer() { self.astconv.ct_infer(ty, Some(param), inf.span).into() } else { @@ -477,7 +485,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, .. } => { @@ -491,7 +502,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Avoid ICE #86756 when type error recovery goes awry. return tcx.ty_error().into(); } - tcx.at(self.span).bound_type_of(param.def_id).subst(tcx, substs).into() + tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into() } else if infer_args { self.astconv.ty_infer(Some(param), self.span).into() } else { @@ -500,7 +511,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } GenericParamDefKind::Const { has_default } => { - let ty = tcx.at(self.span).type_of(param.def_id); + let ty = tcx + .at(self.span) + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"); if ty.references_error() { return tcx.const_error(ty).into(); } @@ -1227,7 +1242,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } hir::def::DefKind::AssocConst => tcx .const_error_with_guaranteed( - tcx.bound_type_of(assoc_item_def_id) + tcx.type_of(assoc_item_def_id) .subst(tcx, projection_ty.skip_binder().substs), reported, ) @@ -1264,7 +1279,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment: &hir::PathSegment<'_>, ) -> Ty<'tcx> { let substs = self.ast_path_substs_for_ty(span, did, item_segment); - self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs) + self.tcx().at(span).type_of(did).subst(self.tcx(), substs) } fn conv_object_ty_poly_trait_ref( @@ -1317,7 +1332,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Clause::TypeOutlives(_) => { // Do nothing, we deal with regions separately } - ty::Clause::RegionOutlives(_) => bug!(), + ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(), }, ty::PredicateKind::WellFormed(_) | ty::PredicateKind::AliasEq(..) @@ -1597,14 +1612,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .collect::>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); v.dedup(); - let existential_predicates = tcx.mk_poly_existential_predicates(v.into_iter()); + let existential_predicates = tcx.intern_poly_existential_predicates(&v); // Use explicitly-specified region bound. let region_bound = if !lifetime.is_elided() { 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 +1637,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.emit() }; - tcx.re_error(e) + tcx.mk_re_error(e) }) } }) @@ -2043,7 +2058,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assoc_segment, adt_substs, ); - let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs); + let ty = tcx.type_of(assoc_ty_did).subst(tcx, item_substs); return Ok((ty, DefKind::AssocTy, assoc_ty_did)); } } @@ -2597,6 +2612,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, opt_self_ty: Option>, path: &hir::Path<'_>, + hir_id: hir::HirId, permit_variants: bool, ) -> Ty<'tcx> { let tcx = self.tcx(); @@ -2660,11 +2676,26 @@ 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)) + } + Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar), + arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), + } } Res::SelfTyParam { .. } => { // `Self` in trait or type alias. @@ -2685,7 +2716,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. - let ty = tcx.at(span).type_of(def_id); + let ty = tcx.at(span).type_of(def_id).subst_identity(); let span_of_impl = tcx.span_of_impl(def_id); self.prohibit_generics(path.segments.iter(), |err| { let def_id = match *ty.kind() { @@ -2882,12 +2913,13 @@ 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) } 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); @@ -2919,7 +2951,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { None, ty::BoundConstness::NotConst, ); - EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs) + tcx.at(span).type_of(def_id).subst(tcx, substs) } hir::TyKind::Array(ty, length) => { let length = match length { @@ -2932,7 +2964,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.mk_array_with_const_len(self.ast_ty_to_ty(ty), length) } hir::TyKind::Typeof(e) => { - let ty_erased = tcx.type_of(e.def_id); + let ty_erased = tcx.type_of(e.def_id).subst_identity(); let ty = tcx.fold_regions(ty_erased, |r, _| { if r.is_erased() { tcx.lifetimes.re_static } else { r } }); @@ -3060,7 +3092,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?output_ty); - let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi); + let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi); let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); if !self.allow_ty_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 49ad09800a5a..04396c883d3a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -93,7 +93,7 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) { /// Check that the fields of the `union` do not need dropping. fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool { - let item_type = tcx.type_of(item_def_id); + let item_type = tcx.type_of(item_def_id).subst_identity(); if let ty::Adt(def, substs) = item_type.kind() { assert!(def.is_union()); @@ -170,7 +170,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // would be enough to check this for `extern` statics, as statics with an initializer will // have UB during initialization if they are uninhabited, but there also seems to be no good // reason to allow any statics to be uninhabited. - let ty = tcx.type_of(def_id); + let ty = tcx.type_of(def_id).subst_identity(); let span = tcx.def_span(def_id); let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) { Ok(l) => l, @@ -227,7 +227,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { if !tcx.features().impl_trait_projections { check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span); } - if tcx.type_of(item.owner_id.def_id).references_error() { + if tcx.type_of(item.owner_id.def_id).subst_identity().references_error() { return; } if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() { @@ -425,7 +425,7 @@ fn check_opaque_meets_bounds<'tcx>( // // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it // here rather than using ReErased. - let hidden_ty = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs); + let hidden_ty = tcx.type_of(def_id.to_def_id()).subst(tcx, substs); let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() { ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), _ => re, @@ -492,7 +492,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>( fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() { - if match tcx.type_of(def_id).kind() { + if match tcx.type_of(def_id).subst_identity().kind() { ty::RawPtr(_) => false, ty::Adt(adt_def, substs) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *substs), _ => true, @@ -537,7 +537,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { let assoc_items = tcx.associated_items(id.owner_id); check_on_unimplemented(tcx, id); - for assoc_item in assoc_items.in_definition_order() { + for &assoc_item in assoc_items.in_definition_order() { match assoc_item.kind { ty::AssocKind::Fn => { let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi(); @@ -578,7 +578,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } } DefKind::TyAlias => { - let pty_ty = tcx.type_of(id.owner_id); + let pty_ty = tcx.type_of(id.owner_id).subst_identity(); let generics = tcx.generics_of(id.owner_id); check_type_params_are_used(tcx, &generics, pty_ty); } @@ -670,7 +670,7 @@ pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) { pub(super) fn check_specialization_validity<'tcx>( tcx: TyCtxt<'tcx>, trait_def: &ty::TraitDef, - trait_item: &ty::AssocItem, + trait_item: ty::AssocItem, impl_id: DefId, impl_item: DefId, ) { @@ -767,17 +767,17 @@ fn check_impl_items_against_trait<'tcx>( )); } ty::AssocKind::Fn => { - compare_impl_method(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); + compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_ref); } ty::AssocKind::Type => { - compare_impl_ty(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); + compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_ref); } } check_specialization_validity( tcx, trait_def, - &ty_trait_item, + ty_trait_item, impl_id.to_def_id(), impl_item, ); @@ -854,7 +854,7 @@ fn check_impl_items_against_trait<'tcx>( } pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { - let t = tcx.type_of(def_id); + let t = tcx.type_of(def_id).subst_identity(); if let ty::Adt(def, substs) = t.kind() && def.is_struct() { @@ -974,7 +974,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { &if first { format!( "`{}` contains a field of type `{}`", - tcx.type_of(def.did()), + tcx.type_of(def.did()).subst_identity(), ident ) } else { @@ -996,7 +996,7 @@ pub(super) fn check_packed_inner( def_id: DefId, stack: &mut Vec, ) -> Option> { - if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() { + if let ty::Adt(def, substs) = tcx.type_of(def_id).subst_identity().kind() { if def.is_struct() || def.is_union() { if def.repr().align.is_some() { return Some(vec![(def.did(), DUMMY_SP)]); 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 6b0eade2d326..a9fcc8e62501 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -37,8 +37,8 @@ use std::iter; /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation pub(super) fn compare_impl_method<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) { debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); @@ -129,8 +129,8 @@ pub(super) fn compare_impl_method<'tcx>( #[instrument(level = "debug", skip(tcx, impl_trait_ref))] fn compare_method_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, check_implied_wf: CheckImpliedWfMode, ) -> Result<(), ErrorGuaranteed> { @@ -381,8 +381,8 @@ fn compare_method_predicate_entailment<'tcx>( fn extract_bad_args_for_implies_lint<'tcx>( tcx: TyCtxt<'tcx>, errors: &[infer::RegionResolutionError<'tcx>], - (trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>), - (impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>), + (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>), + (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>), hir_id: hir::HirId, ) -> Vec<(Span, Option)> { let mut blame_generics = vec![]; @@ -464,14 +464,10 @@ impl<'tcx> TypeFolder> 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 } @@ -480,7 +476,7 @@ impl<'tcx> TypeFolder> for RemapLateBound<'_, 'tcx> { fn emit_implied_wf_lint<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, + impl_m: ty::AssocItem, hir_id: hir::HirId, bad_args: Vec<(Span, Option)>, ) { @@ -527,8 +523,8 @@ enum CheckImpliedWfMode { fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, ) -> Result<(), ErrorGuaranteed> { if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async { match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() { @@ -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); @@ -873,8 +869,8 @@ fn report_trait_method_mismatch<'tcx>( infcx: &InferCtxt<'tcx>, mut cause: ObligationCause<'tcx>, terr: TypeError<'tcx>, - (trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>), - (impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>), + (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>), + (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>), impl_trait_ref: ty::TraitRef<'tcx>, ) -> ErrorGuaranteed { let tcx = infcx.tcx; @@ -967,8 +963,8 @@ fn report_trait_method_mismatch<'tcx>( fn check_region_bounds_on_impl_item<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, delay: bool, ) -> Result<(), ErrorGuaranteed> { let impl_generics = tcx.generics_of(impl_m.def_id); @@ -1042,7 +1038,7 @@ fn check_region_bounds_on_impl_item<'tcx>( .sess .create_err(LifetimesOrBoundsMismatchOnTrait { span, - item_kind: assoc_item_kind_str(impl_m), + item_kind: assoc_item_kind_str(&impl_m), ident: impl_m.ident(tcx), generics_span, bounds_span, @@ -1060,8 +1056,8 @@ fn extract_spans_for_error_reporting<'tcx>( infcx: &infer::InferCtxt<'tcx>, terr: TypeError<'_>, cause: &ObligationCause<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, ) -> (Span, Option) { let tcx = infcx.tcx; let mut impl_args = { @@ -1084,8 +1080,8 @@ fn extract_spans_for_error_reporting<'tcx>( fn compare_self_type<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { // Try to give more informative error messages about self typing @@ -1096,7 +1092,7 @@ fn compare_self_type<'tcx>( // inscrutable, particularly for cases where one method has no // self. - let self_string = |method: &ty::AssocItem| { + let self_string = |method: ty::AssocItem| { let untransformed_self_ty = match method.container { ty::ImplContainer => impl_trait_ref.self_ty(), ty::TraitContainer => tcx.types.self_param, @@ -1186,8 +1182,8 @@ fn compare_self_type<'tcx>( /// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters fn compare_number_of_generics<'tcx>( tcx: TyCtxt<'tcx>, - impl_: &ty::AssocItem, - trait_: &ty::AssocItem, + impl_: ty::AssocItem, + trait_: ty::AssocItem, delay: bool, ) -> Result<(), ErrorGuaranteed> { let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts(); @@ -1207,7 +1203,7 @@ fn compare_number_of_generics<'tcx>( ("const", trait_own_counts.consts, impl_own_counts.consts), ]; - let item_kind = assoc_item_kind_str(impl_); + let item_kind = assoc_item_kind_str(&impl_); let mut err_occurred = None; for (kind, trait_count, impl_count) in matchings { @@ -1329,8 +1325,8 @@ fn compare_number_of_generics<'tcx>( fn compare_number_of_method_arguments<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, ) -> Result<(), ErrorGuaranteed> { let impl_m_fty = tcx.fn_sig(impl_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id); @@ -1409,8 +1405,8 @@ fn compare_number_of_method_arguments<'tcx>( fn compare_synthetic_generics<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &ty::AssocItem, - trait_m: &ty::AssocItem, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, ) -> Result<(), ErrorGuaranteed> { // FIXME(chrisvittal) Clean up this function, list of FIXME items: // 1. Better messages for the span labels @@ -1563,8 +1559,8 @@ fn compare_synthetic_generics<'tcx>( /// This function does not handle lifetime parameters fn compare_generic_param_kinds<'tcx>( tcx: TyCtxt<'tcx>, - impl_item: &ty::AssocItem, - trait_item: &ty::AssocItem, + impl_item: ty::AssocItem, + trait_item: ty::AssocItem, delay: bool, ) -> Result<(), ErrorGuaranteed> { assert_eq!(impl_item.kind, trait_item.kind); @@ -1609,7 +1605,11 @@ fn compare_generic_param_kinds<'tcx>( let make_param_message = |prefix: &str, param: &ty::GenericParamDef| match param.kind { Const { .. } => { - format!("{} const parameter of type `{}`", prefix, tcx.type_of(param.def_id)) + format!( + "{} const parameter of type `{}`", + prefix, + tcx.type_of(param.def_id).subst_identity() + ) } Type { .. } => format!("{} type parameter", prefix), Lifetime { .. } => unreachable!(), @@ -1658,8 +1658,8 @@ pub(super) fn compare_impl_const_raw( // Create a parameter environment that represents the implementation's // method. // Compute placeholder form of impl and trait const tys. - let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()); - let trait_ty = tcx.bound_type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs); + let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()).subst_identity(); + let trait_ty = tcx.type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs); let mut cause = ObligationCause::new( impl_c_span, impl_const_item_def, @@ -1736,8 +1736,8 @@ pub(super) fn compare_impl_const_raw( pub(super) fn compare_impl_ty<'tcx>( tcx: TyCtxt<'tcx>, - impl_ty: &ty::AssocItem, - trait_ty: &ty::AssocItem, + impl_ty: ty::AssocItem, + trait_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) { debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); @@ -1754,8 +1754,8 @@ pub(super) fn compare_impl_ty<'tcx>( /// instead of associated functions. fn compare_type_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, - impl_ty: &ty::AssocItem, - trait_ty: &ty::AssocItem, + impl_ty: ty::AssocItem, + trait_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); @@ -1855,8 +1855,8 @@ fn compare_type_predicate_entailment<'tcx>( #[instrument(level = "debug", skip(tcx))] pub(super) fn check_type_bounds<'tcx>( tcx: TyCtxt<'tcx>, - trait_ty: &ty::AssocItem, - impl_ty: &ty::AssocItem, + trait_ty: ty::AssocItem, + impl_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { // Given @@ -1920,10 +1920,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 { .. } => { @@ -1931,17 +1931,17 @@ pub(super) fn check_type_bounds<'tcx>( bound_vars.push(bound_var); tcx.mk_const( ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)), - tcx.type_of(param.def_id), + tcx.type_of(param.def_id).subst_identity(), ) .into() } }); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let impl_ty_substs = tcx.intern_substs(&substs); let container_id = impl_ty.container_id(tcx); let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); - let impl_ty_value = tcx.type_of(impl_ty.def_id); + let impl_ty_value = tcx.type_of(impl_ty.def_id).subst_identity(); let param_env = tcx.param_env(impl_ty.def_id); diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 64fd61c1359b..c84e3461226d 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -27,7 +27,7 @@ use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; /// cannot do `struct S; impl Drop for S { ... }`). /// pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> { - let dtor_self_type = tcx.type_of(drop_impl_did); + let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity(); let dtor_predicates = tcx.predicates_of(drop_impl_did); match dtor_self_type.kind() { ty::Adt(adt_def, self_to_impl_substs) => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 955cacf03b1c..4720fea8ef4a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -15,8 +15,6 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; -use std::iter; - fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, it: &hir::ForeignItem<'_>, @@ -139,25 +137,21 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let intrinsic_name = tcx.item_name(intrinsic_id); let name_str = intrinsic_name.as_str(); - let bound_vars = tcx.mk_bound_variable_kinds( - [ - ty::BoundVariableKind::Region(ty::BrAnon(0, None)), - ty::BoundVariableKind::Region(ty::BrEnv), - ] - .iter() - .copied(), - ); + let bound_vars = tcx.intern_bound_variable_kinds(&[ + ty::BoundVariableKind::Region(ty::BrAnon(0, None)), + ty::BoundVariableKind::Region(ty::BrEnv), + ]); 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()]); + ); + let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) }; @@ -377,24 +371,22 @@ 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)), - ], - tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())), + vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))], + tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])), ) } kw::Try => { let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8); let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(mut_u8), + [mut_u8], tcx.mk_unit(), false, hir::Unsafety::Normal, Abi::Rust, )); let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - [mut_u8, mut_u8].iter().cloned(), + [mut_u8, mut_u8], tcx.mk_unit(), false, hir::Unsafety::Normal, @@ -430,8 +422,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) } @@ -450,7 +441,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, 0, inputs, output, unsafety) }; - let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); + let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic); let sig = ty::Binder::bind_with_vars(sig, bound_vars); equate_intrinsic_type(tcx, it, n_tps, n_lts, sig) } @@ -548,13 +539,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) } }; - let sig = tcx.mk_fn_sig( - inputs.into_iter(), - output, - false, - hir::Unsafety::Unsafe, - Abi::PlatformIntrinsic, - ); + let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic); let sig = ty::Binder::dummy(sig); equate_intrinsic_type(tcx, it, n_tps, 0, sig) } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 56ac18c49279..b3e76010da34 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -414,7 +414,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that sym actually points to a function. Later passes // depend on this. hir::InlineAsmOperand::SymFn { anon_const } => { - let ty = self.tcx.type_of(anon_const.def_id); + let ty = self.tcx.type_of(anon_const.def_id).subst_identity(); match ty.kind() { ty::Never | ty::Error(_) => {} ty::FnDef(..) => {} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 7b013cabc3ab..9acfc1b3d292 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -199,7 +199,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp fn missing_items_err( tcx: TyCtxt<'_>, impl_span: Span, - missing_items: &[&ty::AssocItem], + missing_items: &[ty::AssocItem], full_impl_span: Span, ) { let missing_items_msg = missing_items @@ -225,7 +225,7 @@ fn missing_items_err( let padding = tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new()); - for trait_item in missing_items { + for &trait_item in missing_items { let snippet = suggestion_signature(trait_item, tcx); let code = format!("{}{}\n{}", padding, snippet, padding); let msg = format!("implement the missing item: `{snippet}`"); @@ -272,7 +272,7 @@ fn default_body_is_unstable( reason: Option, issue: Option, ) { - let missing_item_name = &tcx.associated_item(item_did).name; + let missing_item_name = tcx.associated_item(item_did).name; let use_of_unstable_library_feature_note = match reason { Some(r) => format!("use of unstable library feature '{feature}': {r}"), None => format!("use of unstable library feature '{feature}'"), @@ -365,7 +365,7 @@ fn fn_sig_suggestion<'tcx>( sig: ty::FnSig<'tcx>, ident: Ident, predicates: ty::GenericPredicates<'tcx>, - assoc: &ty::AssocItem, + assoc: ty::AssocItem, ) -> String { let args = sig .inputs() @@ -433,7 +433,7 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { /// Return placeholder code for the given associated item. /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a /// structured suggestion. -fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { +fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { match assoc.kind { ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all @@ -450,7 +450,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { } ty::AssocKind::Type => format!("type {} = Type;", assoc.name), ty::AssocKind::Const => { - let ty = tcx.type_of(assoc.def_id); + let ty = tcx.type_of(assoc.def_id).subst_identity(); let val = ty_kind_suggestion(ty).unwrap_or("value"); format!("const {}: {} = {};", assoc.name, ty, val) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c64d507f8284..66c3904af963 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), @@ -877,7 +874,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { // Const parameters are well formed if their type is structural match. hir::GenericParamKind::Const { ty: hir_ty, default: _ } => { - let ty = tcx.type_of(param.def_id); + let ty = tcx.type_of(param.def_id).subst_identity(); if tcx.features().adt_const_params { if let Some(non_structural_match_ty) = @@ -1014,12 +1011,12 @@ fn check_associated_item( let self_ty = match item.container { ty::TraitContainer => tcx.types.self_param, - ty::ImplContainer => tcx.type_of(item.container_id(tcx)), + ty::ImplContainer => tcx.type_of(item.container_id(tcx)).subst_identity(), }; match item.kind { ty::AssocKind::Const => { - let ty = tcx.type_of(item.def_id); + let ty = tcx.type_of(item.def_id).subst_identity(); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } @@ -1040,7 +1037,7 @@ fn check_associated_item( check_associated_type_bounds(wfcx, item, span) } if item.defaultness(tcx).has_value() { - let ty = tcx.type_of(item.def_id); + let ty = tcx.type_of(item.def_id).subst_identity(); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } @@ -1073,7 +1070,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = tcx.hir().get_by_def_id(field_id).expect_field(); - let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did)); + let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity()); wfcx.register_wf_obligation( hir_ty.span, Some(WellFormedLoc::Ty(field_id)), @@ -1085,7 +1082,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b // intermediate types must be sized. let needs_drop_copy = || { packed && { - let ty = tcx.type_of(variant.fields.last().unwrap().did); + let ty = tcx.type_of(variant.fields.last().unwrap().did).subst_identity(); let ty = tcx.erase_regions(ty); if ty.needs_infer() { tcx.sess @@ -1107,7 +1104,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = tcx.hir().get_by_def_id(field_id).expect_field(); - let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did)); + let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did).subst_identity()); wfcx.register_bound( traits::ObligationCause::new( hir_ty.span, @@ -1183,7 +1180,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { /// /// Assuming the defaults are used, check that all predicates (bounds on the /// assoc type and where clauses on the trait) hold. -fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: &ty::AssocItem, span: Span) { +fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, span: Span) { let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); @@ -1218,7 +1215,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo debug!("check_item_type: {:?}", item_id); enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| { - let ty = tcx.type_of(item_id); + let ty = tcx.type_of(item_id).subst_identity(); let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty); let mut forbid_unsized = true; @@ -1303,7 +1300,7 @@ fn check_impl<'tcx>( wfcx.register_obligations(obligations); } None => { - let self_ty = tcx.type_of(item.owner_id); + let self_ty = tcx.type_of(item.owner_id).subst_identity(); let self_ty = wfcx.normalize( item.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), @@ -1348,7 +1345,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id match param.kind { GenericParamDefKind::Type { .. } => { if is_our_default(param) { - let ty = tcx.type_of(param.def_id); + let ty = tcx.type_of(param.def_id).subst_identity(); // Ignore dependent defaults -- that is, where the default of one type // parameter includes another (e.g., ``). In those cases, we can't // be sure if it will error or not as user might always specify the other. @@ -1400,7 +1397,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id GenericParamDefKind::Type { .. } => { // If the param has a default, ... if is_our_default(param) { - let default_ty = tcx.type_of(param.def_id); + let default_ty = tcx.type_of(param.def_id).subst_identity(); // ... and it's not a dependent default, ... if !default_ty.needs_subst() { // ... then substitute it with the default. @@ -1633,7 +1630,7 @@ const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut se fn check_method_receiver<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, fn_sig: &hir::FnSig<'_>, - method: &ty::AssocItem, + method: ty::AssocItem, self_ty: Ty<'tcx>, ) { let tcx = wfcx.tcx(); @@ -1816,7 +1813,7 @@ fn check_variances_for_type_defn<'tcx>( item: &hir::Item<'tcx>, hir_generics: &hir::Generics<'_>, ) { - let ty = tcx.type_of(item.owner_id); + let ty = tcx.type_of(item.owner_id).subst_identity(); if tcx.has_error_field(ty) { return; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index c0ba385987d7..51c5f2970519 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -50,7 +50,7 @@ impl<'tcx> Checker<'tcx> { fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { // Destructors only work on local ADT types. - match tcx.type_of(impl_did).kind() { + match tcx.type_of(impl_did).subst_identity().kind() { ty::Adt(def, _) if def.did().is_local() => return, ty::Error(_) => return, _ => {} @@ -64,7 +64,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let self_type = tcx.type_of(impl_did); + let self_type = tcx.type_of(impl_did).subst_identity(); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); let param_env = tcx.param_env(impl_did); @@ -206,7 +206,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); - let source = tcx.type_of(impl_did); + let source = tcx.type_of(impl_did).subst_identity(); assert!(!source.has_escaping_bound_vars()); let target = { let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); @@ -370,7 +370,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err.to_string())); }); - let source = tcx.type_of(impl_did); + let source = tcx.type_of(impl_did).subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.substs.type_at(1); @@ -482,7 +482,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn .filter_map(|(i, f)| { let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); - if tcx.type_of(f.did).is_phantom_data() { + if tcx.type_of(f.did).subst_identity().is_phantom_data() { // Ignore PhantomData fields return None; } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index f0b6ab03ad69..02f3eeee0e7e 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -173,7 +173,7 @@ impl<'tcx> InherentCollect<'tcx> { let id = id.owner_id.def_id; let item_span = self.tcx.def_span(id); - let self_ty = self.tcx.type_of(id); + let self_ty = self.tcx.type_of(id).subst_identity(); match *self_ty.kind() { ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), ty::Foreign(did) => self.check_def_id(id, self_ty, did), diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index a9331af4eab3..7bca4edcc8c9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -27,8 +27,8 @@ impl<'tcx> InherentOverlapChecker<'tcx> { /// namespace. fn impls_have_common_items( &self, - impl_items1: &ty::AssocItems<'_>, - impl_items2: &ty::AssocItems<'_>, + impl_items1: &ty::AssocItems, + impl_items2: &ty::AssocItems, ) -> bool { let mut impl_items1 = &impl_items1; let mut impl_items2 = &impl_items2; @@ -38,10 +38,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> { std::mem::swap(&mut impl_items1, &mut impl_items2); } - for item1 in impl_items1.in_definition_order() { + for &item1 in impl_items1.in_definition_order() { let collision = impl_items2 .filter_by_name_unhygienic(item1.name) - .any(|item2| self.compare_hygienically(item1, item2)); + .any(|&item2| self.compare_hygienically(item1, item2)); if collision { return true; @@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { false } - fn compare_hygienically(&self, item1: &ty::AssocItem, item2: &ty::AssocItem) -> bool { + fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool { // Symbols and namespace match, compare hygienically. item1.kind.namespace() == item2.kind.namespace() && item1.ident(self.tcx).normalize_to_macros_2_0() @@ -98,10 +98,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> { let impl_items1 = self.tcx.associated_items(impl1); let impl_items2 = self.tcx.associated_items(impl2); - for item1 in impl_items1.in_definition_order() { + for &item1 in impl_items1.in_definition_order() { let collision = impl_items2 .filter_by_name_unhygienic(item1.name) - .find(|item2| self.compare_hygienically(item1, item2)); + .find(|&&item2| self.compare_hygienically(item1, item2)); if let Some(item2) = collision { let name = item1.ident(self.tcx).normalize_to_macros_2_0(); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9f33d84ab520..ed3d50bfafa8 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), + }) } ), ), @@ -1145,8 +1143,8 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> } Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { - let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)); - let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id)); + let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity(); + let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).subst_identity()); ty::Binder::dummy(tcx.mk_fn_sig( inputs, ty, @@ -1347,7 +1345,7 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option {} - 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(..) + | rbv::ResolvedArg::Error(_), + ) + | 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 d0d67ae9257c..2badd66e346f 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -9,8 +9,8 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{GenericPredicates, ToPredicate}; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; @@ -151,7 +151,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP trace!(?generics); // Collect the predicates that were written inline by the user on each - // type parameter (e.g., ``). + // type parameter (e.g., ``). Also add `ConstArgHasType` predicates + // for each const parameter. for param in ast_generics.params { match param.kind { // We already dealt with early bound lifetimes above. @@ -175,7 +176,19 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP trace!(?predicates); } GenericParamKind::Const { .. } => { - // Bounds on const parameters are currently not possible. + let name = param.name.ident().name; + let param_const = ty::ParamConst::new(index, name); + + let ct_ty = tcx.type_of(param.def_id.to_def_id()).subst_identity(); + + let ct = tcx.mk_const(param_const, ct_ty); + + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::ConstArgHasType(ct, ct_ty), + )) + .to_predicate(tcx); + predicates.insert((predicate, param.span)); + index += 1; } } @@ -251,7 +264,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // in trait checking. See `setup_constraining_predicates` // for details. if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { - let self_ty = tcx.type_of(def_id); + let self_ty = tcx.type_of(def_id).subst_identity(); let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::subst_identity); cgp::setup_constraining_predicates( tcx, @@ -284,11 +297,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), @@ -439,7 +452,9 @@ pub(super) fn explicit_predicates_of<'tcx>( let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let parent_def_id = tcx.hir().get_parent_item(hir_id); - if tcx.hir().opt_const_param_default_param_def_id(hir_id).is_some() { + if let Some(defaulted_param_def_id) = + tcx.hir().opt_const_param_default_param_def_id(hir_id) + { // In `generics_of` we set the generics' parent to be our parent's parent which means that // we lose out on the predicates of our actual parent if we dont return those predicates here. // (See comment in `generics_of` for more information on why the parent shenanigans is necessary) @@ -452,7 +467,39 @@ pub(super) fn explicit_predicates_of<'tcx>( // // In the above code we want the anon const to have predicates in its param env for `T: Trait` // and we would be calling `explicit_predicates_of(Foo)` here - return tcx.explicit_predicates_of(parent_def_id); + let parent_preds = tcx.explicit_predicates_of(parent_def_id); + + // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter + // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution + // to #106994 is implemented. + let filtered_predicates = parent_preds + .predicates + .into_iter() + .filter(|(pred, _)| { + if let ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, _)) = + pred.kind().skip_binder() + { + match ct.kind() { + ty::ConstKind::Param(param_const) => { + let defaulted_param_idx = tcx + .generics_of(parent_def_id) + .param_def_id_to_index[&defaulted_param_def_id.to_def_id()]; + param_const.index < defaulted_param_idx + } + _ => bug!( + "`ConstArgHasType` in `predicates_of`\ + that isn't a `Param` const" + ), + } + } else { + true + } + }) + .cloned(); + return GenericPredicates { + parent: parent_preds.parent, + predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, + }; } let parent_def_kind = tcx.def_kind(parent_def_id); diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs similarity index 84% rename from compiler/rustc_hir_analysis/src/collect/lifetimes.rs rename to compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d8606f759b24..c0c90e47a753 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; - 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 { match *self { - Region::Static => None, + ResolvedArg::StaticLifetime | ResolvedArg::Error(_) => 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, +struct NamedVarMap { + // maps from every use of a named (not anonymous) bound var to a + // `ResolvedArg` describing how that variable is bound + defs: HirIdMap, // Maps relevant hir items to the bound vars on them. These include: // - function defs @@ -87,9 +89,9 @@ struct NamedRegionMap { late_bound_vars: HirIdMap>, } -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, + bound_vars: FxIndexMap, 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, + lifetime: Option, 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, + bound_vars: Vec, 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, 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,64 @@ 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); } } } } + + fn visit_poly_trait_ref_inner( + &mut self, + trait_ref: &'tcx hir::PolyTraitRef<'tcx>, + non_lifetime_binder_allowed: NonLifetimeBinderAllowed, + ) { + debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref); + + let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); + + let initial_bound_vars = binders.len() as u32; + let mut bound_vars: FxIndexMap = 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); + + if let NonLifetimeBinderAllowed::Deny(where_) = non_lifetime_binder_allowed { + deny_non_region_late_bound(self.tcx, &mut bound_vars, where_); + } + + debug!(?binders); + self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders); + + // Always introduce a scope here, even if this is in a where clause and + // we introduced the binders around the bounded Ty. In that case, we + // just reuse the concatenation functionality also present in nested trait + // refs. + let scope = Scope::Binder { + hir_id: trait_ref.trait_ref.hir_ref_id, + bound_vars, + s: self.scope, + scope_type, + where_bound_origin: None, + }; + self.with(scope, |this| { + walk_list!(this, visit_generic_param, trait_ref.bound_generic_params); + this.visit_trait_ref(&trait_ref.trait_ref); + }); + } } -impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { + +enum NonLifetimeBinderAllowed { + Deny(&'static str), + Allow, +} + +impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Self::Map { @@ -386,22 +450,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } - let (lifetimes, binders): (FxIndexMap, Vec<_>) = + let (mut bound_vars, binders): (FxIndexMap, 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(); + deny_non_region_late_bound(self.tcx, &mut bound_vars, "closures"); + 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 +526,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`. 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 +544,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 +580,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 +619,23 @@ 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, Vec<_>) = c + let (mut bound_vars, binders): (FxIndexMap, 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(); + + deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types"); + 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, @@ -592,7 +651,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let scope = Scope::TraitRefBoundary { s: self.scope }; self.with(scope, |this| { for bound in bounds { - this.visit_poly_trait_ref(bound); + this.visit_poly_trait_ref_inner( + bound, + NonLifetimeBinderAllowed::Deny("trait object types"), + ); } }); match lifetime.res { @@ -674,7 +736,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 +784,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 +823,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }), Type(ty) => { let generics = &impl_item.generics; - let lifetimes: FxIndexMap = 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 = + 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 +852,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 +865,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 +923,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { origin, .. }) => { - let lifetimes: FxIndexMap = + + let (bound_vars, binders): (FxIndexMap, 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 +941,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 +967,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 +1011,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, @@ -978,43 +1025,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) { - debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref); - - let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); - - let initial_bound_vars = binders.len() as u32; - let mut lifetimes: FxIndexMap = 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); - r - }); - binders.extend(binders_iter); - - debug!(?binders); - self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders); - - // Always introduce a scope here, even if this is in a where clause and - // we introduced the binders around the bounded Ty. In that case, we - // just reuse the concatenation functionality also present in nested trait - // refs. - let scope = Scope::Binder { - hir_id: trait_ref.trait_ref.hir_ref_id, - lifetimes, - s: self.scope, - scope_type, - where_bound_origin: None, - }; - self.with(scope, |this| { - walk_list!(this, visit_generic_param, trait_ref.bound_generic_params); - this.visit_trait_ref(&trait_ref.trait_ref); - }); + self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow); } } @@ -1063,13 +1074,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(&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 +1121,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 = generics + let bound_vars: FxIndexMap = 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 +1152,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 +1190,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 +1272,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 +1288,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 +1342,59 @@ 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; + } + + self.tcx + .sess + .delay_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 +1481,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 +1573,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 +1608,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 +1693,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 +1708,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 +1716,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)); } @@ -1804,7 +1875,7 @@ fn is_late_bound_map( let mut walker = ConstrainedCollectorPostAstConv { arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(), }; - walker.visit_ty(self.tcx.type_of(alias_def)); + walker.visit_ty(self.tcx.type_of(alias_def).subst_identity()); match segments.last() { Some(hir::PathSegment { args: Some(args), .. }) => { @@ -1872,3 +1943,37 @@ fn is_late_bound_map( } } } + +pub fn deny_non_region_late_bound( + tcx: TyCtxt<'_>, + bound_vars: &mut FxIndexMap, + where_: &str, +) { + let mut first = true; + + for (var, arg) in bound_vars { + let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else { + bug!(); + }; + + let what = match param.kind { + hir::GenericParamKind::Type { .. } => "type", + hir::GenericParamKind::Const { .. } => "const", + hir::GenericParamKind::Lifetime { .. } => continue, + }; + + let mut diag = tcx.sess.struct_span_err( + param.span, + format!("late-bound {what} parameter not allowed on {where_}"), + ); + + let guar = if tcx.features().non_lifetime_binders && first { + diag.emit() + } else { + diag.delay_as_bug() + }; + + first = false; + *arg = ResolvedArg::Error(guar); + } +} diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 54fcccb0c11e..a3bc0082ef20 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -243,7 +243,7 @@ fn get_path_containing_arg_in_pat<'hir>( arg_path } -pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { +pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> { let def_id = def_id.expect_local(); use rustc_hir::*; @@ -251,7 +251,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let icx = ItemCtxt::new(tcx, def_id.to_def_id()); - match tcx.hir().get(hir_id) { + let output = match tcx.hir().get(hir_id) { Node::TraitItem(item) => match item.kind { TraitItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); @@ -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), @@ -382,7 +377,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { VariantData::Unit(..) | VariantData::Struct(..) => { - tcx.type_of(tcx.hir().get_parent_item(hir_id)) + tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity() } VariantData::Tuple(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); @@ -399,7 +394,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => { // We defer to `type_of` of the corresponding parameter // for generic arguments. - tcx.type_of(param) + tcx.type_of(param).subst_identity() } Node::AnonConst(_) => { @@ -451,7 +446,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { && e.hir_id == hir_id => { let Some(trait_def_id) = trait_ref.trait_def_id() else { - return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); }; let assoc_items = tcx.associated_items(trait_def_id); let assoc_item = assoc_items.find_by_name_and_kind( @@ -461,7 +456,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { def_id.to_def_id(), ); if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) + tcx.type_of(assoc_item.def_id).subst_identity() } else { // FIXME(associated_const_equality): add a useful error message here. tcx.ty_error_with_message( @@ -485,7 +480,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }) => { let Some(trait_def_id) = trait_ref.trait_def_id() else { - return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); }; let assoc_items = tcx.associated_items(trait_def_id); let assoc_item = assoc_items.find_by_name_and_kind( @@ -506,7 +501,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { if let Some(param) = assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const()) { - tcx.type_of(param.def_id) + tcx.type_of(param.def_id).subst_identity() } else { // FIXME(associated_const_equality): add a useful error message here. tcx.ty_error_with_message( @@ -520,7 +515,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { def_id: param_def_id, kind: GenericParamKind::Const { default: Some(ct), .. }, .. - }) if ct.hir_id == hir_id => tcx.type_of(param_def_id), + }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(), x => tcx.ty_error_with_message( DUMMY_SP, @@ -538,7 +533,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { x => { bug!("unexpected sort of node in type_of(): {:?}", x); } - } + }; + ty::EarlyBinder(output) } #[instrument(skip(tcx), level = "debug")] diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 4f30318412d7..8ab9964d8100 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -70,7 +70,7 @@ pub fn provide(providers: &mut Providers) { fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { // Every lifetime used in an associated type must be constrained. - let impl_self_ty = tcx.type_of(impl_def_id); + let impl_self_ty = tcx.type_of(impl_def_id).subst_identity(); if impl_self_ty.references_error() { // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) @@ -104,7 +104,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) match item.kind { ty::AssocKind::Type => { if item.defaultness(tcx).has_value() { - cgp::parameters_for(&tcx.type_of(def_id), true) + cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true) } else { Vec::new() } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 02f77f9d6afb..4741e4b095d2 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -496,6 +496,16 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc ) .emit(); } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + // FIXME(min_specialization), FIXME(const_generics): + // It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure + // about the actual rules that would be sound. Can't just always error here because otherwise + // std/core doesn't even compile as they have `const N: usize` in some specializing impls. + // + // While we do not support constructs like `` there is probably no risk of + // soundness bugs, but when we support generic const parameter types this will need to be + // revisited. + } _ => { tcx.sess .struct_span_err(span, &format!("cannot specialize on predicate `{}`", predicate)) @@ -517,6 +527,7 @@ fn trait_predicate_kind<'tcx>( ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::Projection(_)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::Subtype(_) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index c2fa46e563e6..11240cf22e4b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -113,7 +113,6 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; -use std::iter; use std::ops::Not; use astconv::AstConv; @@ -187,7 +186,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { if let Some(local_def_id) = def_id.as_local() { - let hir_type = tcx.type_of(local_def_id); + let hir_type = tcx.type_of(local_def_id).subst_identity(); if !matches!(hir_type.kind(), ty::FnDef(..)) { span_bug!(sp, "main has a non-function type: found `{}`", hir_type); } @@ -204,7 +203,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"); @@ -348,7 +347,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { } let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| { - tcx.mk_fn_sig(iter::empty(), expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) + tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) })); require_same_types( @@ -366,7 +365,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { let start_def_id = start_def_id.expect_local(); let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id); let start_span = tcx.def_span(start_def_id); - let start_t = tcx.type_of(start_def_id); + let start_t = tcx.type_of(start_def_id).subst_identity(); match start_t.kind() { ty::FnDef(..) => { if let Some(Node::Item(it)) = tcx.hir().find(start_id) { @@ -434,7 +433,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { } let se_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - [tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(), + [tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))], tcx.types.isize, false, hir::Unsafety::Normal, diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index ecd6849426db..9ee6785970c4 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -54,6 +54,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::ObjectSafe(..) diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index 925042436dec..a8b33c74bc1e 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -46,7 +46,7 @@ pub(super) fn infer_predicates( // For field of type &'a T (reference) or Adt // (struct/enum/union) there will be outlive // requirements for adt_def. - let field_ty = tcx.type_of(field_def.did); + let field_ty = tcx.type_of(field_def.did).subst_identity(); let field_span = tcx.def_span(field_def.did); insert_required_predicates_to_be_wf( tcx, diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 9133e6540d44..560ffc620e0d 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -423,7 +423,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn get_unbound_associated_types(&self) -> Vec { if self.tcx.is_trait(self.def_id) { - let items: &AssocItems<'_> = self.tcx.associated_items(self.def_id); + let items: &AssocItems = self.tcx.associated_items(self.def_id); items .in_definition_order() .filter(|item| item.kind == AssocKind::Type) diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index b0cf0387f87a..408bec71ee01 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let inferred_start = self.terms_cx.inferred_starts[&def_id]; let current_item = &CurrentItem { inferred_start }; - match tcx.type_of(def_id).kind() { + match tcx.type_of(def_id).subst_identity().kind() { ty::Adt(def, _) => { // Not entirely obvious: constraints on structs/enums do not // affect the variance of their type parameters. See discussion @@ -112,7 +112,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { for field in def.all_fields() { self.add_constraints_from_ty( current_item, - tcx.type_of(field.did), + tcx.type_of(field.did).subst_identity(), self.covariant, ); } diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs index a17edb598ad5..c27c176e35f5 100644 --- a/compiler/rustc_hir_analysis/src/variance/solve.rs +++ b/compiler/rustc_hir_analysis/src/variance/solve.rs @@ -103,7 +103,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { self.enforce_const_invariance(generics, variances); // Functions are permitted to have unused generic parameters: make those invariant. - if let ty::FnDef(..) = tcx.type_of(def_id).kind() { + if let ty::FnDef(..) = tcx.type_of(def_id).subst_identity().kind() { for variance in variances.iter_mut() { if *variance == ty::Bivariant { *variance = ty::Invariant; diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 05f6d8e60721..bf8259ff70fa 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.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); @@ -266,7 +264,7 @@ fn check_lang_start_fn<'tcx>( let fn_generic = generics.param_at(0, tcx); let generic_ty = tcx.mk_ty_param(fn_generic.index, fn_generic.name); let expected_fn_sig = - tcx.mk_fn_sig([].iter(), &generic_ty, false, hir::Unsafety::Normal, Abi::Rust); + tcx.mk_fn_sig([], generic_ty, false, hir::Unsafety::Normal, Abi::Rust); let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig)); // we emit the same error to suggest changing the arg no matter what's wrong with the arg diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index b1268c5f7923..cf296a7bf653 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - iter::once(self.tcx.intern_tup(sig.inputs())), + [self.tcx.intern_tup(sig.inputs())], sig.output(), sig.c_variadic, sig.unsafety, @@ -326,7 +326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?ret_param_ty); let sig = projection.rebind(self.tcx.mk_fn_sig( - input_tys.iter(), + input_tys, ret_param_ty, false, hir::Unsafety::Normal, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 7173239ba619..ba503bf47e70 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 76e87a9e5662..879a64fc0fb9 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) { @@ -2037,7 +2037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args: &[hir::Expr<'_>], kind: CallableKind| { let arg_idx = args.iter().position(|a| a.hir_id == expr.hir_id).unwrap(); - let fn_ty = self.tcx.bound_type_of(def_id).0; + let fn_ty = self.tcx.type_of(def_id).skip_binder(); if !fn_ty.is_fn() { return; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 52c2dabee293..5b641be062be 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -663,6 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) @@ -776,9 +777,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let def_kind = self.tcx.def_kind(def_id); let item_ty = if let DefKind::Variant = def_kind { - self.tcx.bound_type_of(self.tcx.parent(def_id)) + self.tcx.type_of(self.tcx.parent(def_id)) } else { - self.tcx.bound_type_of(def_id) + self.tcx.type_of(def_id) }; let substs = self.fresh_substs_for_item(span, def_id); let ty = item_ty.subst(self.tcx, substs); @@ -1130,7 +1131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(false); let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res { - let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id)); + let ty = self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).subst_identity()); match ty.normalized.ty_adt_def() { Some(adt_def) if adt_def.has_ctor() => { let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap(); @@ -1226,7 +1227,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { let tcx = self.fcx.tcx(); - self.fcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into() + self.fcx + .ct_infer( + tcx.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + Some(param), + inf.span, + ) + .into() } _ => unreachable!(), } @@ -1248,7 +1257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we have a default, then we it doesn't matter that we're not // inferring the type arguments: we provide the default where any // is missing. - tcx.bound_type_of(param.def_id).subst(tcx, substs.unwrap()).into() + tcx.type_of(param.def_id).subst(tcx, substs.unwrap()).into() } else { // If no type arguments were provided, we have to infer them. // This case also occurs as a result of some malformed input, e.g. @@ -1296,7 +1305,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Substitute the values for the type parameters into the type of // the referenced item. - let ty = tcx.bound_type_of(def_id); + let ty = tcx.type_of(def_id); assert!(!substs.has_escaping_bound_vars()); assert!(!ty.0.has_escaping_bound_vars()); let ty_substituted = self.normalize(span, ty.subst(tcx, substs)); @@ -1307,7 +1316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // type parameters, which we can infer by unifying the provided `Self` // with the substituted impl type. // This also occurs for an enum variant on a type alias. - let impl_ty = self.normalize(span, tcx.bound_type_of(impl_def_id).subst(tcx, substs)); + let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).subst(tcx, substs)); let self_ty = self.normalize(span, self_ty); match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) { Ok(ok) => self.register_infer_ok_obligations(ok), 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 f434fb922893..06d6a375697d 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 @@ -312,7 +312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // same rules that check_expr_struct uses for macro hygiene. if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx) { - return Some((expr_field.expr, self.tcx.type_of(field.did))); + return Some((expr_field.expr, self.tcx.type_of(field.did).subst_identity())); } } } @@ -339,7 +339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { receiver: Option<&'tcx hir::Expr<'tcx>>, args: &'tcx [hir::Expr<'tcx>], ) -> bool { - let ty = self.tcx.type_of(def_id); + let ty = self.tcx.type_of(def_id).subst_identity(); if !ty.is_fn() { return false; } @@ -477,19 +477,24 @@ 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> = - 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_or_alias_def_id) { + self.tcx.mk_trait_ref( + obligation.impl_or_alias_def_id, + ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_or_alias_def_id), + ) + } else { + self.tcx + .impl_trait_ref(obligation.impl_or_alias_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. let impl_self_ty: Ty<'tcx> = impl_trait_self_ref.self_ty(); let impl_predicates: ty::GenericPredicates<'tcx> = - self.tcx.predicates_of(obligation.impl_def_id); + self.tcx.predicates_of(obligation.impl_or_alias_def_id); let Some(impl_predicate_index) = obligation.impl_def_predicate_index else { // We don't have the index, so we can only guess. return Err(expr); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9c7a84ce198e..69a7235802bb 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/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 7ce721e94cb2..3539202d1ca6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1378,7 +1378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Same item return false; } - let item_ty = self.tcx.type_of(item.def_id); + let item_ty = self.tcx.type_of(item.def_id).subst_identity(); // FIXME(compiler-errors): This check is *so* rudimentary if item_ty.needs_subst() { return false; diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 29ed9a24ecfd..14e3ba83b103 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}"), @@ -314,7 +312,7 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.iter()); + let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); @@ -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_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 323bacf70ab9..0204beb6fb84 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -154,7 +154,7 @@ fn typeck_const_arg<'tcx>( tcx: TyCtxt<'tcx>, (did, param_did): (LocalDefId, DefId), ) -> &ty::TypeckResults<'tcx> { - let fallback = move || tcx.type_of(param_did); + let fallback = move || tcx.type_of(param_did).subst_identity(); typeck_with_fallback(tcx, did, fallback) } @@ -162,7 +162,7 @@ fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tc if let Some(param_did) = tcx.opt_const_param_of(def_id) { tcx.typeck_const_arg((def_id, param_did)) } else { - let fallback = move || tcx.type_of(def_id.to_def_id()); + let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); typeck_with_fallback(tcx, def_id, fallback) } } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index fa0dc4d84150..f7de55c989fa 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -384,7 +384,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { let tcx = self.cfcx.tcx(); - self.cfcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into() + self.cfcx + .ct_infer( + tcx.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + Some(param), + inf.span, + ) + .into() } _ => unreachable!(), } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index a35fa008a955..0b9226802cf5 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -735,7 +735,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("impl_ty: {:?}", impl_ty); // Determine the receiver type that the method itself expects. - let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs); + let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_substs); debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty); // We can't use normalize_associated_types_in as it will pollute the @@ -796,7 +796,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let new_trait_ref = this.erase_late_bound_regions(new_trait_ref); let (xform_self_ty, xform_ret_ty) = - this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs); + this.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs); this.push_candidate( Candidate { xform_self_ty, @@ -826,6 +826,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) @@ -845,7 +846,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let trait_ref = this.erase_late_bound_regions(poly_trait_ref); let (xform_self_ty, xform_ret_ty) = - this.xform_self_ty(&item, trait_ref.self_ty(), trait_ref.substs); + this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.substs); // Because this trait derives from a where-clause, it // should not contain any inference variables or other @@ -916,7 +917,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn matches_return_type( &self, - method: &ty::AssocItem, + method: ty::AssocItem, self_ty: Option>, expected: Ty<'tcx>, ) -> bool { @@ -965,11 +966,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } else { let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref); - let (xform_self_ty, xform_ret_ty) = self.xform_self_ty( - &item, - new_trait_ref.self_ty(), - new_trait_ref.substs, - ); + let (xform_self_ty, xform_ret_ty) = + self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs); self.push_candidate( Candidate { xform_self_ty, @@ -997,7 +995,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } let (xform_self_ty, xform_ret_ty) = - self.xform_self_ty(&item, trait_ref.self_ty(), trait_substs); + self.xform_self_ty(item, trait_ref.self_ty(), trait_substs); self.push_candidate( Candidate { xform_self_ty, @@ -1024,7 +1022,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .filter(|candidate| candidate_filter(&candidate.item)) .filter(|candidate| { if let Some(return_ty) = self.return_type { - self.matches_return_type(&candidate.item, None, return_ty) + self.matches_return_type(candidate.item, None, return_ty) } else { true } @@ -1576,7 +1574,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { traits::ImplDerivedObligation(Box::new( traits::ImplDerivedObligationCause { derived, - impl_def_id, + impl_or_alias_def_id: impl_def_id, impl_def_predicate_index: None, span, }, @@ -1883,7 +1881,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn xform_self_ty( &self, - item: &ty::AssocItem, + item: ty::AssocItem, impl_ty: Ty<'tcx>, substs: SubstsRef<'tcx>, ) -> (Ty<'tcx>, Option>) { @@ -1940,7 +1938,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, impl_def_id: DefId, ) -> (ty::EarlyBinder>, SubstsRef<'tcx>) { - (self.tcx.bound_type_of(impl_def_id), self.fresh_item_substs(impl_def_id)) + (self.tcx.type_of(impl_def_id), self.fresh_item_substs(impl_def_id)) } fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> { @@ -1958,7 +1956,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { kind: ConstVariableOriginKind::SubstitutionPlaceholder, span, }; - self.next_const_var(self.tcx.type_of(param.def_id), origin).into() + self.next_const_var( + self.tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + origin, + ) + .into() } }) } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 54890489f8b8..6a7b1f6646ab 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -616,7 +616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ObligationCauseCode::ImplDerivedObligation(data) if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) => { - Some((p, parent, data.impl_def_id, data)) + Some((p, parent, data.impl_or_alias_def_id, data)) } _ => None, }) @@ -714,7 +714,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } Some(Node::Item(hir::Item { - ident, kind: hir::ItemKind::Trait(..), .. + ident, + kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..), + .. })) => { skip_list.insert(p); let entry = spanned_predicates.entry(ident.span); @@ -906,8 +908,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // different from the received one // So we avoid suggestion method with Box // for instance - self.tcx.at(span).type_of(*def_id) != rcvr_ty - && self.tcx.at(span).type_of(*def_id) != rcvr_ty + self.tcx.at(span).type_of(*def_id).subst_identity() + != rcvr_ty + && self.tcx.at(span).type_of(*def_id).subst_identity() + != rcvr_ty } (Mode::Path, false, _) => true, _ => false, @@ -927,7 +931,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .take(limit) .map(|impl_item| { - format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) + format!( + "- `{}`", + self.tcx.at(span).type_of(*impl_item).subst_identity() + ) }) .collect::>() .join("\n"); @@ -1104,7 +1111,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None }; - let impl_ty = self.tcx.at(span).type_of(impl_did); + let impl_ty = self.tcx.at(span).type_of(impl_did).subst_identity(); let insertion = match self.tcx.impl_trait_ref(impl_did) { None => String::new(), @@ -1233,7 +1240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. // (#61411) - let impl_ty = self.tcx.type_of(*impl_did); + let impl_ty = self.tcx.type_of(*impl_did).subst_identity(); let target_ty = self .autoderef(sugg_span, rcvr_ty) .find(|(rcvr_ty, _)| { @@ -1453,8 +1460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let range_def_id = self.tcx.require_lang_item(lang_item.unwrap(), None); - let range_ty = - self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]); + let range_ty = self.tcx.type_of(range_def_id).subst(self.tcx, &[actual.into()]); let pick = self.lookup_probe_for_diagnostic( item_name, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index e12a575d5acd..7c8abb4186f1 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -301,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Build a tuple (U0..Un) of the final upvar types U0..Un // and unify the upvar tuple type in the closure with it: - let final_tupled_upvars_type = self.tcx.mk_tup(final_upvar_tys.iter()); + let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys); self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type); let fake_reads = delegate @@ -315,8 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().closure_size_eval.insert( closure_def_id, ClosureSizeProfileData { - before_feature_tys: self.tcx.mk_tup(before_feature_tys.into_iter()), - after_feature_tys: self.tcx.mk_tup(after_feature_tys.into_iter()), + before_feature_tys: self.tcx.intern_tup(&before_feature_tys), + after_feature_tys: self.tcx.intern_tup(&after_feature_tys), }, ); } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 6bfdeda3a246..2b33d31994f2 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> 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 d5cb3fb24984..4552256545b4 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 0c97217bd6a5..b9cb9732ca3e 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/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 964222307bca..f5504b05dc4e 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -125,11 +125,11 @@ impl<'tcx> InferCtxt<'tcx> { } (ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => { - relation.register_type_equate_obligation(a.into(), b.into()); + relation.register_type_equate_obligation(a, b); Ok(b) } (_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => { - relation.register_type_equate_obligation(b.into(), a.into()); + relation.register_type_equate_obligation(b, a); Ok(a) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 2b5a19914a32..cf2f6ef33beb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1062,7 +1062,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let parent_def_id = generics.parent.unwrap(); if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) { - let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs); + let parent_ty = tcx.type_of(parent_def_id).subst(tcx, substs); match (parent_ty.kind(), &ty.kind) { ( ty::Adt(def, substs), 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 39f4d5022598..fec04af23139 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,11 @@ 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(_, _, _) + | rbv::ResolvedArg::Error(_), ) | None, _, @@ -186,9 +187,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 +197,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 +209,11 @@ 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(_, _) + | rbv::ResolvedArg::Error(_), ) | None, _, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 1067ccda20ca..2c63a3904107 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; // Next, let's figure out the set of trait objects with implicit static bounds - let ty = self.tcx().type_of(*impl_def_id); + let ty = self.tcx().type_of(*impl_def_id).subst_identity(); let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(ty); let mut traits = vec![]; 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 99431567edac..c1ea0a0d95e9 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 4c0f457b46a7..ac4de2cc8426 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 - } + } + }) }) } @@ -125,7 +123,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { br: ty::BoundRegionKind, hir_sig: &hir::FnSig<'_>, ) -> Option { - let fn_ty = self.tcx().type_of(scope_def_id); + let fn_ty = self.tcx().type_of(scope_def_id).subst_identity(); if let ty::FnDef(_, _) = fn_ty.kind() { let ret_ty = fn_ty.fn_sig(self.tcx()).output(); let span = hir_sig.decl.output.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b6337d6853fa..b33729d0be5c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -326,7 +326,7 @@ impl Trait for X { diag, &trait_ref, pred.bounds, - &assoc, + assoc, assoc_substs, ty, msg, @@ -577,7 +577,7 @@ fn foo(&self) -> Self::T { String::new() } if let hir::Defaultness::Default { has_value: true } = tcx.impl_defaultness(item.id.owner_id) { - let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); + let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity(); if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label( item.span, @@ -598,7 +598,7 @@ fn foo(&self) -> Self::T { String::new() } })) => { for item in &items[..] { if let hir::AssocItemKind::Type = item.kind { - let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); + let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity(); if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label(item.span, "expected this associated type"); @@ -624,7 +624,7 @@ fn foo(&self) -> Self::T { String::new() } diag: &mut Diagnostic, trait_ref: &ty::TraitRef<'tcx>, bounds: hir::GenericBounds<'_>, - assoc: &ty::AssocItem, + assoc: ty::AssocItem, assoc_substs: &[ty::GenericArg<'tcx>], ty: Ty<'tcx>, msg: &str, @@ -667,7 +667,7 @@ fn foo(&self) -> Self::T { String::new() } &self, diag: &mut Diagnostic, span: Span, - assoc: &ty::AssocItem, + assoc: ty::AssocItem, assoc_substs: &[ty::GenericArg<'tcx>], ty: Ty<'tcx>, msg: &str, diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 39940f4592de..82a1bb1fd161 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 4a2210bdb68d..ac203c4eb0b2 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 17e734f07003..aa316b2dadb0 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 @@ -1166,7 +1166,15 @@ impl<'tcx> InferCtxt<'tcx> { origin, val: ConstVariableValue::Unknown { universe: self.universe() }, }); - self.tcx.mk_const(const_var_id, self.tcx.type_of(param.def_id)).into() + self.tcx + .mk_const( + const_var_id, + self.tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + ) + .into() } } } diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index a8e668d81eae..83f3d5a74fb4 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -21,6 +21,7 @@ pub fn explicit_outlives_bounds<'tcx>( .filter_map(move |kind| match kind { ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Subtype(..) 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 c46edc33ff40..e413b2bb570d 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 cb24375c7a3f..33514eedfc3d 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 008bf1e9c5dc..2c246a5787c7 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> 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_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index e617eb68d477..c1f0a6e98340 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -158,7 +158,7 @@ impl<'tcx> Elaborator<'tcx> { traits::ImplDerivedObligation(Box::new( traits::ImplDerivedObligationCause { derived, - impl_def_id: data.def_id(), + impl_or_alias_def_id: data.def_id(), impl_def_predicate_index: Some(index), span, }, @@ -297,6 +297,9 @@ impl<'tcx> Elaborator<'tcx> { ty::PredicateKind::AliasEq(..) => { // No } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + // Nothing to elaborate + } } } } diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 6e815863d06f..e6f04fe0aaa6 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -95,7 +95,7 @@ pub enum TokenKind { Literal { kind: LiteralKind, suffix_start: u32 }, /// "'a" - Lifetime { starts_with_number: bool }, + Lifetime { starts_with_number: bool, contains_emoji: bool }, // One-char tokens: /// ";" @@ -630,7 +630,13 @@ impl Cursor<'_> { // If the first symbol is valid for identifier, it can be a lifetime. // Also check if it's a number for a better error reporting (so '0 will // be reported as invalid lifetime and not as unterminated char literal). - is_id_start(self.first()) || self.first().is_digit(10) + // We also have to account for potential `'🐱` emojis to avoid reporting + // it as an unterminated char literal. + is_id_start(self.first()) + || self.first().is_digit(10) + // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode + // 5.0, but Unicode is already newer than this. + || unic_emoji_char::is_emoji(self.first()) }; if !can_be_a_lifetime { @@ -643,16 +649,33 @@ impl Cursor<'_> { return Literal { kind, suffix_start }; } - // Either a lifetime or a character literal with - // length greater than 1. + // Either a lifetime or a character literal. let starts_with_number = self.first().is_digit(10); + let mut contains_emoji = false; - // Skip the literal contents. - // First symbol can be a number (which isn't a valid identifier start), - // so skip it without any checks. - self.bump(); - self.eat_while(is_id_continue); + // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode + // 5.0, but Unicode is already newer than this. + if unic_emoji_char::is_emoji(self.first()) { + contains_emoji = true; + } else { + // Skip the literal contents. + // First symbol can be a number (which isn't a valid identifier start), + // so skip it without any checks. + self.bump(); + } + self.eat_while(|c| { + if is_id_continue(c) { + true + // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode + // 5.0, but Unicode is already newer than this. + } else if unic_emoji_char::is_emoji(c) { + contains_emoji = true; + true + } else { + false + } + }); // Check if after skipping literal contents we've met a closing // single quote (which means that user attempted to create a @@ -662,7 +685,7 @@ impl Cursor<'_> { let kind = Char { terminated: true }; Literal { kind, suffix_start: self.pos_within_token() } } else { - Lifetime { starts_with_number } + Lifetime { starts_with_number, contains_emoji } } } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index e4c1787f2cce..670d64fb983f 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -235,7 +235,7 @@ fn lifetime() { check_lexing( "'abc", expect![[r#" - Token { kind: Lifetime { starts_with_number: false }, len: 4 } + Token { kind: Lifetime { starts_with_number: false, contains_emoji: false }, len: 4 } "#]], ); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f18c0aa377fb..11fb1f80a111 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { - self.check_heap_type(cx, it.span, cx.tcx.type_of(it.owner_id)) + self.check_heap_type(cx, it.span, cx.tcx.type_of(it.owner_id).subst_identity()) } _ => (), } @@ -192,7 +192,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers { match it.kind { hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { for field in struct_def.fields() { - self.check_heap_type(cx, field.span, cx.tcx.type_of(field.def_id)); + self.check_heap_type( + cx, + field.span, + cx.tcx.type_of(field.def_id).subst_identity(), + ); } } _ => (), @@ -589,7 +593,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { // If the method is an impl for an item with docs_hidden, don't doc. MethodLateContext::PlainImpl => { let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); - let impl_ty = cx.tcx.type_of(parent); + let impl_ty = cx.tcx.type_of(parent).subst_identity(); let outerdef = match impl_ty.kind() { ty::Adt(def, _) => Some(def.did()), ty::Foreign(def_id) => Some(*def_id), @@ -698,7 +702,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { // and recommending Copy might be a bad idea. for field in def.all_fields() { let did = field.did; - if cx.tcx.type_of(did).is_unsafe_ptr() { + if cx.tcx.type_of(did).subst_identity().is_unsafe_ptr() { return; } } @@ -798,7 +802,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { if self.impling_types.is_none() { let mut impls = LocalDefIdSet::default(); cx.tcx.for_each_impl(debug, |d| { - if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() { + if let Some(ty_def) = cx.tcx.type_of(d).subst_identity().ty_adt_def() { if let Some(def_id) = ty_def.did().as_local() { impls.insert(def_id); } @@ -1591,6 +1595,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Clause(Clause::TypeOutlives(..)) | Clause(Clause::RegionOutlives(..)) => "lifetime", + // `ConstArgHasType` is never global as `ct` is always a param + Clause(Clause::ConstArgHasType(..)) | // Ignore projections, as they can only be global // if the trait bound is global Clause(Clause::Projection(..)) | @@ -2007,7 +2013,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 +2023,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 +2103,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 +2126,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 +2314,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, @@ -2855,8 +2858,8 @@ impl ClashingExternDeclarations { structurally_same_type_impl( seen_types, cx, - tcx.type_of(a_did), - tcx.type_of(b_did), + tcx.type_of(a_did).subst_identity(), + tcx.type_of(b_did).subst_identity(), ckind, ) }, @@ -2956,8 +2959,8 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { if let ForeignItemKind::Fn(..) = this_fi.kind { let tcx = cx.tcx; if let Some(existing_did) = self.insert(tcx, this_fi) { - let existing_decl_ty = tcx.type_of(existing_did); - let this_decl_ty = tcx.type_of(this_fi.owner_id); + let existing_decl_ty = tcx.type_of(existing_did).skip_binder(); + let this_decl_ty = tcx.type_of(this_fi.owner_id).subst_identity(); debug!( "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}", existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 972240f42cf4..9a9e2de7b5c7 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/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index dff5a645c175..ccf95992a6e6 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { // `Deref` is being implemented for `t` if let hir::ItemKind::Impl(impl_) = item.kind && let Some(trait_) = &impl_.of_trait - && let t = cx.tcx.type_of(item.owner_id) + && let t = cx.tcx.type_of(item.owner_id).subst_identity() && let opt_did @ Some(did) = trait_.trait_def_id() && opt_did == cx.tcx.lang_items().deref_trait() // `t` is `dyn t_principal` @@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { }); cx.emit_spanned_lint(DEREF_INTO_DYN_SUPERTRAIT, cx.tcx.def_span(item.owner_id.def_id), SupertraitAsDerefTarget { t, - target_principal: target_principal.to_string(), + target_principal, label, }); } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 1add352e0c42..a3367ae4a9f1 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_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 6cefaea2bc7d..2fd0ef3cda8b 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -216,7 +216,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option { } // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait. Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { - if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { + if let ty::Adt(adt, substs) = cx.tcx.type_of(did).subst_identity().kind() { if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) { // NOTE: This path is currently unreachable as `Ty<'tcx>` is diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2e447b900e11..94a43ab0c467 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -8,7 +8,7 @@ use rustc_errors::{ }; use rustc_hir::def_id::DefId; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{Predicate, Ty, TyCtxt}; +use rustc_middle::ty::{PolyExistentialTraitRef, Predicate, Ty, TyCtxt}; use rustc_session::parse::ParseSess; use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol}; @@ -556,8 +556,7 @@ pub struct BuiltinUnexpectedCliConfigValue { #[diag(lint_supertrait_as_deref_target)] pub struct SupertraitAsDerefTarget<'a> { pub t: Ty<'a>, - pub target_principal: String, - // pub target_principal: Binder<'a, ExistentialTraitRef<'b>>, + pub target_principal: PolyExistentialTraitRef<'a>, #[subdiagnostic] pub label: Option, } diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 392e13f2fa94..2bb2a3aab552 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -50,7 +50,7 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { - if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { + if let ty::Adt(adt, substs) = cx.tcx.type_of(did).subst_identity().kind() { if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) { return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs)); } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 88c6ea7efb28..b7fd6a254d81 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -651,7 +651,7 @@ pub fn transparent_newtype_field<'a, 'tcx>( ) -> Option<&'a ty::FieldDef> { let param_env = tcx.param_env(variant.def_id); variant.fields.iter().find(|field| { - let field_ty = tcx.type_of(field.did); + let field_ty = tcx.type_of(field.did).subst_identity(); let is_zst = tcx.layout_of(param_env.and(field_ty)).map_or(false, |layout| layout.is_zst()); !is_zst }) @@ -1240,7 +1240,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } fn check_foreign_static(&mut self, id: hir::OwnerId, span: Span) { - let ty = self.cx.tcx.type_of(id); + let ty = self.cx.tcx.type_of(id).subst_identity(); self.check_type_for_ffi_and_report_errors(span, ty, true, false); } @@ -1301,7 +1301,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind { - let t = cx.tcx.type_of(it.owner_id); + let t = cx.tcx.type_of(it.owner_id).subst_identity(); let ty = cx.tcx.erase_regions(t); let Ok(layout) = cx.layout_of(ty) else { return }; let Variants::Multiple { @@ -1421,7 +1421,7 @@ impl InvalidAtomicOrdering { && recognized_names.contains(&method_path.ident.name) && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_did) = cx.tcx.impl_of_method(m_def_id) - && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() + && let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() // skip extension traits, only lint functions from the standard library && cx.tcx.trait_id_of_impl(impl_did).is_none() && let parent = cx.tcx.parent(adt.did()) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index fbc1d8ef310c..0a42265a6baa 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -594,6 +594,8 @@ struct LLVMRustSanitizerOptions { bool SanitizeThread; bool SanitizeHWAddress; bool SanitizeHWAddressRecover; + bool SanitizeKernelAddress; + bool SanitizeKernelAddressRecover; }; extern "C" LLVMRustResult @@ -765,15 +767,17 @@ LLVMRustOptimize( ); } - if (SanitizerOptions->SanitizeAddress) { + if (SanitizerOptions->SanitizeAddress || SanitizerOptions->SanitizeKernelAddress) { OptimizerLastEPCallbacks.push_back( [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) { + auto CompileKernel = SanitizerOptions->SanitizeKernelAddress; #if LLVM_VERSION_LT(15, 0) MPM.addPass(RequireAnalysisPass()); #endif AddressSanitizerOptions opts = AddressSanitizerOptions{ - /*CompileKernel=*/false, - SanitizerOptions->SanitizeAddressRecover, + CompileKernel, + SanitizerOptions->SanitizeAddressRecover + || SanitizerOptions->SanitizeKernelAddressRecover, /*UseAfterScope=*/true, AsanDetectStackUseAfterReturnMode::Runtime, }; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index a8514c69d1c5..d823989bb02b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -499,9 +499,10 @@ impl<'tcx> Collector<'tcx> { let argument_types: &List> = self.tcx.erase_late_bound_regions( self.tcx .type_of(item.id.owner_id) + .subst_identity() .fn_sig(self.tcx) .inputs() - .map_bound(|slice| self.tcx.mk_type_list(slice.iter())), + .map_bound(|slice| self.tcx.intern_type_list(slice)), ); argument_types diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 8082a8903204..0bacf51e9119 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -114,7 +114,7 @@ macro_rules! provide_one { fn $name<'tcx>( $tcx: TyCtxt<'tcx>, def_id_arg: ty::query::query_keys::$name<'tcx>, - ) -> ty::query::query_values::$name<'tcx> { + ) -> ty::query::query_provided::$name<'tcx> { let _prof_timer = $tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name))); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 43047051f0f6..e941dd456888 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1541,8 +1541,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.impl_defaultness.set_some(def_id.index, *defaultness); self.tables.constness.set_some(def_id.index, *constness); - let trait_ref = self.tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::skip_binder); + let trait_ref = self.tcx.impl_trait_ref(def_id); if let Some(trait_ref) = trait_ref { + let trait_ref = trait_ref.skip_binder(); let trait_def = self.tcx.trait_def(trait_ref.def_id); if let Ok(mut an) = trait_def.ancestors(self.tcx, def_id) { if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 9227609cc8b6..01691398ad08 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; @@ -369,7 +369,7 @@ define_tables! { explicit_predicates_of: Table>>, generics_of: Table>, super_predicates_of: Table>>, - type_of: Table>>, + type_of: Table>>>, variances_of: Table>, fn_sig: Table>>>, codegen_fn_attrs: Table>, diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 2e82efba1924..84510fe218cf 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -74,8 +74,8 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { type DepKind = DepKind; #[inline] - fn with_stable_hashing_context(&self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R { - TyCtxt::with_stable_hashing_context(*self, f) + fn with_stable_hashing_context(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R { + TyCtxt::with_stable_hashing_context(self, f) } #[inline] diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ba93330d5812..2eafc356dc3f 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 { - 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 { diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index dedc65f4cbf4..dc89f762b764 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -104,7 +104,7 @@ impl<'tcx> TyCtxt<'tcx> { self.impl_trait_ref(def_id) .map(|t| t.subst_identity()) .map(ImplSubject::Trait) - .unwrap_or_else(|| ImplSubject::Inherent(self.type_of(def_id))) + .unwrap_or_else(|| ImplSubject::Inherent(self.type_of(def_id).subst_identity())) } } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index ada516aa0329..bb617e692cce 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/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index bea884c856a9..c4601a1fb418 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -91,7 +91,8 @@ bitflags! { /// the MIR `InstrumentCoverage` pass and not added to the coverage map /// during codegen. const NO_COVERAGE = 1 << 15; - /// `#[used(linker)]`: indicates that LLVM nor the linker can eliminate this function. + /// `#[used(linker)]`: + /// indicates that neither LLVM nor the linker will eliminate this function. const USED_LINKER = 1 << 16; /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory. const DEALLOCATOR = 1 << 17; diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 8dc68b1f5a82..0b6774f1b1fe 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 similarity index 80% rename from compiler/rustc_middle/src/middle/resolve_lifetime.rs rename to compiler/rustc_middle/src/middle/resolve_bound_vars.rs index c3bf1c717d9a..c59704fc0238 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -1,18 +1,20 @@ -//! Name resolution for lifetimes: type declarations. +//! Name resolution for lifetimes and late-bound type and const variables: type declarations. use crate::ty; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; 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), + Error(ErrorGuaranteed), } /// A set containing, at most, one known element. @@ -46,10 +48,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>, + pub defs: FxHashMap>, pub late_bound_vars: FxHashMap>>, } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c596e91160c8..46184cddd51f 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) }) } @@ -2497,7 +2497,7 @@ impl<'tcx> ConstantKind<'tcx> { }; debug!("expr.kind: {:?}", expr.kind); - let ty = tcx.type_of(def.def_id_for_type_of()); + let ty = tcx.type_of(def.def_id_for_type_of()).subst_identity(); debug!(?ty); // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` @@ -2525,14 +2525,12 @@ impl<'tcx> ConstantKind<'tcx> { } let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) { - if let Some(parent_did) = parent_hir_id.as_owner() { - InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) - } else { - tcx.mk_substs(Vec::>::new().into_iter()) - } + let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) + && let Some(parent_did) = parent_hir_id.as_owner() + { + InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) } else { - tcx.mk_substs(Vec::>::new().into_iter()) + tcx.intern_substs(&[]) }; debug!(?parent_substs); diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 97dc8a99f9b0..aa9f170477bc 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -165,7 +165,7 @@ impl<'tcx> Rvalue<'tcx> { tcx.mk_array_with_const_len(operand.ty(local_decls, tcx), count) } Rvalue::ThreadLocalRef(did) => { - let static_ty = tcx.type_of(did); + let static_ty = tcx.type_of(did).subst_identity(); if tcx.is_mutable_static(did) { tcx.mk_mut_ptr(static_ty) } else if tcx.is_foreign_item(did) { @@ -202,9 +202,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))), - AggregateKind::Adt(did, _, substs, _, _) => { - tcx.bound_type_of(did).subst(tcx, substs) - } + AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs), AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs), AggregateKind::Generator(did, substs, movability) => { tcx.mk_generator(did, substs, movability) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 3ddac5e11fbc..443c1b2d261e 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -323,7 +323,7 @@ macro_rules! make_mir_visitor { self.visit_source_scope($(& $mutability)? *parent_scope); } if let Some((callee, callsite_span)) = inlined { - let location = START_BLOCK.start_location(); + let location = Location::START; self.visit_span($(& $mutability)? *callsite_span); @@ -837,7 +837,7 @@ macro_rules! make_mir_visitor { } = var_debug_info; self.visit_source_info(source_info); - let location = START_BLOCK.start_location(); + let location = Location::START; match value { VarDebugInfoContents::Const(c) => self.visit_constant(c, location), VarDebugInfoContents::Place(place) => @@ -1026,7 +1026,7 @@ macro_rules! super_body { $self.visit_span($(& $mutability)? $body.span); for const_ in &$($mutability)? $body.required_consts { - let location = START_BLOCK.start_location(); + let location = Location::START; $self.visit_constant(const_, location); } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4b34f6b4881b..cf4d9b4b0057 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -152,7 +152,7 @@ rustc_queries! { /// to an alias, it will "skip" this alias to return the aliased type. /// /// [`DefId`]: rustc_hir::def_id::DefId - query type_of(key: DefId) -> Ty<'tcx> { + query type_of(key: DefId) -> ty::EarlyBinder> { desc { |tcx| "{action} `{path}`", action = { @@ -729,15 +729,14 @@ rustc_queries! { } /// Maps from a trait item to the trait item "descriptor". - query associated_item(key: DefId) -> &'tcx ty::AssocItem { + query associated_item(key: DefId) -> ty::AssocItem { desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) } - arena_cache cache_on_disk_if { key.is_local() } separate_provide_extern } /// Collects the associated items defined on a trait or impl. - query associated_items(key: DefId) -> &'tcx ty::AssocItems<'tcx> { + query associated_items(key: DefId) -> &'tcx ty::AssocItems { arena_cache desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } } @@ -781,7 +780,7 @@ rustc_queries! { separate_provide_extern } - query issue33140_self_ty(key: DefId) -> Option> { + query issue33140_self_ty(key: DefId) -> Option>> { desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) } } @@ -1641,12 +1640,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> { + query named_variable_map(_: hir::OwnerId) -> + Option<&'tcx FxHashMap> { desc { "looking up a named region" } } query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet> { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index c528929e7561..6231dd9b6f54 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -474,7 +474,11 @@ pub enum WellFormedLoc { #[derive(TypeVisitable, TypeFoldable)] pub struct ImplDerivedObligationCause<'tcx> { pub derived: DerivedObligationCause<'tcx>, - pub impl_def_id: DefId, + /// The `DefId` of the `impl` that gave rise to the `derived` obligation. + /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl, + /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle + /// that exceptional case where appropriate. + pub impl_or_alias_def_id: DefId, /// The index of the derived predicate in the parent impl's predicates. pub impl_def_predicate_index: Option, pub span: Span, diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index aad5b2fbe076..4019cf8ceee6 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -133,11 +133,7 @@ impl Node { /// /// If this returns `None`, the item can potentially still be found in /// parents of this node. - pub fn item<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - trait_item_def_id: DefId, - ) -> Option<&'tcx ty::AssocItem> { + pub fn item<'tcx>(&self, tcx: TyCtxt<'tcx>, trait_item_def_id: DefId) -> Option { match *self { Node::Trait(_) => Some(tcx.associated_item(trait_item_def_id)), Node::Impl(impl_def_id) => { @@ -239,7 +235,7 @@ impl<'tcx> Ancestors<'tcx> { } } - Some(LeafDef { item: *item, defining_node: node, finalizing_node }) + Some(LeafDef { item, defining_node: node, finalizing_node }) } else { // Item not mentioned. This "finalizes" any defaulted item provided by an ancestor. finalizing_node = Some(node); @@ -263,7 +259,7 @@ pub fn ancestors( if let Some(reported) = specialization_graph.has_errored { Err(reported) - } else if let Err(reported) = tcx.type_of(start_from_impl).error_reported() { + } else if let Err(reported) = tcx.type_of(start_from_impl).subst_identity().error_reported() { Err(reported) } else { Ok(Ancestors { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 71cecfb558fb..f1a9e50a4f05 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -83,7 +83,7 @@ impl AssocItem { } ty::AssocKind::Type => format!("type {};", self.name), ty::AssocKind::Const => { - format!("const {}: {:?};", self.name, tcx.type_of(self.def_id)) + format!("const {}: {:?};", self.name, tcx.type_of(self.def_id).subst_identity()) } } } @@ -129,13 +129,13 @@ impl std::fmt::Display for AssocKind { /// it is relatively expensive. Instead, items are indexed by `Symbol` and hygienic comparison is /// done only on items with the same name. #[derive(Debug, Clone, PartialEq, HashStable)] -pub struct AssocItems<'tcx> { - items: SortedIndexMultiMap, +pub struct AssocItems { + items: SortedIndexMultiMap, } -impl<'tcx> AssocItems<'tcx> { +impl AssocItems { /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order. - pub fn new(items_in_def_order: impl IntoIterator) -> Self { + pub fn new(items_in_def_order: impl IntoIterator) -> Self { let items = items_in_def_order.into_iter().map(|item| (item.name, item)).collect(); AssocItems { items } } @@ -145,7 +145,7 @@ impl<'tcx> AssocItems<'tcx> { /// New code should avoid relying on definition order. If you need a particular associated item /// for a known trait, make that trait a lang item instead of indexing this array. pub fn in_definition_order(&self) -> impl '_ + Iterator { - self.items.iter().map(|(_, v)| *v) + self.items.iter().map(|(_, v)| v) } pub fn len(&self) -> usize { @@ -157,7 +157,7 @@ impl<'tcx> AssocItems<'tcx> { &self, name: Symbol, ) -> impl '_ + Iterator { - self.items.get_by_key(name).copied() + self.items.get_by_key(name) } /// Returns the associated item with the given name and `AssocKind`, if one exists. diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 927f18f59b97..884ae7f5da28 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; @@ -71,7 +73,10 @@ impl<'tcx> Const<'tcx> { let expr = &tcx.hir().body(body_id).value; debug!(?expr); - let ty = tcx.type_of(def.def_id_for_type_of()); + let ty = tcx + .type_of(def.def_id_for_type_of()) + .no_bound_vars() + .expect("const parameter types cannot be generic"); match Self::try_eval_lit_or_param(tcx, ty, expr) { Some(v) => v, @@ -125,16 +130,30 @@ 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, + )), + Some(rbv::ResolvedArg::Error(guar)) => { + Some(tcx.const_error_with_guaranteed(ty, guar)) + } + 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 4aef071cd982..e2f32cdca3ca 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::{ @@ -67,7 +67,7 @@ use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::WithCachedTypeInfo; -use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags}; +use rustc_type_ir::{CollectAndApply, DynKind, Interner, TypeFlags}; use std::any::Any; use std::borrow::Borrow; @@ -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>, + + /// 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>>, } 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, + } } } @@ -479,7 +520,7 @@ pub struct GlobalCtxt<'tcx> { pub on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, pub queries: &'tcx dyn query::QueryEngine<'tcx>, - pub query_caches: query::QueryCaches<'tcx>, + pub query_system: query::QuerySystem<'tcx>, pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. @@ -664,7 +705,7 @@ impl<'tcx> TyCtxt<'tcx> { untracked, on_disk_cache, queries, - query_caches: query::QueryCaches::default(), + query_system: Default::default(), query_kinds, ty_rcache: Default::default(), pred_rcache: Default::default(), @@ -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>(self, span: S, msg: &str) -> Region<'tcx> { + pub fn mk_re_error_with_message>(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` @@ -1108,18 +1149,16 @@ impl<'tcx> TyCtxt<'tcx> { _ => return None, } - let ret_ty = self.type_of(scope_def_id); + let ret_ty = self.type_of(scope_def_id).subst_identity(); match ret_ty.kind() { 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, } @@ -1150,8 +1189,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn caller_location_ty(self) -> Ty<'tcx> { self.mk_imm_ref( self.lifetimes.re_static, - self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None)) - .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())), + self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) + .subst(self, self.intern_substs(&[self.lifetimes.re_static.into()])), ) } @@ -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 { - 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> { 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>, &'tcx List>>(self) }) - } else { - None - } + .then(|| unsafe { mem::transmute::<&'a List>, &'tcx List>>(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>, @@ -1623,21 +1660,14 @@ impl<'tcx> TyCtxt<'tcx> { unsafety: hir::Unsafety, ) -> PolyFnSig<'tcx> { sig.map_bound(|s| { - let params_iter = match s.inputs()[0].kind() { - ty::Tuple(params) => params.into_iter(), + let params = match s.inputs()[0].kind() { + ty::Tuple(params) => *params, _ => bug!(), }; - self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) + self.mk_fn_sig(params, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) }) } - /// 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] @@ -1724,7 +1754,7 @@ impl<'tcx> TyCtxt<'tcx> { ty_param.into() } else { assert!(has_default); - self.bound_type_of(param.def_id).subst(self, substs).into() + self.type_of(param.def_id).subst(self, substs).into() } } }); @@ -1805,8 +1835,12 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) } } - pub fn mk_tup, Ty<'tcx>>>(self, iter: I) -> I::Output { - iter.intern_with(|ts| self.intern_tup(ts)) + pub fn mk_tup(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, Ty<'tcx>>, + { + T::collect_and_apply(iter, |ts| self.intern_tup(ts)) } #[inline] @@ -1966,13 +2000,15 @@ 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 .mk_const( ParamConst { index: param.index, name: param.name }, - self.type_of(param.def_id), + self.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), ) .into(), } @@ -1998,6 +2034,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)) } @@ -2065,11 +2161,12 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn mk_const_list, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_const_list(xs)) + pub fn mk_const_list(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_const_list(xs)) } pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List> { @@ -2118,18 +2215,24 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } } - pub fn mk_fn_sig( + // Unlike various other `mk_*` functions, this one uses `I: IntoIterator` + // instead of `I: Iterator`. Unlike those other functions, this one doesn't + // have a `intern_fn_sig` variant that can be used for cases where `I` is + // something like a `Vec`. That's because of the need to combine `inputs` + // and `output`. + pub fn mk_fn_sig( self, inputs: I, output: I::Item, c_variadic: bool, unsafety: hir::Unsafety, abi: abi::Abi, - ) -> , ty::FnSig<'tcx>>>::Output + ) -> T::Output where - I: Iterator, ty::FnSig<'tcx>>>, + I: IntoIterator, + T: CollectAndApply, ty::FnSig<'tcx>>, { - inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig { + T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { inputs_and_output: self.intern_type_list(xs), c_variadic, unsafety, @@ -2137,38 +2240,47 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn mk_poly_existential_predicates< - I: InternAs, &'tcx List>>, - >( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_poly_existential_predicates(xs)) + pub fn mk_poly_existential_predicates(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply< + PolyExistentialPredicate<'tcx>, + &'tcx List>, + >, + { + T::collect_and_apply(iter, |xs| self.intern_poly_existential_predicates(xs)) } - pub fn mk_predicates, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_predicates(xs)) + pub fn mk_predicates(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_predicates(xs)) } - pub fn mk_type_list, &'tcx List>>>(self, iter: I) -> I::Output { - iter.intern_with(|xs| self.intern_type_list(xs)) + pub fn mk_type_list(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_type_list(xs)) } - pub fn mk_substs, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_substs(xs)) + pub fn mk_substs(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_substs(xs)) } - pub fn mk_place_elems, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_place_elems(xs)) + pub fn mk_place_elems(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_place_elems(xs)) } pub fn mk_substs_trait( @@ -2197,13 +2309,12 @@ impl<'tcx> TyCtxt<'tcx> { ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () } } - pub fn mk_bound_variable_kinds< - I: InternAs>, - >( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_bound_variable_kinds(xs)) + pub fn mk_bound_variable_kinds(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply>, + { + T::collect_and_apply(iter, |xs| self.intern_bound_variable_kinds(xs)) } /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -2278,9 +2389,9 @@ impl<'tcx> TyCtxt<'tcx> { Some(&*candidates) } - pub fn named_region(self, id: HirId) -> Option { + pub fn named_bound_var(self, id: HirId) -> Option { 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 { @@ -2288,13 +2399,13 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn late_bound_vars(self, id: HirId) -> &'tcx List { - self.mk_bound_variable_kinds( - self.late_bound_vars_map(id.owner) + self.intern_bound_variable_kinds( + &self + .late_bound_vars_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) .unwrap_or_else(|| { bug!("No bound vars found for {}", self.hir().node_to_string(id)) - }) - .iter(), + }), ) } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index fc529f5d1d09..a029c1b209df 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -481,8 +481,9 @@ impl<'tcx> TypeVisitor> for IsSuggestableVisitor<'tcx> { Alias(Opaque, AliasTy { def_id, .. }) => { let parent = self.tcx.parent(def_id); + let parent_ty = self.tcx.type_of(parent).subst_identity(); if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent) - && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *self.tcx.type_of(parent).kind() + && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() && parent_opaque_def_id == def_id { // Okay @@ -564,8 +565,9 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { Alias(Opaque, AliasTy { def_id, .. }) => { let parent = self.tcx.parent(def_id); + let parent_ty = self.tcx.type_of(parent).subst_identity(); if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) - && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *self.tcx.type_of(parent).kind() + && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() && parent_opaque_def_id == def_id { t diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 9afa37e9ef3e..106ce9990e1e 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/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index c9aa0ec66d56..91241ff404f4 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -251,6 +251,10 @@ impl FlagComputation { self.add_ty(ty); self.add_region(region); } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + self.add_const(ct); + self.add_ty(ty); + } ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => { self.add_ty(a); self.add_ty(b); diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 352daa8fc298..ee36e60bff15 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> 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 ea95a38f272c..35c036fef2dd 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -85,7 +85,7 @@ impl GenericParamDef { ) -> Option>> { match self.kind { GenericParamDefKind::Type { has_default, .. } if has_default => { - Some(tcx.bound_type_of(self.def_id).map_bound(|t| t.into())) + Some(tcx.type_of(self.def_id).map_bound(|t| t.into())) } GenericParamDefKind::Const { has_default } if has_default => { Some(tcx.const_param_default(self.def_id).map_bound(|c| c.into())) @@ -100,10 +100,10 @@ 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() + tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into() } } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 690c0d58e01c..355b8d8b4313 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -87,7 +87,7 @@ impl<'tcx> VariantDef { InhabitedPredicate::all( tcx, self.fields.iter().map(|field| { - let pred = tcx.type_of(field.did).inhabited_predicate(tcx); + let pred = tcx.type_of(field.did).subst_identity().inhabited_predicate(tcx); if adt.is_enum() { return pred; } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 55f2395e531a..c68a344e92c8 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -103,7 +103,7 @@ impl<'tcx> Instance<'tcx> { /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty) + tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder()) } /// Finds a crate that contains a monomorphization of this instance that @@ -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> { - 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(&self, tcx: TyCtxt<'tcx>, v: &T) -> T @@ -662,7 +662,7 @@ fn polymorphize<'tcx>( let def_id = instance.def_id(); let upvars_ty = if tcx.is_closure(def_id) { Some(substs.as_closure().tupled_upvars_ty()) - } else if tcx.type_of(def_id).is_generator() { + } else if tcx.type_of(def_id).skip_binder().is_generator() { Some(substs.as_generator().tupled_upvars_ty()) } else { None diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 1d76f435e26d..3d0f9a5053cb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -686,7 +686,7 @@ where Increase this counter if you tried to implement this but failed to do it without duplicating a lot of code from other places in the compiler: 2 - tcx.mk_tup(&[ + tcx.intern_tup(&[ tcx.mk_array(tcx.types.usize, 3), tcx.mk_array(Option), ]) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a1b5eaed2f17..1dc27ce8dae0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -552,6 +552,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(Clause::RegionOutlives(_)) | PredicateKind::Clause(Clause::TypeOutlives(_)) | PredicateKind::Clause(Clause::Projection(_)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::ObjectSafe(_) | PredicateKind::ClosureKind(_, _, _) @@ -590,6 +591,10 @@ pub enum Clause<'tcx> { /// `where ::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. Projection(ProjectionPredicate<'tcx>), + + /// Ensures that a const generic argument to a parameter `const N: u8` + /// is of type `u8`. + ConstArgHasType(Const<'tcx>, Ty<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -1193,6 +1198,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Projection(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) @@ -1213,6 +1219,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) @@ -1233,6 +1240,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::TypeOutlives(data)) => Some(predicate.rebind(data)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::Clause(Clause::Projection(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) @@ -2017,7 +2025,7 @@ impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `subst` is /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { - tcx.bound_type_of(self.did).subst(tcx, subst) + tcx.type_of(self.did).subst(tcx, subst) } /// Computes the `Ident` of this variant by looking up the `Span` @@ -2198,7 +2206,7 @@ impl<'tcx> TyCtxt<'tcx> { Some(Ident::new(def, span)) } - pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> { + pub fn opt_associated_item(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { Some(self.associated_item(def_id)) } else { diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 66c878c8b635..8aeef4684b38 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> 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 303675d3ca5c..8849e7eab335 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/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 90bf3288ccf5..021c20b5854d 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -115,7 +115,7 @@ pub trait Printer<'tcx>: Sized { DefPathData::Impl => { let generics = self.tcx().generics_of(def_id); - let self_ty = self.tcx().bound_type_of(def_id); + let self_ty = self.tcx().type_of(def_id); let impl_trait_ref = self.tcx().impl_trait_ref(def_id); let (self_ty, impl_trait_ref) = if substs.len() >= generics.count() { ( diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f50a5d89d3d1..1e59983583b1 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. @@ -754,7 +754,7 @@ pub trait PrettyPrinter<'tcx>: // NOTE: I know we should check for NO_QUERIES here, but it's alright. // `type_of` on a type alias or assoc type should never cause a cycle. if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) = - *self.tcx().type_of(parent).kind() + *self.tcx().type_of(parent).subst_identity().kind() { if d == def_id { // If the type alias directly starts with the `impl` of the @@ -2271,7 +2271,7 @@ impl<'a, 'tcx> ty::ir::TypeFolder> 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, @@ -2822,15 +2822,18 @@ define_print_and_forward_display! { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(predicate)) => p!(print(predicate)), ty::PredicateKind::Clause(ty::Clause::TypeOutlives(predicate)) => p!(print(predicate)), ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) => p!(print(predicate)), + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + p!("the constant `", print(ct), "` has type `", print(ty), "`") + }, ty::PredicateKind::WellFormed(arg) => p!(print(arg), " well-formed"), ty::PredicateKind::ObjectSafe(trait_def_id) => { p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe") } - ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!("the closure `", + ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => p!( + "the closure `", print_value_path(closure_def_id, &[]), - write("` implements the trait `{}`", kind)) - } + write("` implements the trait `{}`", kind) + ), ty::PredicateKind::ConstEvaluatable(ct) => { p!("the constant `", print(ct), "` can be evaluated") } diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index ed54aa96f5b8..5b3f38704299 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -1,3 +1,5 @@ +#![allow(unused_parens)] + use crate::dep_graph; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; @@ -6,7 +8,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; @@ -34,6 +36,7 @@ use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::GeneratorDiagnosticData; use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams}; +use rustc_arena::TypedArena; use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_attr as attr; @@ -41,6 +44,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::WorkerLocal; use rustc_data_structures::unord::UnordSet; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -59,6 +63,7 @@ use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi; use rustc_target::spec::PanicStrategy; +use std::mem; use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; @@ -66,6 +71,12 @@ use std::sync::Arc; pub(crate) use rustc_query_system::query::QueryJobId; use rustc_query_system::query::*; +#[derive(Default)] +pub struct QuerySystem<'tcx> { + pub arenas: QueryArenas<'tcx>, + pub caches: QueryCaches<'tcx>, +} + #[derive(Copy, Clone)] pub struct TyCtxtAt<'tcx> { pub tcx: TyCtxt<'tcx>, @@ -112,10 +123,10 @@ macro_rules! query_helper_param_ty { } macro_rules! query_if_arena { - ([] $arena:ty, $no_arena:ty) => { + ([] $arena:tt $no_arena:tt) => { $no_arena }; - ([(arena_cache) $($rest:tt)*] $arena:ty, $no_arena:ty) => { + ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => { $arena }; ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { @@ -131,7 +142,7 @@ macro_rules! separate_provide_extern_decl { for<'tcx> fn( TyCtxt<'tcx>, query_keys::$name<'tcx>, - ) -> query_values::$name<'tcx> + ) -> query_provided::$name<'tcx> }; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { separate_provide_extern_decl!([$($modifiers)*][$($args)*]) @@ -183,30 +194,77 @@ macro_rules! define_callbacks { $(pub type $name<'tcx> = $($K)*;)* } - #[allow(nonstandard_style, unused_lifetimes, unused_parens)] + #[allow(nonstandard_style, unused_lifetimes)] pub mod query_values { use super::*; - $(pub type $name<'tcx> = query_if_arena!([$($modifiers)*] <$V as Deref>::Target, $V);)* + $(pub type $name<'tcx> = $V;)* } - #[allow(nonstandard_style, unused_lifetimes, unused_parens)] + + /// This module specifies the type returned from query providers and the type used for + /// decoding. For regular queries this is the declared returned type `V`, but + /// `arena_cache` will use `::Target` instead. + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_provided { + use super::*; + + $( + pub type $name<'tcx> = query_if_arena!([$($modifiers)*] (<$V as Deref>::Target) ($V)); + )* + } + + /// This module has a function per query which takes a `query_provided` value and coverts + /// it to a regular `V` value by allocating it on an arena if the query has the + /// `arena_cache` modifier. This will happen when computing the query using a provider or + /// decoding a stored result. + #[allow(nonstandard_style, unused_lifetimes)] + pub mod query_provided_to_value { + use super::*; + + $( + #[inline(always)] + pub fn $name<'tcx>( + _tcx: TyCtxt<'tcx>, + value: query_provided::$name<'tcx>, + ) -> query_values::$name<'tcx> { + query_if_arena!([$($modifiers)*] + { + if mem::needs_drop::>() { + &*_tcx.query_system.arenas.$name.alloc(value) + } else { + &*_tcx.arena.dropless.alloc(value) + } + } + (value) + ) + } + )* + } + #[allow(nonstandard_style, unused_lifetimes)] pub mod query_storage { use super::*; $( - pub type $name<'tcx> = query_if_arena!([$($modifiers)*] - <<$($K)* as Key>::CacheSelector - as CacheSelector<'tcx, <$V as Deref>::Target>>::ArenaCache, - <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache - ); + pub type $name<'tcx> = <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache; )* } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_stored { - use super::*; + pub struct QueryArenas<'tcx> { + $($(#[$attr])* pub $name: query_if_arena!([$($modifiers)*] + (WorkerLocal::Target>>) + () + ),)* + } - $(pub type $name<'tcx> = $V;)* + impl Default for QueryArenas<'_> { + fn default() -> Self { + Self { + $($name: query_if_arena!([$($modifiers)*] + (WorkerLocal::new(|_| Default::default())) + () + ),)* + } + } } #[derive(Default)] @@ -221,7 +279,7 @@ macro_rules! define_callbacks { let key = key.into_query_param(); opt_remap_env_constness!([$($modifiers)*][key]); - match try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key) { + match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) { Some(_) => return, None => self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure), }; @@ -246,7 +304,7 @@ macro_rules! define_callbacks { let key = key.into_query_param(); opt_remap_env_constness!([$($modifiers)*][key]); - match try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key) { + match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) { Some(value) => value, None => self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap(), } @@ -257,7 +315,7 @@ macro_rules! define_callbacks { $(pub $name: for<'tcx> fn( TyCtxt<'tcx>, query_keys::$name<'tcx>, - ) -> query_values::$name<'tcx>,)* + ) -> query_provided::$name<'tcx>,)* } pub struct ExternProviders { @@ -334,12 +392,13 @@ macro_rules! define_feedable { $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] - pub fn $name(self, value: query_values::$name<'tcx>) -> $V { + pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { let key = self.key().into_query_param(); opt_remap_env_constness!([$($modifiers)*][key]); let tcx = self.tcx; - let cache = &tcx.query_caches.$name; + let value = query_provided_to_value::$name(tcx, value); + let cache = &tcx.query_system.caches.$name; match try_get_cached(tcx, cache, &key) { Some(old) => { @@ -357,7 +416,8 @@ macro_rules! define_feedable { &value, hash_result!([$($modifiers)*]), ); - cache.complete(key, value, dep_node_index) + cache.complete(key, value, dep_node_index); + value } } } @@ -435,10 +495,6 @@ impl<'tcx> TyCtxt<'tcx> { self.opt_def_kind(def_id) .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) } - - pub fn bound_type_of(self, def_id: impl IntoQueryParam) -> ty::EarlyBinder> { - ty::EarlyBinder(self.type_of(def_id)) - } } impl<'tcx> TyCtxtAt<'tcx> { @@ -447,8 +503,4 @@ impl<'tcx> TyCtxtAt<'tcx> { self.opt_def_kind(def_id) .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) } - - pub fn bound_type_of(self, def_id: impl IntoQueryParam) -> ty::EarlyBinder> { - ty::EarlyBinder(self.type_of(def_id)) - } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 33b509ec490b..2ba25e8bfadc 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -163,8 +163,7 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { let variance = variances[i]; let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { - let ty = - *cached_ty.get_or_insert_with(|| tcx.bound_type_of(ty_def_id).subst(tcx, a_subst)); + let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst)); ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } } else { ty::VarianceDiagInfo::default() @@ -674,7 +673,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( for (a_arg, b_arg) in aa.iter().zip(ba.iter()) { related_args.push(r.consts(a_arg, b_arg)?); } - let related_args = tcx.mk_const_list(related_args.iter()); + let related_args = tcx.intern_const_list(&related_args); Expr::FunctionCall(func, related_args) } _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 97ee2b1fc5dd..573105fd8c00 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -147,6 +147,7 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { impl<'tcx> fmt::Debug for ty::Clause<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { + ty::Clause::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"), ty::Clause::Trait(ref a) => a.fmt(f), ty::Clause::RegionOutlives(ref pair) => pair.fmt(f), ty::Clause::TypeOutlives(ref pair) => pair.fmt(f), @@ -418,7 +419,7 @@ impl<'tcx> ir::TypeFoldable> for &'tcx ty::List ir::TypeFoldable> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { - ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter())) + ty::util::fold_list(self, folder, |tcx, v| tcx.intern_const_list(v)) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c613b3627f2f..f8d17433cf77 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -933,6 +933,12 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } +impl rustc_errors::IntoDiagnosticArg for PolyExistentialTraitRef<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + self.to_string().into_diagnostic_arg() + } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundVariableKind { @@ -1187,7 +1193,7 @@ impl<'tcx> FallibleTypeFolder> 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) @@ -2268,7 +2274,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); - (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) + (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) }, // type parameters only have unit metadata if they're sized, so return true diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a6ab7440c8e6..6b4a6a17aef5 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>> { - 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>::as_substs`. - Some(unsafe { &*(self as *const List> as *const List>) }) - } else { - None - } + unsafe { &*(self as *const List> as *const List>) } + }) } /// Interpret these substitutions as the substitutions of a closure type. diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 71353acaaa7c..a4a82bf247d0 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -225,7 +225,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait for &impl_def_id in tcx.hir().trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); - let impl_self_ty = tcx.type_of(impl_def_id); + let impl_self_ty = tcx.type_of(impl_def_id).subst_identity(); if impl_self_ty.references_error() { continue; } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 35831ff87064..a34ee1a99a17 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -362,7 +362,7 @@ impl<'tcx> TyCtxt<'tcx> { let drop_trait = self.lang_items().drop_trait()?; self.ensure().coherent_trait(drop_trait); - let ty = self.type_of(adt_did); + let ty = self.type_of(adt_did).subst_identity(); let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| { if let Some(item_id) = self.associated_item_def_ids(impl_did).first() { if validate(self, impl_did).is_ok() { @@ -415,12 +415,12 @@ impl<'tcx> TyCtxt<'tcx> { // , and then look up which of the impl substs refer to // parameters marked as pure. - let impl_substs = match *self.type_of(impl_def_id).kind() { + let impl_substs = match *self.type_of(impl_def_id).subst_identity().kind() { ty::Adt(def_, substs) if def_ == def => substs, _ => bug!(), }; - let item_substs = match *self.type_of(def.did()).kind() { + let item_substs = match *self.type_of(def.did()).subst_identity().kind() { ty::Adt(def_, substs) if def_ == def => substs, _ => bug!(), }; @@ -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> { 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) @@ -602,7 +602,10 @@ impl<'tcx> TyCtxt<'tcx> { /// Get the type of the pointer to the static that we use in MIR. pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. - let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)); + let static_ty = self.normalize_erasing_regions( + ty::ParamEnv::empty(), + self.type_of(def_id).subst_identity(), + ); // Make sure that accesses to unsafe statics end up using raw pointers. // For thread-locals, this needs to be kept in sync with `Rvalue::ty`. @@ -790,7 +793,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { Some(expanded_ty) => *expanded_ty, None => { - let generic_ty = self.tcx.bound_type_of(def_id); + let generic_ty = self.tcx.type_of(def_id); let concrete_ty = generic_ty.subst(self.tcx, substs); let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, substs), expanded_ty); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 38b1fa91d0a6..dac9bf0a8835 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 ad7a568a2318..8859f5002e46 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/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 1655e224ddbb..933b1158fa6e 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -643,7 +643,7 @@ fn construct_error( let num_params = match body_owner_kind { hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(), hir::BodyOwnerKind::Closure => { - let ty = tcx.type_of(def); + let ty = tcx.type_of(def).subst_identity(); match ty.kind() { ty::Closure(_, substs) => { 1 + substs.as_closure().sig().inputs().skip_binder().len() diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 10df4b229520..74c35ef0fc24 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -133,14 +133,14 @@ impl<'tcx> Cx<'tcx> { bug!("closure expr does not have closure type: {:?}", closure_ty); }; - let bound_vars = self.tcx.mk_bound_variable_kinds(std::iter::once( - ty::BoundVariableKind::Region(ty::BrEnv), - )); + let bound_vars = self + .tcx + .intern_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]); let br = ty::BoundRegion { 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( @@ -193,7 +193,7 @@ impl<'tcx> Cx<'tcx> { let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span)); self.tcx - .bound_type_of(va_list_did) + .type_of(va_list_did) .subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()]) } else { fn_sig.inputs()[index] 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 977c4b4ae6c0..e5b7d685c499 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 { - 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 47ca0a87fcc2..41306dd80fbd 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 2890fa32cc91..633a5674f1f9 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/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index d8f85d2e3798..9b4b720702b6 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -41,7 +41,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { // // Here we test for this function itself whether its ABI allows // unwinding or not. - let body_ty = tcx.type_of(def_id); + let body_ty = tcx.type_of(def_id).skip_binder(); let body_abi = match body_ty.kind() { ty::FnDef(..) => body_ty.fn_sig(tcx).abi(), ty::Closure(..) => Abi::RustCall, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index feb054392bc2..13f064aa72e5 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -82,7 +82,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } - let is_generator = tcx.type_of(def_id.to_def_id()).is_generator(); + let is_generator = tcx.type_of(def_id.to_def_id()).subst_identity().is_generator(); // FIXME(welseywiser) const prop doesn't work on generators because of query cycles // computing their layout. if is_generator { diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index c4b10218c237..be41d611fe48 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -57,7 +57,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { return; } - let is_generator = tcx.type_of(def_id.to_def_id()).is_generator(); + let is_generator = tcx.type_of(def_id.to_def_id()).subst_identity().is_generator(); // FIXME(welseywiser) const prop doesn't work on generators because of query cycles // computing their layout. if is_generator { diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs index 7d127032179b..1b3ac78fbc66 100644 --- a/compiler/rustc_mir_transform/src/ctfe_limit.rs +++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs @@ -47,8 +47,7 @@ fn has_back_edge( return false; } // Check if any of the dominators of the node are also the node's successor. - doms.dominators(node) - .any(|dom| node_data.terminator().successors().into_iter().any(|succ| succ == dom)) + doms.dominators(node).any(|dom| node_data.terminator().successors().any(|succ| succ == dom)) } fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) { diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index ddab7bbb2e30..89ca04a15827 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -163,7 +163,7 @@ pub fn deduced_param_attrs<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [Ded // Codegen won't use this information for anything if all the function parameters are passed // directly. Detect that and bail, for compilation speed. - let fn_ty = tcx.type_of(def_id); + let fn_ty = tcx.type_of(def_id).subst_identity(); if matches!(fn_ty.kind(), ty::FnDef(..)) { if fn_ty .fn_sig(tcx) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 5c5baa68e588..2e481b972781 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -136,8 +136,8 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::{dump_mir, PassWhere}; use rustc_middle::mir::{ - traversal, BasicBlock, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, - Rvalue, Statement, StatementKind, TerminatorKind, + traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, Rvalue, + Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::impls::MaybeLiveLocals; @@ -468,7 +468,7 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> { // to reuse the allocation. write_info: write_info_alloc, // Doesn't matter what we put here, will be overwritten before being used - at: Location { block: BasicBlock::from_u32(0), statement_index: 0 }, + at: Location::START, }; this.internal_filter_liveness(); } diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 932134bd6318..dc583471c89d 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -18,8 +18,8 @@ pub fn build_ptr_tys<'tcx>( nonnull_did: DefId, ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) { let substs = tcx.intern_substs(&[pointee.into()]); - let unique_ty = tcx.bound_type_of(unique_did).subst(tcx, substs); - let nonnull_ty = tcx.bound_type_of(nonnull_did).subst(tcx, substs); + let unique_ty = tcx.type_of(unique_did).subst(tcx, substs); + let nonnull_ty = tcx.type_of(nonnull_did).subst(tcx, substs); let ptr_ty = tcx.mk_imm_ptr(pointee); (unique_ty, nonnull_ty, ptr_ty) @@ -93,7 +93,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { if let Some(def_id) = tcx.lang_items().owned_box() { let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[0].did; - let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else { + let Some(nonnull_def) = tcx.type_of(unique_did).subst_identity().ty_adt_def() else { span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") }; diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 1244c18020dd..e6546911a2d0 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -49,7 +49,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let body = &*tcx.mir_built(ty::WithOptConstParam::unknown(local_def_id)).borrow(); - let body_ty = tcx.type_of(def_id); + let body_ty = tcx.type_of(def_id).skip_binder(); let body_abi = match body_ty.kind() { ty::FnDef(..) => body_ty.fn_sig(tcx).abi(), ty::Closure(..) => Abi::RustCall, diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index aa19b1fdb5ef..66d32b954e47 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> { 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/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 35c6037fa292..dc5f88f24f80 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -487,7 +487,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None); - for bb in BasicBlock::new(0)..body.basic_blocks.next_index() { + for bb in START_BLOCK..body.basic_blocks.next_index() { let bb_data = &body[bb]; if bb_data.is_cleanup { continue; @@ -1255,7 +1255,7 @@ fn create_generator_resume_function<'tcx>( use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn}; // Jump to the entry point on the unresumed - cases.insert(0, (UNRESUMED, BasicBlock::new(0))); + cases.insert(0, (UNRESUMED, START_BLOCK)); // Panic when resumed on the returned or poisoned state let generator_kind = body.generator_kind().unwrap(); @@ -1481,7 +1481,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // When first entering the generator, move the resume argument into its new local. let source_info = SourceInfo::outermost(body.span); - let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements; + let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements; stmts.insert( 0, Statement { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 84640b703c80..8c6b0463a739 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -96,7 +96,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { history: Vec::new(), changed: false, }; - let blocks = BasicBlock::new(0)..body.basic_blocks.next_index(); + let blocks = START_BLOCK..body.basic_blocks.next_index(); this.process_blocks(body, blocks); this.changed } @@ -900,7 +900,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { let kind = match parent_ty.ty.kind() { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { - self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind() + self.tcx.type_of(def_id).subst(self.tcx, substs).kind() } kind => kind, }; diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 1079377fbacd..0534e688703e 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -110,11 +110,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { fn combine_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Ref(_, _, place) = rvalue { if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() { - if let ty::Ref(_, _, Mutability::Not) = - base.ty(self.local_decls, self.tcx).ty.kind() - { - // The dereferenced place must have type `&_`, so that we don't copy `&mut _`. - } else { + if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty { return; } diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 194c41c6ba1c..2ca33a624e20 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/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 6cabef92d8c2..1becfddb23bd 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -13,7 +13,7 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Avoid query cycles (generators require optimized MIR for layout). - if tcx.type_of(body.source.def_id()).is_generator() { + if tcx.type_of(body.source.def_id()).subst_identity().is_generator() { return; } let param_env = tcx.param_env(body.source.def_id()); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 551422386f6e..682ad081f5cf 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -597,7 +597,7 @@ fn build_call_shim<'tcx>( let untuple_args = sig.inputs(); // Create substitutions for the `Self` and `Args` generic parameters of the shim body. - let arg_tup = tcx.mk_tup(untuple_args.iter()); + let arg_tup = tcx.intern_tup(untuple_args); (Some([ty.into(), arg_tup.into()]), Some(untuple_args)) } else { @@ -692,7 +692,7 @@ fn build_call_shim<'tcx>( // `FnDef` call with optional receiver. CallKind::Direct(def_id) => { - let ty = tcx.type_of(def_id); + let ty = tcx.type_of(def_id).subst_identity(); ( Operand::Constant(Box::new(Constant { span, diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index ced97b2c7884..9ef55c558c60 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -496,7 +496,7 @@ impl UsedLocals { self.increment = false; // The location of the statement is irrelevant. - let location = Location { block: START_BLOCK, statement_index: 0 }; + let location = Location::START; self.visit_statement(statement, location); } diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 65c15d9c6749..c1e7f62dea5c 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_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index bbe4e67977c9..55a9f912e085 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1196,8 +1196,7 @@ impl<'v> RootCollector<'_, 'v> { { debug!("RootCollector: ADT drop-glue for `{id:?}`",); - let ty = - self.tcx.bound_type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); + let ty = self.tcx.type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } } diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 29009c48050e..62bafb981e77 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -308,7 +308,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( let impl_self_ty = tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - tcx.type_of(impl_def_id), + tcx.type_of(impl_def_id).skip_binder(), ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { return Some(def_id); diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index bd998ed91d97..37449aaabed8 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -200,16 +200,21 @@ impl<'a> StringReader<'a> { }; token::Literal(token::Lit { kind, symbol, suffix }) } - rustc_lexer::TokenKind::Lifetime { starts_with_number } => { + rustc_lexer::TokenKind::Lifetime { starts_with_number, contains_emoji } => { // Include the leading `'` in the real identifier, for macro // expansion purposes. See #12512 for the gory details of why // this is necessary. let lifetime_name = self.str_from(start); if starts_with_number { let span = self.mk_sp(start, self.pos); - let mut diag = self.sess.struct_err("lifetimes cannot start with a number"); + let mut diag = self.sess.struct_err("lifetimes or labels cannot start with a number"); diag.set_span(span); diag.stash(span, StashKey::LifetimeIsChar); + } else if contains_emoji { + let span = self.mk_sp(start, self.pos); + let mut diag = self.sess.struct_err("lifetimes or labels cannot contain emojis"); + diag.set_span(span); + diag.stash(span, StashKey::LifetimeContainsEmoji); } let ident = Symbol::intern(lifetime_name); token::Lifetime(ident) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0cb88f3c3a91..a74f408d7741 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 { - 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 2e706a00cf7f..49959a8981c6 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 5b92563fc358..4f4252b532ed 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 34a4fd02ea69..8a3cedfee795 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 225095948af8..8ad4a5ef9581 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}; @@ -2174,7 +2174,7 @@ impl CheckAttrVisitor<'_> { let tcx = self.tcx; if target == Target::Fn { let Some(tokenstream) = tcx.get_diagnostic_item(sym::TokenStream) else {return}; - let tokenstream = tcx.type_of(tokenstream); + let tokenstream = tcx.type_of(tokenstream).subst_identity(); let id = hir_id.expect_owner(); let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap(); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7cfffe390d3f..668c159f3cc5 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -315,7 +315,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { //// This is done to handle the case where, for example, the static //// method of a private type is used, but the type itself is never //// called directly. - let self_ty = self.tcx.type_of(item); + let self_ty = self.tcx.type_of(item).subst_identity(); match *self_ty.kind() { ty::Adt(def, _) => self.check_def_id(def.did()), ty::Foreign(did) => self.check_def_id(did), @@ -654,7 +654,7 @@ impl<'tcx> DeadVisitor<'tcx> { if self.live_symbols.contains(&field.did.expect_local()) { return ShouldWarnAboutField::No; } - let field_type = self.tcx.type_of(field.did); + let field_type = self.tcx.type_of(field.did).subst_identity(); if field_type.is_phantom_data() { return ShouldWarnAboutField::No; } diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 10ffa87efe35..0ae7096642cf 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/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 827d86780aa8..047b9b525e85 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -29,7 +29,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) { fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { let tcx = tcx; let param_env = tcx.param_env(item_def_id); - let ty = tcx.type_of(item_def_id); + let ty = tcx.type_of(item_def_id).subst_identity(); match tcx.layout_of(param_env.and(ty)) { Ok(ty_layout) => { // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 873c40e8cb61..2e736039fb59 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 4675bd79c462..58dfca75c65f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -159,9 +159,21 @@ where _region, ))) => ty.visit_with(self), ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => ControlFlow::Continue(()), + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + ct.visit_with(self)?; + ty.visit_with(self) + } ty::PredicateKind::ConstEvaluatable(ct) => ct.visit_with(self), ty::PredicateKind::WellFormed(arg) => arg.visit_with(self), - _ => bug!("unexpected predicate: {:?}", predicate), + + ty::PredicateKind::ObjectSafe(_) + | ty::PredicateKind::ClosureKind(_, _, _) + | ty::PredicateKind::Subtype(_) + | ty::PredicateKind::Coerce(_) + | ty::PredicateKind::ConstEquate(_, _) + | ty::PredicateKind::TypeWellFormedFromEnv(_) + | ty::PredicateKind::Ambiguous + | ty::PredicateKind::AliasEq(_, _) => bug!("unexpected predicate: {:?}", predicate), } } @@ -207,7 +219,7 @@ where // so we need to visit the self type additionally. if let Some(assoc_item) = tcx.opt_associated_item(def_id) { if let Some(impl_def_id) = assoc_item.impl_container(tcx) { - tcx.type_of(impl_def_id).visit_with(self)?; + tcx.type_of(impl_def_id).subst_identity().visit_with(self)?; } } } @@ -270,10 +282,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) } } @@ -341,7 +354,7 @@ trait VisibilityLike: Sized { effective_visibilities: &EffectiveVisibilities, ) -> Self { let mut find = FindMin { tcx, effective_visibilities, min: Self::MAX }; - find.visit(tcx.type_of(def_id)); + find.visit(tcx.type_of(def_id).subst_identity()); if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { find.visit_trait(trait_ref.subst_identity()); } @@ -837,11 +850,11 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { - self.visit(self.ev.tcx.type_of(param.def_id)); + self.visit(self.ev.tcx.type_of(param.def_id).subst_identity()); } } GenericParamDefKind::Const { has_default } => { - self.visit(self.ev.tcx.type_of(param.def_id)); + self.visit(self.ev.tcx.type_of(param.def_id).subst_identity()); if has_default { self.visit(self.ev.tcx.const_param_default(param.def_id).subst_identity()); } @@ -857,7 +870,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { } fn ty(&mut self) -> &mut Self { - self.visit(self.ev.tcx.type_of(self.item_def_id)); + self.visit(self.ev.tcx.type_of(self.item_def_id).subst_identity()); self } @@ -1268,7 +1281,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { // Method calls have to be checked specially. self.span = segment.ident.span; if let Some(def_id) = self.typeck_results().type_dependent_def_id(expr.hir_id) { - if self.visit(self.tcx.type_of(def_id)).is_break() { + if self.visit(self.tcx.type_of(def_id).subst_identity()).is_break() { return; } } else { @@ -1742,12 +1755,12 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { - self.visit(self.tcx.type_of(param.def_id)); + self.visit(self.tcx.type_of(param.def_id).subst_identity()); } } // FIXME(generic_const_exprs): May want to look inside const here GenericParamDefKind::Const { .. } => { - self.visit(self.tcx.type_of(param.def_id)); + self.visit(self.tcx.type_of(param.def_id).subst_identity()); } } } @@ -1774,7 +1787,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } fn ty(&mut self) -> &mut Self { - self.visit(self.tcx.type_of(self.item_def_id)); + self.visit(self.tcx.type_of(self.item_def_id).subst_identity()); self } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 2d243e13cc21..d7708a3bc3f4 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -21,7 +21,9 @@ use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::{self, DepKindStruct}; use rustc_middle::query::Key; -use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values}; +use rustc_middle::ty::query::{ + query_keys, query_provided, query_provided_to_value, query_storage, query_values, +}; use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 49309db564ea..e2884f2026eb 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -53,7 +53,7 @@ impl<'tcx> HasDepContext for QueryCtxt<'tcx> { } impl QueryContext for QueryCtxt<'_> { - fn next_job_id(&self) -> QueryJobId { + fn next_job_id(self) -> QueryJobId { QueryJobId( NonZeroU64::new( self.queries.jobs.fetch_add(1, rustc_data_structures::sync::Ordering::Relaxed), @@ -62,31 +62,31 @@ impl QueryContext for QueryCtxt<'_> { ) } - fn current_query_job(&self) -> Option { - tls::with_related_context(**self, |icx| icx.query) + fn current_query_job(self) -> Option { + tls::with_related_context(*self, |icx| icx.query) } - fn try_collect_active_jobs(&self) -> Option> { - self.queries.try_collect_active_jobs(**self) + fn try_collect_active_jobs(self) -> Option> { + self.queries.try_collect_active_jobs(*self) } // Interactions with on_disk_cache - fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects { + fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects { self.queries .on_disk_cache .as_ref() - .map(|c| c.load_side_effects(**self, prev_dep_node_index)) + .map(|c| c.load_side_effects(*self, prev_dep_node_index)) .unwrap_or_default() } - fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) { + fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) { if let Some(c) = self.queries.on_disk_cache.as_ref() { c.store_side_effects(dep_node_index, side_effects) } } fn store_side_effects_for_anon_node( - &self, + self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects, ) { @@ -100,7 +100,7 @@ impl QueryContext for QueryCtxt<'_> { /// captured during execution and the actual result. #[inline(always)] fn start_query( - &self, + self, token: QueryJobId, depth_limit: bool, diagnostics: Option<&Lock>>, @@ -109,14 +109,14 @@ impl QueryContext for QueryCtxt<'_> { // The `TyCtxt` stored in TLS has the same global interner lifetime // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes // when accessing the `ImplicitCtxt`. - tls::with_related_context(**self, move |current_icx| { + tls::with_related_context(*self, move |current_icx| { if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) { self.depth_limit_error(token); } // Update the `ImplicitCtxt` to point to our new query job. let new_icx = ImplicitCtxt { - tcx: **self, + tcx: *self, query: Some(token), diagnostics, query_depth: current_icx.query_depth + depth_limit as usize, @@ -130,7 +130,7 @@ impl QueryContext for QueryCtxt<'_> { }) } - fn depth_limit_error(&self, job: QueryJobId) { + fn depth_limit_error(self, job: QueryJobId) { let mut span = None; let mut layout_of_depth = None; if let Some(map) = self.try_collect_active_jobs() { @@ -293,14 +293,14 @@ macro_rules! get_provider { } macro_rules! should_ever_cache_on_disk { - ([]) => {{ - None + ([]$yes:tt $no:tt) => {{ + $no }}; - ([(cache) $($rest:tt)*]) => {{ - Some($crate::plumbing::try_load_from_disk::) + ([(cache) $($rest:tt)*]$yes:tt $no:tt) => {{ + $yes }}; - ([$other:tt $($modifiers:tt)*]) => { - should_ever_cache_on_disk!([$($modifiers)*]) + ([$other:tt $($modifiers:tt)*]$yes:tt $no:tt) => { + should_ever_cache_on_disk!([$($modifiers)*]$yes $no) }; } @@ -472,7 +472,6 @@ macro_rules! define_queries { $(impl<'tcx> QueryConfig> for queries::$name<'tcx> { type Key = query_keys::$name<'tcx>; type Value = query_values::$name<'tcx>; - type Stored = query_stored::$name<'tcx>; const NAME: &'static str = stringify!($name); #[inline] @@ -493,24 +492,39 @@ macro_rules! define_queries { fn query_cache<'a>(tcx: QueryCtxt<'tcx>) -> &'a Self::Cache where 'tcx:'a { - &tcx.query_caches.$name + &tcx.query_system.caches.$name } - fn execute_query(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Stored { + fn execute_query(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { tcx.$name(key) } #[inline] - // key is only sometimes used #[allow(unused_variables)] - fn compute(qcx: QueryCtxt<'tcx>, key: &Self::Key) -> fn(TyCtxt<'tcx>, Self::Key) -> Self::Value { - get_provider!([$($modifiers)*][qcx, $name, key]) + fn compute(qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { + query_provided_to_value::$name( + qcx.tcx, + get_provider!([$($modifiers)*][qcx, $name, key])(qcx.tcx, key) + ) } #[inline] - fn try_load_from_disk(qcx: QueryCtxt<'tcx>, key: &Self::Key) -> rustc_query_system::query::TryLoadFromDisk, Self> { - let cache_on_disk = Self::cache_on_disk(qcx.tcx, key); - if cache_on_disk { should_ever_cache_on_disk!([$($modifiers)*]) } else { None } + fn try_load_from_disk(_qcx: QueryCtxt<'tcx>, _key: &Self::Key) -> rustc_query_system::query::TryLoadFromDisk, Self> { + should_ever_cache_on_disk!([$($modifiers)*] { + if Self::cache_on_disk(_qcx.tcx, _key) { + Some(|qcx: QueryCtxt<'tcx>, dep_node| { + let value = $crate::plumbing::try_load_from_disk::>( + qcx, + dep_node + ); + value.map(|value| query_provided_to_value::$name(qcx.tcx, value)) + }) + } else { + None + } + } { + None + }) } const ANON: bool = is_anon!([$($modifiers)*]); @@ -633,7 +647,7 @@ macro_rules! define_queries { $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache( tcx, stringify!($name), - &tcx.query_caches.$name, + &tcx.query_system.caches.$name, string_cache, ) }, @@ -725,7 +739,7 @@ macro_rules! define_queries_struct { span: Span, key: as QueryConfig>>::Key, mode: QueryMode, - ) -> Option> { + ) -> Option> { let qcx = QueryCtxt { tcx, queries: self }; get_query::, _, rustc_middle::dep_graph::DepKind>(qcx, span, key, mode) })* diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index e370c6990a41..6969f2dbef8b 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -23,7 +23,7 @@ pub trait DepContext: Copy { type DepKind: self::DepKind; /// Create a hashing context for hashing new results. - fn with_stable_hashing_context(&self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R; + fn with_stable_hashing_context(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R; /// Access the DepGraph. fn dep_graph(&self) -> &DepGraph; @@ -37,7 +37,7 @@ pub trait DepContext: Copy { fn dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct; #[inline(always)] - fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle { + fn fingerprint_style(self, kind: Self::DepKind) -> FingerprintStyle { let data = self.dep_kind_info(kind); if data.is_anon { return FingerprintStyle::Opaque; @@ -47,7 +47,7 @@ pub trait DepContext: Copy { #[inline(always)] /// Return whether this kind always require evaluation. - fn is_eval_always(&self, kind: Self::DepKind) -> bool { + fn is_eval_always(self, kind: Self::DepKind) -> bool { self.dep_kind_info(kind).is_eval_always } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a81595b2420c..29513df460ff 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> GraphEncoder { 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_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 81c7e4673d41..e840108bdd86 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -1,12 +1,10 @@ use crate::dep_graph::DepNodeIndex; -use rustc_arena::TypedArena; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded; #[cfg(parallel_compiler)] use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::Lock; -use rustc_data_structures::sync::WorkerLocal; use rustc_index::vec::{Idx, IndexVec}; use std::fmt::Debug; use std::hash::Hash; @@ -16,12 +14,10 @@ pub trait CacheSelector<'tcx, V> { type Cache where V: Copy; - type ArenaCache; } pub trait QueryStorage { - type Value: Debug; - type Stored: Copy; + type Value: Copy; } pub trait QueryCache: QueryStorage + Sized { @@ -31,9 +27,9 @@ pub trait QueryCache: QueryStorage + Sized { /// It returns the shard index and a lock guard to the shard, /// which will be used if the query is not in the cache and we need /// to compute it. - fn lookup(&self, key: &Self::Key) -> Option<(Self::Stored, DepNodeIndex)>; + fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>; - fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex) -> Self::Stored; + fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex); fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); } @@ -44,7 +40,6 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<'tcx, V> for DefaultCacheSelecto type Cache = DefaultCache where V: Copy; - type ArenaCache = ArenaCache<'tcx, K, V>; } pub struct DefaultCache { @@ -62,7 +57,6 @@ impl Default for DefaultCache { impl QueryStorage for DefaultCache { type Value = V; - type Stored = V; } impl QueryCache for DefaultCache @@ -85,7 +79,7 @@ where } #[inline] - fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored { + fn complete(&self, key: K, value: V, index: DepNodeIndex) { #[cfg(parallel_compiler)] let mut lock = self.cache.get_shard_by_value(&key).lock(); #[cfg(not(parallel_compiler))] @@ -93,7 +87,6 @@ where // We may be overwriting another value. This is all right, since the dep-graph // will check that the fingerprint matches. lock.insert(key, (value, index)); - value } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { @@ -122,7 +115,6 @@ impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector { type Cache = SingleCache where V: Copy; - type ArenaCache = ArenaCache<'tcx, (), V>; } pub struct SingleCache { @@ -137,7 +129,6 @@ impl Default for SingleCache { impl QueryStorage for SingleCache { type Value = V; - type Stored = V; } impl QueryCache for SingleCache @@ -152,9 +143,8 @@ where } #[inline] - fn complete(&self, _key: (), value: V, index: DepNodeIndex) -> Self::Stored { + fn complete(&self, _key: (), value: V, index: DepNodeIndex) { *self.cache.lock() = Some((value, index)); - value } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { @@ -162,85 +152,12 @@ where } } -pub struct ArenaCache<'tcx, K, V> { - arena: WorkerLocal>, - #[cfg(parallel_compiler)] - cache: Sharded>, - #[cfg(not(parallel_compiler))] - cache: Lock>, -} - -impl<'tcx, K, V> Default for ArenaCache<'tcx, K, V> { - fn default() -> Self { - ArenaCache { arena: WorkerLocal::new(|_| TypedArena::default()), cache: Default::default() } - } -} - -impl<'tcx, K: Eq + Hash, V: Debug + 'tcx> QueryStorage for ArenaCache<'tcx, K, V> { - type Value = V; - type Stored = &'tcx V; -} - -impl<'tcx, K, V: 'tcx> QueryCache for ArenaCache<'tcx, K, V> -where - K: Eq + Hash + Clone + Debug, - V: Debug, -{ - type Key = K; - - #[inline(always)] - fn lookup(&self, key: &K) -> Option<(&'tcx V, DepNodeIndex)> { - let key_hash = sharded::make_hash(key); - #[cfg(parallel_compiler)] - let lock = self.cache.get_shard_by_hash(key_hash).lock(); - #[cfg(not(parallel_compiler))] - let lock = self.cache.lock(); - let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key); - - if let Some((_, value)) = result { Some((&value.0, value.1)) } else { None } - } - - #[inline] - fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored { - let value = self.arena.alloc((value, index)); - let value = unsafe { &*(value as *const _) }; - #[cfg(parallel_compiler)] - let mut lock = self.cache.get_shard_by_value(&key).lock(); - #[cfg(not(parallel_compiler))] - let mut lock = self.cache.lock(); - // We may be overwriting another value. This is all right, since the dep-graph - // will check that the fingerprint matches. - lock.insert(key, value); - &value.0 - } - - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { - #[cfg(parallel_compiler)] - { - let shards = self.cache.lock_shards(); - for shard in shards.iter() { - for (k, v) in shard.iter() { - f(k, &v.0, v.1); - } - } - } - #[cfg(not(parallel_compiler))] - { - let map = self.cache.lock(); - for (k, v) in map.iter() { - f(k, &v.0, v.1); - } - } - } -} - pub struct VecCacheSelector(PhantomData); impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector { type Cache = VecCache where V: Copy; - type ArenaCache = VecArenaCache<'tcx, K, V>; } pub struct VecCache { @@ -258,7 +175,6 @@ impl Default for VecCache { impl QueryStorage for VecCache { type Value = V; - type Stored = V; } impl QueryCache for VecCache @@ -278,87 +194,12 @@ where } #[inline] - fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored { + fn complete(&self, key: K, value: V, index: DepNodeIndex) { #[cfg(parallel_compiler)] let mut lock = self.cache.get_shard_by_hash(key.index() as u64).lock(); #[cfg(not(parallel_compiler))] let mut lock = self.cache.lock(); lock.insert(key, (value, index)); - value - } - - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { - #[cfg(parallel_compiler)] - { - let shards = self.cache.lock_shards(); - for shard in shards.iter() { - for (k, v) in shard.iter_enumerated() { - if let Some(v) = v { - f(&k, &v.0, v.1); - } - } - } - } - #[cfg(not(parallel_compiler))] - { - let map = self.cache.lock(); - for (k, v) in map.iter_enumerated() { - if let Some(v) = v { - f(&k, &v.0, v.1); - } - } - } - } -} - -pub struct VecArenaCache<'tcx, K: Idx, V> { - arena: WorkerLocal>, - #[cfg(parallel_compiler)] - cache: Sharded>>, - #[cfg(not(parallel_compiler))] - cache: Lock>>, -} - -impl<'tcx, K: Idx, V> Default for VecArenaCache<'tcx, K, V> { - fn default() -> Self { - VecArenaCache { - arena: WorkerLocal::new(|_| TypedArena::default()), - cache: Default::default(), - } - } -} - -impl<'tcx, K: Eq + Idx, V: Debug + 'tcx> QueryStorage for VecArenaCache<'tcx, K, V> { - type Value = V; - type Stored = &'tcx V; -} - -impl<'tcx, K, V: 'tcx> QueryCache for VecArenaCache<'tcx, K, V> -where - K: Eq + Idx + Clone + Debug, - V: Debug, -{ - type Key = K; - - #[inline(always)] - fn lookup(&self, key: &K) -> Option<(&'tcx V, DepNodeIndex)> { - #[cfg(parallel_compiler)] - let lock = self.cache.get_shard_by_hash(key.index() as u64).lock(); - #[cfg(not(parallel_compiler))] - let lock = self.cache.lock(); - if let Some(Some(value)) = lock.get(*key) { Some((&value.0, value.1)) } else { None } - } - - #[inline] - fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored { - let value = self.arena.alloc((value, index)); - let value = unsafe { &*(value as *const _) }; - #[cfg(parallel_compiler)] - let mut lock = self.cache.get_shard_by_hash(key.index() as u64).lock(); - #[cfg(not(parallel_compiler))] - let mut lock = self.cache.lock(); - lock.insert(key, value); - &value.0 } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index a28e45a5c086..56247e827a2d 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -20,10 +20,9 @@ pub trait QueryConfig { const NAME: &'static str; type Key: DepNodeParams + Eq + Hash + Clone + Debug; - type Value: Debug; - type Stored: Debug + Copy + std::borrow::Borrow; + type Value: Debug + Copy; - type Cache: QueryCache; + type Cache: QueryCache; // Don't use this method to access query results, instead use the methods on TyCtxt fn query_state<'a>(tcx: Qcx) -> &'a QueryState @@ -38,9 +37,9 @@ pub trait QueryConfig { fn cache_on_disk(tcx: Qcx::DepContext, key: &Self::Key) -> bool; // Don't use this method to compute query results, instead use the methods on TyCtxt - fn execute_query(tcx: Qcx::DepContext, k: Self::Key) -> Self::Stored; + fn execute_query(tcx: Qcx::DepContext, k: Self::Key) -> Self::Value; - fn compute(tcx: Qcx, key: &Self::Key) -> fn(Qcx::DepContext, Self::Key) -> Self::Value; + fn compute(tcx: Qcx, key: Self::Key) -> Self::Value; fn try_load_from_disk(qcx: Qcx, idx: &Self::Key) -> TryLoadFromDisk; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 6c0ee2bc2f6f..383c63cd2f8a 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -101,22 +101,22 @@ impl QuerySideEffects { } pub trait QueryContext: HasDepContext { - fn next_job_id(&self) -> QueryJobId; + fn next_job_id(self) -> QueryJobId; /// Get the query information from the TLS context. - fn current_query_job(&self) -> Option; + fn current_query_job(self) -> Option; - fn try_collect_active_jobs(&self) -> Option>; + fn try_collect_active_jobs(self) -> Option>; /// Load side effects associated to the node in the previous session. - fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects; + fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects; /// Register diagnostics for the given node, for use in next session. - fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects); + fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects); /// Register diagnostics for the given node, for use in next session. fn store_side_effects_for_anon_node( - &self, + self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects, ); @@ -125,12 +125,12 @@ pub trait QueryContext: HasDepContext { /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. fn start_query( - &self, + self, token: QueryJobId, depth_limit: bool, diagnostics: Option<&Lock>>, compute: impl FnOnce() -> R, ) -> R; - fn depth_limit_error(&self, job: QueryJobId); + fn depth_limit_error(self, job: QueryJobId); } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index ed66d1929c5e..53e04bcc132a 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -19,7 +19,6 @@ use rustc_data_structures::sync::Lock; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; -use std::borrow::Borrow; use std::cell::Cell; use std::collections::hash_map::Entry; use std::fmt::Debug; @@ -246,7 +245,7 @@ where /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query - fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) -> C::Stored + fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) where C: QueryCache, { @@ -257,23 +256,19 @@ where // Forget ourself so our destructor won't poison the query mem::forget(self); - let (job, result) = { - let job = { - #[cfg(parallel_compiler)] - let mut lock = state.active.get_shard_by_value(&key).lock(); - #[cfg(not(parallel_compiler))] - let mut lock = state.active.lock(); - match lock.remove(&key).unwrap() { - QueryResult::Started(job) => job, - QueryResult::Poisoned => panic!(), - } - }; - let result = cache.complete(key, result, dep_node_index); - (job, result) + let job = { + #[cfg(parallel_compiler)] + let mut lock = state.active.get_shard_by_value(&key).lock(); + #[cfg(not(parallel_compiler))] + let mut lock = state.active.lock(); + match lock.remove(&key).unwrap() { + QueryResult::Started(job) => job, + QueryResult::Poisoned => panic!(), + } }; + cache.complete(key, result, dep_node_index); job.signal_complete(); - result } } @@ -336,7 +331,7 @@ where /// which will be used if the query is not in the cache and we need /// to compute it. #[inline] -pub fn try_get_cached(tcx: Tcx, cache: &C, key: &C::Key) -> Option +pub fn try_get_cached(tcx: Tcx, cache: &C, key: &C::Key) -> Option where C: QueryCache, Tcx: DepContext, @@ -358,7 +353,7 @@ fn try_execute_query( span: Span, key: Q::Key, dep_node: Option>, -) -> (Q::Stored, Option) +) -> (Q::Value, Option) where Q: QueryConfig, Qcx: QueryContext, @@ -368,29 +363,17 @@ where let (result, dep_node_index) = execute_job::(qcx, key.clone(), dep_node, job.id); if Q::FEEDABLE { - // We may have put a value inside the cache from inside the execution. - // Verify that it has the same hash as what we have now, to ensure consistency. + // We should not compute queries that also got a value via feeding. + // This can't happen, as query feeding adds the very dependencies to the fed query + // as its feeding query had. So if the fed query is red, so is its feeder, which will + // get evaluated first, and re-feed the query. if let Some((cached_result, _)) = cache.lookup(&key) { - let hasher = Q::HASH_RESULT.expect("feedable forbids no_hash"); - - let old_hash = qcx.dep_context().with_stable_hashing_context(|mut hcx| { - hasher(&mut hcx, cached_result.borrow()) - }); - let new_hash = qcx - .dep_context() - .with_stable_hashing_context(|mut hcx| hasher(&mut hcx, &result)); - debug_assert_eq!( - old_hash, - new_hash, - "Computed query value for {:?}({:?}) is inconsistent with fed value,\ncomputed={:#?}\nfed={:#?}", - Q::DEP_KIND, - key, - result, - cached_result, + panic!( + "fed query later has its value computed. The already cached value: {cached_result:?}" ); } } - let result = job.complete(cache, result, dep_node_index); + job.complete(cache, result, dep_node_index); (result, Some(dep_node_index)) } TryGetJob::Cycle(error) => { @@ -426,9 +409,7 @@ where // Fast path for when incr. comp. is off. if !dep_graph.is_fully_enabled() { let prof_timer = qcx.dep_context().profiler().query_provider(); - let result = qcx.start_query(job_id, Q::DEPTH_LIMIT, None, || { - Q::compute(qcx, &key)(*qcx.dep_context(), key) - }); + let result = qcx.start_query(job_id, Q::DEPTH_LIMIT, None, || Q::compute(qcx, key)); let dep_node_index = dep_graph.next_virtual_depnode_index(); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); return (result, dep_node_index); @@ -454,17 +435,15 @@ where let (result, dep_node_index) = qcx.start_query(job_id, Q::DEPTH_LIMIT, Some(&diagnostics), || { if Q::ANON { - return dep_graph.with_anon_task(*qcx.dep_context(), Q::DEP_KIND, || { - Q::compute(qcx, &key)(*qcx.dep_context(), key) - }); + return dep_graph + .with_anon_task(*qcx.dep_context(), Q::DEP_KIND, || Q::compute(qcx, key)); } // `to_dep_node` is expensive for some `DepKind`s. let dep_node = dep_node_opt.unwrap_or_else(|| Q::construct_dep_node(*qcx.dep_context(), &key)); - let task = Q::compute(qcx, &key); - dep_graph.with_task(dep_node, *qcx.dep_context(), key, task, Q::HASH_RESULT) + dep_graph.with_task(dep_node, qcx, key, Q::compute, Q::HASH_RESULT) }); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -555,7 +534,7 @@ where let prof_timer = qcx.dep_context().profiler().query_provider(); // The dep-graph for this computation is already in-place. - let result = dep_graph.with_ignore(|| Q::compute(qcx, key)(*qcx.dep_context(), key.clone())); + let result = dep_graph.with_ignore(|| Q::compute(qcx, key.clone())); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -727,7 +706,7 @@ pub enum QueryMode { Ensure, } -pub fn get_query(qcx: Qcx, span: Span, key: Q::Key, mode: QueryMode) -> Option +pub fn get_query(qcx: Qcx, span: Span, key: Q::Key, mode: QueryMode) -> Option where D: DepKind, Q: QueryConfig, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d3bcbbabf55e..324de7461cd9 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 a3195a643668..5205d055cf9a 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 a967f4b940c8..3425e24585cd 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 e8bc19f88e3e..295e93f61033 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1022,7 +1022,13 @@ fn default_configuration(sess: &Session) -> CrateConfig { let panic_strategy = sess.panic_strategy(); ret.insert((sym::panic, Some(panic_strategy.desc_symbol()))); - for s in sess.opts.unstable_opts.sanitizer { + for mut s in sess.opts.unstable_opts.sanitizer { + // KASAN should use the same attribute name as ASAN, as it's still ASAN + // under the hood + if s == SanitizerSet::KERNELADDRESS { + s = SanitizerSet::ADDRESS; + } + let symbol = Symbol::intern(&s.to_string()); ret.insert((sym::sanitize, Some(symbol))); } @@ -2544,7 +2550,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 c851145440b8..bd32adbbdbb5 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 b6a328908ce0..2075ed57a94d 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 { // 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 d9e68320f8ff..0d5818bd39cf 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -370,7 +370,7 @@ mod desc { pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; - pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`"; + pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`"; pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; pub const parse_cfguard: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; @@ -684,6 +684,7 @@ mod parse { "address" => SanitizerSet::ADDRESS, "cfi" => SanitizerSet::CFI, "kcfi" => SanitizerSet::KCFI, + "kernel-address" => SanitizerSet::KERNELADDRESS, "leak" => SanitizerSet::LEAK, "memory" => SanitizerSet::MEMORY, "memtag" => SanitizerSet::MEMTAG, @@ -809,7 +810,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 +851,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 2aa8ca9e4a91..cbdcc5581e5e 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, - explain: &str, + explain: impl Into, ) -> 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, issue: GateIssue, - explain: &str, + explain: impl Into, ) -> 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_session/src/session.rs b/compiler/rustc_session/src/session.rs index e608b9fe0b3f..3dc09854b3cb 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -954,10 +954,10 @@ impl Session { /// Checks if LLVM lifetime markers should be emitted. pub fn emit_lifetime_markers(&self) -> bool { self.opts.optimize != config::OptLevel::No - // AddressSanitizer uses lifetimes to detect use after scope bugs. + // AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs. // MemorySanitizer uses lifetimes to detect use of uninitialized stack variables. // HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future. - || self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS) + || self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS) } pub fn is_proc_macro_attr(&self, attr: &Attribute) -> bool { diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index cdda052f5290..2340d501d5a6 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 { - 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 { - 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 56835a2466a5..37d2aea42ad8 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/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 23ff6b333f0d..744e8a4320e3 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -26,7 +26,7 @@ pub(super) fn mangle<'tcx>( let key = tcx.def_key(ty_def_id); match key.disambiguated_data.data { DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => { - instance_ty = tcx.type_of(ty_def_id); + instance_ty = tcx.type_of(ty_def_id).subst_identity(); debug!(?instance_ty); break; } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 547a59076602..d81722e59a66 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_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 710f38264036..59a2227cd364 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -696,13 +696,13 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio let variant = adt_def.non_enum_variant(); let param_env = tcx.param_env(variant.def_id); let field = variant.fields.iter().find(|field| { - let ty = tcx.type_of(field.did); + let ty = tcx.type_of(field.did).subst_identity(); let is_zst = tcx.layout_of(param_env.and(ty)).map_or(false, |layout| layout.is_zst()); !is_zst }); if let Some(field) = field { - let ty0 = tcx.bound_type_of(field.did).subst(tcx, substs); + let ty0 = tcx.type_of(field.did).subst(tcx, substs); // Generalize any repr(transparent) user-defined type that is either a pointer // or reference, and either references itself or any other type that contains or // references itself, to avoid a reference cycle. @@ -781,8 +781,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio let output = transform_ty(tcx, fn_sig.skip_binder().output(), options); ty = tcx.mk_fn_ptr(ty::Binder::bind_with_vars( tcx.mk_fn_sig( - parameters.iter(), - &output, + parameters, + output, fn_sig.c_variadic(), fn_sig.unsafety(), fn_sig.abi(), @@ -813,21 +813,18 @@ fn transform_substs<'tcx>( substs: SubstsRef<'tcx>, options: TransformTyOptions, ) -> SubstsRef<'tcx> { - let substs: Vec> = substs - .iter() - .map(|subst| { - if let GenericArgKind::Type(ty) = subst.unpack() { - if is_c_void_ty(tcx, ty) { - tcx.mk_unit().into() - } else { - transform_ty(tcx, ty, options).into() - } + let substs = substs.iter().map(|subst| { + if let GenericArgKind::Type(ty) = subst.unpack() { + if is_c_void_ty(tcx, ty) { + tcx.mk_unit().into() } else { - subst + transform_ty(tcx, ty, options).into() } - }) - .collect(); - tcx.mk_substs(substs.iter()) + } else { + subst + } + }); + tcx.mk_substs(substs) } /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index b5f9eb1259da..e9edfd2877b8 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -1,8 +1,11 @@ use super::apple_base::{ios_llvm_target, opts, Arch}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; + let mut base = opts("ios", arch); + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; + Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. @@ -28,7 +31,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..opts("ios", arch) + ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs index 3374755e2dd8..6e2d62b6e085 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs @@ -1,8 +1,11 @@ use super::apple_base::{ios_sim_llvm_target, opts, Arch}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64_sim; + let mut base = opts("ios", arch); + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; + Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. @@ -28,7 +31,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..opts("ios", arch) + ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs index 30fbe6f3c153..be27302f7f52 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs @@ -15,7 +15,7 @@ pub fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+v8a,+strict-align,+neon,+fp-armv8".into(), - supported_sanitizers: SanitizerSet::KCFI, + supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs index 8c65d6afcc18..f6f46aac4c39 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs @@ -19,7 +19,7 @@ pub fn target() -> Target { max_atomic_width: Some(32), emit_debug_gdb_scripts: false, // GCC and Clang default to 8 for arm-none here - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs index 7013bc60d16b..9608efe8bcf6 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs @@ -20,7 +20,7 @@ pub fn target() -> Target { max_atomic_width: Some(32), emit_debug_gdb_scripts: false, // GCC and Clang default to 8 for arm-none here - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs index 7ac1aab3b43c..28b109889e92 100644 --- a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs @@ -49,7 +49,7 @@ pub fn target() -> Target { // from thumb_base, rust-lang/rust#44993. emit_debug_gdb_scripts: false, // from thumb_base, apparently gcc/clang give enums a minimum of 8 bits on no-os targets - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs index 4e20fb325697..d59de86a2301 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs @@ -27,7 +27,7 @@ pub fn target() -> Target { max_atomic_width: Some(64), panic_strategy: PanicStrategy::Abort, emit_debug_gdb_scripts: false, - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs index ae70129ae518..8cdf3c36ba2e 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs @@ -19,7 +19,7 @@ pub fn target() -> Target { panic_strategy: PanicStrategy::Abort, emit_debug_gdb_scripts: false, // GCC and Clang default to 8 for arm-none here - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs index 25f301ccce74..5225abf44fca 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs @@ -18,7 +18,7 @@ pub fn target() -> Target { max_atomic_width: Some(32), emit_debug_gdb_scripts: false, // GCC and Clang default to 8 for arm-none here - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs index 40449759dd37..9a35e04617f9 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs @@ -19,7 +19,7 @@ pub fn target() -> Target { max_atomic_width: Some(32), emit_debug_gdb_scripts: false, // GCC and Clang default to 8 for arm-none here - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs index 3aad05eb2719..4c6ab5f5ae45 100644 --- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { base.has_rpath = true; base.linker_flavor = LinkerFlavor::Unix(Cc::Yes); - base.c_enum_min_bits = 8; + base.c_enum_min_bits = Some(8); Target { llvm_target: "hexagon-unknown-linux-musl".into(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index bc1920e34249..0d86a3032a65 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -812,6 +812,7 @@ bitflags::bitflags! { const MEMTAG = 1 << 6; const SHADOWCALLSTACK = 1 << 7; const KCFI = 1 << 8; + const KERNELADDRESS = 1 << 9; } } @@ -824,6 +825,7 @@ impl SanitizerSet { SanitizerSet::ADDRESS => "address", SanitizerSet::CFI => "cfi", SanitizerSet::KCFI => "kcfi", + SanitizerSet::KERNELADDRESS => "kernel-address", SanitizerSet::LEAK => "leak", SanitizerSet::MEMORY => "memory", SanitizerSet::MEMTAG => "memtag", @@ -866,6 +868,7 @@ impl IntoIterator for SanitizerSet { SanitizerSet::SHADOWCALLSTACK, SanitizerSet::THREAD, SanitizerSet::HWADDRESS, + SanitizerSet::KERNELADDRESS, ] .iter() .copied() @@ -1344,10 +1347,18 @@ impl Target { }); } - dl.c_enum_min_size = match Integer::from_size(Size::from_bits(self.c_enum_min_bits)) { - Ok(bits) => bits, - Err(err) => return Err(TargetDataLayoutErrors::InvalidBitsSize { err }), - }; + dl.c_enum_min_size = self + .c_enum_min_bits + .map_or_else( + || { + self.c_int_width + .parse() + .map_err(|_| String::from("failed to parse c_int_width")) + }, + Ok, + ) + .and_then(|i| Integer::from_size(Size::from_bits(i))) + .map_err(|err| TargetDataLayoutErrors::InvalidBitsSize { err })?; Ok(dl) } @@ -1701,8 +1712,8 @@ pub struct TargetOptions { /// If present it's a default value to use for adjusting the C ABI. pub default_adjusted_cabi: Option, - /// Minimum number of bits in #[repr(C)] enum. Defaults to 32. - pub c_enum_min_bits: u64, + /// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int + pub c_enum_min_bits: Option, /// Whether or not the DWARF `.debug_aranges` section should be generated. pub generate_arange_section: bool, @@ -1935,7 +1946,7 @@ impl Default for TargetOptions { supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), supported_sanitizers: SanitizerSet::empty(), default_adjusted_cabi: None, - c_enum_min_bits: 32, + c_enum_min_bits: None, generate_arange_section: true, supports_stack_protector: true, entry_name: "main".into(), @@ -2122,12 +2133,6 @@ impl Target { base.$key_name = s; } } ); - ($key_name:ident, u64) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|j| Json::as_u64(&j)) { - base.$key_name = s; - } - } ); ($key_name:ident, u32) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { @@ -2339,6 +2344,7 @@ impl Target { Some("address") => SanitizerSet::ADDRESS, Some("cfi") => SanitizerSet::CFI, Some("kcfi") => SanitizerSet::KCFI, + Some("kernel-address") => SanitizerSet::KERNELADDRESS, Some("leak") => SanitizerSet::LEAK, Some("memory") => SanitizerSet::MEMORY, Some("memtag") => SanitizerSet::MEMTAG, @@ -2496,6 +2502,7 @@ impl Target { key!(is_builtin, bool); key!(c_int_width = "target-c-int-width"); + key!(c_enum_min_bits, Option); // if None, matches c_int_width key!(os); key!(env); key!(abi); @@ -2591,7 +2598,6 @@ impl Target { key!(supported_split_debuginfo, falliable_list)?; key!(supported_sanitizers, SanitizerSet)?; key!(default_adjusted_cabi, Option)?; - key!(c_enum_min_bits, u64); key!(generate_arange_section, bool); key!(supports_stack_protector, bool); key!(entry_name); diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 409b0b269615..ab3c14e3fe73 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs @@ -1,6 +1,8 @@ use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; use crate::spec::{RelocModel, Target, TargetOptions}; +use super::SanitizerSet; + pub fn target() -> Target { Target { data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), @@ -20,6 +22,7 @@ pub fn target() -> Target { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, eh_frame_header: false, + supported_sanitizers: SanitizerSet::KERNELADDRESS, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs index 87aba9171b41..0f1821c9985b 100644 --- a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; -use crate::spec::{RelocModel, Target, TargetOptions}; +use crate::spec::{RelocModel, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -19,6 +19,7 @@ pub fn target() -> Target { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, eh_frame_header: false, + supported_sanitizers: SanitizerSet::KERNELADDRESS, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index 000766c57ce7..4dcf47fe465c 100644 --- a/compiler/rustc_target/src/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs @@ -53,7 +53,7 @@ pub fn opts() -> TargetOptions { frame_pointer: FramePointer::Always, // ARM supports multiple ABIs for enums, the linux one matches the default of 32 here // but any arm-none or thumb-none target will be defaulted to 8 on GCC and clang - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 5a3e4c88d3a9..e3734932f885 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -55,7 +55,7 @@ pub fn target() -> Target { // suggested from thumb_base, rust-lang/rust#44993. emit_debug_gdb_scripts: false, // suggested from thumb_base, with no-os gcc/clang use 8-bit enums - c_enum_min_bits: 8, + c_enum_min_bits: Some(8), frame_pointer: FramePointer::MayOmit, main_needs_argc_argv: false, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index fbd3ebd4d043..1dcb47056a46 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -1,8 +1,11 @@ use super::apple_base::{ios_sim_llvm_target, opts, Arch}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; + let mut base = opts("ios", arch); + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; + Target { llvm_target: ios_sim_llvm_target(arch).into(), pointer_width: 64, @@ -12,7 +15,7 @@ pub fn target() -> Target { options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, - ..opts("ios", arch) + ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs index 32060c35c11b..43c5ce78ce34 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs @@ -20,7 +20,7 @@ pub fn target() -> Target { features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" .into(), - supported_sanitizers: SanitizerSet::KCFI, + supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, disable_redzone: true, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Kernel), diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 28aa3d527059..6890811fd046 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -25,7 +25,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::Obligation; use rustc_middle::infer::canonical::Certainty as OldCertainty; use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate, }; @@ -290,6 +290,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(predicate)) => { self.compute_region_outlives_goal(Goal { param_env, predicate }) } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + self.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) }) + } ty::PredicateKind::Subtype(predicate) => { self.compute_subtype_goal(Goal { param_env, predicate }) } @@ -471,6 +474,16 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } } + + #[instrument(level = "debug", skip(self), ret)] + fn compute_const_arg_has_type_goal( + &mut self, + goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>, + ) -> QueryResult<'tcx> { + let (ct, ty) = goal.predicate; + let nested_goals = self.infcx.eq(goal.param_env, ct.ty(), ty)?; + self.evaluate_all_and_make_canonical_response(nested_goals) + } } impl<'tcx> EvalCtxt<'_, 'tcx> { diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index b52200e066f6..883342148f40 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -244,7 +244,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { // Finally we construct the actual value of the associated type. let is_const = matches!(tcx.def_kind(assoc_def.item.def_id), DefKind::AssocConst); - let ty = tcx.bound_type_of(assoc_def.item.def_id); + let ty = tcx.type_of(assoc_def.item.def_id); let term: ty::EarlyBinder> = if is_const { let identity_substs = ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id); @@ -388,7 +388,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty::Dynamic(_, _, _) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); - tcx.bound_type_of(dyn_metadata) + tcx.type_of(dyn_metadata) .subst(tcx, &[ty::GenericArg::from(goal.predicate.self_ty())]) } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 6554c739b3f0..d12e5f797fb9 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -326,7 +326,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .fields .last() .expect("expected unsized ADT to have a tail field"); - let tail_field_ty = tcx.bound_type_of(tail_field.did); + let tail_field_ty = tcx.type_of(tail_field.did); let a_tail_ty = tail_field_ty.subst(tcx, a_substs); let b_tail_ty = tail_field_ty.subst(tcx, b_substs); @@ -359,7 +359,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let b_last_ty = b_tys.last().unwrap(); // Substitute just the tail field of B., and require that they're equal. - let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty])); + let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied()); let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?; // Similar to ADTs, require that the rest of the fields are equal. diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 1ee35a86e626..3662463178f8 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -68,7 +68,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - Ok(vec![tcx.bound_type_of(def_id).subst(tcx, substs)]) + Ok(vec![tcx.type_of(def_id).subst(tcx, substs)]) } } } @@ -191,10 +191,10 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( ty::FnDef(def_id, substs) => Ok(Some( tcx.fn_sig(def_id) .subst(tcx, substs) - .map_bound(|sig| (tcx.mk_tup(sig.inputs().iter()), sig.output())), + .map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())), )), ty::FnPtr(sig) => { - Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs().iter()), sig.output())))) + Ok(Some(sig.map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())))) } ty::Closure(_, substs) => { let closure_substs = substs.as_closure(); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 3adb15cb4412..9776cc57af8e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -830,6 +830,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // and these don't correspond to adding any new bounds to // the `ParamEnv`. ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a95694e51446..599238e405de 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -82,8 +82,8 @@ pub fn overlapping_impls( (Some(a), Some(b)) => iter::zip(a.skip_binder().substs, b.skip_binder().substs) .all(|(arg1, arg2)| drcx.generic_args_may_unify(arg1, arg2)), (None, None) => { - let self_ty1 = tcx.type_of(impl1_def_id); - let self_ty2 = tcx.type_of(impl2_def_id); + let self_ty1 = tcx.type_of(impl1_def_id).skip_binder(); + let self_ty2 = tcx.type_of(impl2_def_id).skip_binder(); drcx.types_may_unify(self_ty1, self_ty2) } _ => bug!("unexpected impls: {impl1_def_id:?} {impl2_def_id:?}"), @@ -124,7 +124,7 @@ fn with_fresh_ty_vars<'cx, 'tcx>( let header = ty::ImplHeader { impl_def_id, - self_ty: tcx.bound_type_of(impl_def_id).subst(tcx, impl_substs), + self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs), trait_ref: tcx.impl_trait_ref(impl_def_id).map(|i| i.subst(tcx, impl_substs)), predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index edb36b4ac814..a32ab16263a2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1282,6 +1282,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span, "AliasEq predicate should never be the predicate cause of a SelectionError" ), + + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + self.tcx.sess.struct_span_err( + span, + &format!("the constant `{}` is not of type `{}`", ct, ty), + ) + } } } @@ -2432,7 +2439,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }; let mut suggestions = vec![( path.span.shrink_to_lo(), - format!("<{} as ", self.tcx.type_of(impl_def_id)) + format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity()) )]; if let Some(generic_arg) = trait_path_segment.args { let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext); 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 52ed64868c05..b3bf9ad599ac 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![]; @@ -200,7 +200,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(def) = self_ty.ty_adt_def() { // We also want to be able to select self's original // signature with no type arguments resolved - flags.push((sym::_Self, Some(self.tcx.type_of(def.did()).to_string()))); + flags.push(( + sym::_Self, + Some(self.tcx.type_of(def.did()).subst_identity().to_string()), + )); } for param in generics.params.iter() { @@ -218,7 +221,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(def) = param_ty.ty_adt_def() { // We also want to be able to select the parameter's // original signature with no type arguments resolved - flags.push((name, Some(self.tcx.type_of(def.did()).to_string()))); + flags.push(( + name, + Some(self.tcx.type_of(def.did()).subst_identity().to_string()), + )); } } } @@ -251,7 +257,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(def) = aty.ty_adt_def() { // We also want to be able to select the slice's type's original // signature with no type arguments resolved - flags.push((sym::_Self, Some(format!("[{}]", self.tcx.type_of(def.did()))))); + flags.push(( + sym::_Self, + Some(format!("[{}]", self.tcx.type_of(def.did()).subst_identity())), + )); } if aty.is_integral() { flags.push((sym::_Self, Some("[{integral}]".to_string()))); @@ -269,7 +278,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(def) = aty.ty_adt_def() { // We also want to be able to select the array's type's original // signature with no type arguments resolved - let def_ty = self.tcx.type_of(def.did()); + let def_ty = self.tcx.type_of(def.did()).subst_identity(); flags.push((sym::_Self, Some(format!("[{def_ty}; _]")))); if let Some(n) = len { flags.push((sym::_Self, Some(format!("[{def_ty}; {n}]")))); 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 135232d1b208..91b463800a81 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 }; @@ -2017,7 +2012,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let sig = match inputs.kind() { ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => { infcx.tcx.mk_fn_sig( - inputs.iter(), + *inputs, infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, @@ -2028,7 +2023,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } _ => infcx.tcx.mk_fn_sig( - std::iter::once(inputs), + [inputs], infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, @@ -3148,7 +3143,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { parent_trait_pred.print_modifiers_and_trait_path() ); let mut is_auto_trait = false; - match self.tcx.hir().get_if_local(data.impl_def_id) { + match self.tcx.hir().get_if_local(data.impl_or_alias_def_id) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(is_auto, ..), ident, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 19d47d33f671..deeed930e50e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -313,6 +313,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(..) @@ -600,6 +601,19 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::AliasEq(..) => { bug!("AliasEq is only used for new solver") } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + match self + .selcx + .infcx + .at(&obligation.cause, obligation.param_env) + .eq(ct.ty(), ty) + { + Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), + Err(_) => ProcessResult::Error(FulfillmentErrorCode::CodeSelectionError( + SelectionError::Unimplemented, + )), + } + } }, } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 41ee8cd9d3fa..2d299486ee68 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 7ef39b201074..df1aeed941d7 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -97,7 +97,7 @@ fn check_is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { /// object. Note that object-safe traits can have some /// non-vtable-safe methods, so long as they require `Self: Sized` or /// otherwise ensure that they cannot be used when `Self = Trait`. -pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: &ty::AssocItem) -> bool { +pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool { debug_assert!(tcx.generics_of(trait_def_id).has_self); debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self: Sized` bound cannot be called. @@ -120,8 +120,8 @@ fn object_safety_violations_for_trait( .associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Fn) - .filter_map(|item| { - object_safety_violation_for_method(tcx, trait_def_id, &item) + .filter_map(|&item| { + object_safety_violation_for_method(tcx, trait_def_id, item) .map(|(code, span)| ObjectSafetyViolation::Method(item.name, code, span)) }) .collect(); @@ -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,8 +325,12 @@ 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::Clause(ty::Clause::ConstArgHasType(_ct, ty)) => { + has_self_ty(&ty.into()).then_some(sp) + } + ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"), ty::PredicateKind::WellFormed(..) @@ -362,6 +366,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) @@ -382,7 +387,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn object_safety_violation_for_method( tcx: TyCtxt<'_>, trait_def_id: DefId, - method: &ty::AssocItem, + method: ty::AssocItem, ) -> Option<(MethodViolationCode, Span)> { debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self : Sized` requisite is otherwise @@ -415,7 +420,7 @@ fn object_safety_violation_for_method( fn virtual_call_violation_for_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, - method: &ty::AssocItem, + method: ty::AssocItem, ) -> Option { let sig = tcx.fn_sig(method.def_id).subst_identity(); @@ -527,8 +532,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` let trait_object_receiver = @@ -718,7 +722,7 @@ fn object_ty_for_trait<'tcx>( #[allow(dead_code)] fn receiver_is_dispatchable<'tcx>( tcx: TyCtxt<'tcx>, - method: &ty::AssocItem, + method: ty::AssocItem, receiver_ty: Ty<'tcx>, ) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a380d4697ea2..9b3249e58e8d 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -514,7 +514,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } let substs = substs.fold_with(self); - let generic_ty = self.interner().bound_type_of(def_id); + let generic_ty = self.interner().type_of(def_id); let concrete_ty = generic_ty.subst(self.interner(), substs); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); @@ -767,7 +767,7 @@ impl<'tcx> TypeFolder> 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> 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, } @@ -1923,7 +1923,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); - let substs = tcx.mk_substs([self_ty.into()].iter()); + let substs = tcx.intern_substs(&[self_ty.into()]); let lang_items = tcx.lang_items(); let item_def_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); @@ -2138,7 +2138,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx, param_env, impl_def_id, substs, assoc_ty.defining_node); - let ty = tcx.bound_type_of(assoc_ty.item.def_id); + let ty = tcx.type_of(assoc_ty.item.def_id); let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst); let term: ty::EarlyBinder> = if is_const { let identity_substs = @@ -2149,7 +2149,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( } else { ty.map_bound(|ty| ty.into()) }; - if !check_substs_compatible(tcx, &assoc_ty.item, substs) { + if !check_substs_compatible(tcx, assoc_ty.item, substs) { let err = tcx.ty_error_with_message( obligation.cause.span, "impl item and trait item have different parameters", @@ -2164,7 +2164,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( // Verify that the trait item and its implementation have compatible substs lists fn check_substs_compatible<'tcx>( tcx: TyCtxt<'tcx>, - assoc_item: &ty::AssocItem, + assoc_item: ty::AssocItem, substs: ty::SubstsRef<'tcx>, ) -> bool { fn check_substs_compatible_inner<'tcx>( @@ -2238,7 +2238,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( leaf_def.defining_node, ); - if !check_substs_compatible(tcx, &leaf_def.item, impl_fn_substs) { + if !check_substs_compatible(tcx, leaf_def.item, impl_fn_substs) { let err = tcx.ty_error_with_message( obligation.cause.span, "impl method and trait method have different parameters", diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index e7282a450f67..a266013b8fd4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -228,7 +228,7 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> return ty.try_super_fold_with(self); } - let generic_ty = self.interner().bound_type_of(def_id); + let generic_ty = self.interner().type_of(def_id); let concrete_ty = generic_ty.subst(self.interner(), substs); self.anon_depth += 1; if concrete_ty == ty { 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 0d42cd8250a1..21ef4e24fdb0 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 { - 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 e9f7c3bc4cca..dae602908a31 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 dc5bcb48cad7..e4a832e47281 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 { .. } => { @@ -557,15 +557,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1), ), - tcx.type_of(param.def_id), + tcx.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), ) .into() } }); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let assoc_ty_substs = tcx.intern_substs(&substs); - - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let bound = bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs); tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) @@ -1073,7 +1073,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .fields .last() .expect("expected unsized ADT to have a tail field"); - let tail_field_ty = tcx.bound_type_of(tail_field.did); + let tail_field_ty = tcx.type_of(tail_field.did); // Extract `TailField` and `TailField` from `Struct` and `Struct`, // normalizing in the process, since `type_of` returns something directly from @@ -1189,7 +1189,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let cause = obligation.derived_cause(|derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { derived, - impl_def_id, + impl_or_alias_def_id: impl_def_id, impl_def_predicate_index: None, span: obligation.cause.span, })) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fc9678233c3b..e6fc9bb92397 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 { @@ -996,6 +993,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bug!("AliasEq is only used for new solver") } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + match self.infcx.at(&obligation.cause, obligation.param_env).eq(ct.ty(), ty) { + Ok(inf_ok) => self.evaluate_predicates_recursively( + previous_stack, + inf_ok.into_obligations(), + ), + Err(_) => Ok(EvaluatedToErr), + } + } } }) } @@ -2353,7 +2359,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - t.rebind(vec![self.tcx().bound_type_of(def_id).subst(self.tcx(), substs)]) + t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]) } } } @@ -2660,7 +2666,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { derived, - impl_def_id: def_id, + impl_or_alias_def_id: def_id, impl_def_predicate_index: Some(index), span, })) @@ -3023,7 +3029,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/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 3b796c623c0a..d1d6a7a90cf7 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -455,7 +455,13 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti w.push('>'); } - write!(w, " {} for {}", trait_ref.print_only_trait_path(), tcx.type_of(impl_def_id)).unwrap(); + write!( + w, + " {} for {}", + trait_ref.print_only_trait_path(), + tcx.type_of(impl_def_id).subst_identity() + ) + .unwrap(); // The predicates will contain default bounds like `T: Sized`. We need to // remove these bounds, and add `T: ?Sized` to any untouched type parameters. 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 0f9196de4fb1..2e4a5cfe4bcf 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, } @@ -399,7 +399,7 @@ pub(crate) fn assoc_def( // If there is no such item in that impl, this function will fail with a // cycle error if the specialization graph is currently being built. if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_def_id) { - let &item = tcx.associated_item(impl_item_id); + let item = tcx.associated_item(impl_item_id); let impl_node = Node::Impl(impl_def_id); return Ok(LeafDef { item, diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 64daca714c32..9f5c5bbeac8d 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -197,12 +197,12 @@ fn own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &[Def .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Fn); // Now list each method's DefId (for within its trait). - let own_entries = trait_methods.filter_map(move |trait_method| { + let own_entries = trait_methods.filter_map(move |&trait_method| { debug!("own_existential_vtable_entry: trait_method={:?}", trait_method); let def_id = trait_method.def_id; // Some methods cannot be called on an object; skip those. - if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) { + if !is_vtable_safe_method(tcx, trait_def_id, trait_method) { debug!("own_existential_vtable_entry: not vtable safe"); return None; } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5cfb6cf332e1..6a881c233db0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -163,6 +163,10 @@ pub fn predicate_obligations<'tcx>( ty::TermKind::Const(c) => c.into(), }) } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + wf.compute(ct.into()); + wf.compute(ty.into()); + } ty::PredicateKind::WellFormed(arg) => { wf.compute(arg); } @@ -922,6 +926,7 @@ pub(crate) fn required_region_bounds<'tcx>( match obligation.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::WellFormed(..) diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 20725c656de6..e2b5d17e0730 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -246,7 +246,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // Grab the ADT and the param we might need to calculate its layout let param_env = tcx.param_env(did); - let adt_ty = tcx.type_of(did); + let adt_ty = tcx.type_of(did).subst_identity(); // The ADT is a 1-zst if it's a ZST and its alignment is 1. // Mark the ADT as _not_ a 1-zst if there was a layout error. @@ -468,7 +468,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let ty = self .interner .tcx - .bound_type_of(def_id) + .type_of(def_id) .subst(self.interner.tcx, bound_vars) .lower_into(self.interner); @@ -732,13 +732,13 @@ 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 .mk_const( ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), - tcx.type_of(param.def_id), + tcx.type_of(param.def_id).subst_identity(), ) .into(), }) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 2978fc4ed8c4..7635f4bfec3b 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -117,6 +117,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi // We can defer this, but ultimately we'll want to express // some of these in terms of chalk operations. ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) @@ -521,8 +523,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime> { 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 +533,14 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime 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) + } } } @@ -646,6 +648,7 @@ impl<'tcx> LowerInto<'tcx, Option None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::AliasEq(..) @@ -780,6 +783,7 @@ impl<'tcx> LowerInto<'tcx, Option None, ty::PredicateKind::WellFormed(_ty) => None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) | ty::PredicateKind::AliasEq(..) @@ -1025,7 +1029,7 @@ impl<'a, 'tcx> TypeFolder> 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 +1111,7 @@ impl<'tcx> TypeFolder> 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 +1120,7 @@ impl<'tcx> TypeFolder> 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_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 8b7f8033bfac..b5924e949146 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -308,7 +308,7 @@ pub(crate) fn adt_dtorck_constraint( let mut result = DropckConstraint::empty(); for field in def.all_fields() { - let fty = tcx.type_of(field.did); + let fty = tcx.type_of(field.did).subst_identity(); dtorck_constraint_for_ty(tcx, span, fty, 0, fty, &mut result)?; } result.outlives.extend(tcx.destructor_constraints(def)); diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 93f9b66e0f85..abf0c1c5f3e9 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -99,6 +99,9 @@ fn compute_implied_outlives_bounds<'tcx>( }; match pred { ty::PredicateKind::Clause(ty::Clause::Trait(..)) + // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound + // if we ever support that + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 07e716cda42c..2c18a0340507 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -60,6 +60,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => false, ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 27dc16259926..d34fce64dd7d 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -93,7 +93,7 @@ fn relate_mir_and_user_substs<'tcx>( let tcx = ocx.infcx.tcx; let cause = ObligationCause::dummy_with_span(span); - let ty = tcx.bound_type_of(def_id).subst(tcx, substs); + let ty = tcx.type_of(def_id).subst(tcx, substs); let ty = ocx.normalize(&cause, param_env, ty); debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); @@ -122,7 +122,7 @@ fn relate_mir_and_user_substs<'tcx>( if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { let self_ty = ocx.normalize(&cause, param_env, self_ty); - let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs); + let impl_self_ty = tcx.type_of(impl_def_id).subst(tcx, substs); let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index ad5527f5a778..41924dc2a6d9 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); @@ -142,8 +141,8 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Binder::bind_with_vars( tcx.mk_fn_sig( - [env_ty, resume_ty].iter(), - &ret_ty, + [env_ty, resume_ty], + ret_ty, false, hir::Unsafety::Normal, rustc_target::spec::abi::Abi::Rust, @@ -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/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index a6e0f13f6983..164cac6a010f 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -26,7 +26,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { } } -fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> { +fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems { if tcx.is_trait_alias(def_id) { ty::AssocItems::new(Vec::new()) } else { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index a9fbad55dac5..852156c24f42 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -144,7 +144,7 @@ fn recurse_build<'tcx>( for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - let new_args = tcx.mk_const_list(new_args.iter()); + let new_args = tcx.intern_const_list(&new_args); tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 2fe9d135fa56..eb307e66e342 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -28,7 +28,7 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { tcx.intern_type_list(&types) } // Only the impl self type - None => tcx.intern_type_list(&[tcx.type_of(def_id)]), + None => tcx.intern_type_list(&[tcx.type_of(def_id).subst_identity()]), } } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 8d46ba320fc0..de7230b0cfae 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -53,7 +53,8 @@ fn inner_resolve_instance<'tcx>( ) } else { let ty = tcx.type_of(def.def_id_for_type_of()); - let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty); + let item_type = + tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 2df4a5eab210..b860fb6c9186 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -453,9 +453,10 @@ fn layout_of_uncached<'tcx>( let param_env = tcx.param_env(def.did()); def.is_struct() && match def.variants().iter().next().and_then(|x| x.fields.last()) { - Some(last_field) => { - tcx.type_of(last_field.did).is_sized(tcx, param_env) - } + Some(last_field) => tcx + .type_of(last_field.did) + .subst_identity() + .is_sized(tcx, param_env), None => false, } }, diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index cd1475391a4d..c177d60bb596 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -242,7 +242,7 @@ fn drop_tys_helper<'tcx>( Ok(Vec::new()) } else { let field_tys = adt_def.all_fields().map(|field| { - let r = tcx.bound_type_of(field.did).subst(tcx, substs); + let r = tcx.type_of(field.did).subst(tcx, substs); debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); r }); @@ -295,9 +295,15 @@ fn adt_drop_tys<'tcx>( let adt_has_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant); // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_substs)` - drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false) - .collect::, _>>() - .map(|components| tcx.intern_type_list(&components)) + drop_tys_helper( + tcx, + tcx.type_of(def_id).subst_identity(), + tcx.param_env(def_id), + adt_has_dtor, + false, + ) + .collect::, _>>() + .map(|components| tcx.intern_type_list(&components)) } // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed // a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitute the generic parameters @@ -308,7 +314,7 @@ fn adt_significant_drop_tys( ) -> Result<&ty::List>, AlwaysRequiresDrop> { drop_tys_helper( tcx, - tcx.type_of(def_id), // identical to `tcx.make_adt(def, identity_substs)` + tcx.type_of(def_id).subst_identity(), // identical to `tcx.make_adt(def, identity_substs)` tcx.param_env(def_id), adt_consider_insignificant_dtor(tcx), true, diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 7f48fb804178..591017eecd2e 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -31,7 +31,7 @@ fn representability(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Representability { } Representability::Representable } - DefKind::Field => representability_ty(tcx, tcx.type_of(def_id)), + DefKind::Field => representability_ty(tcx, tcx.type_of(def_id).subst_identity()), def_kind => bug!("unexpected {def_kind:?}"), } } @@ -91,7 +91,7 @@ fn params_in_repr(tcx: TyCtxt<'_>, def_id: DefId) -> BitSet { let mut params_in_repr = BitSet::new_empty(generics.params.len()); for variant in adt_def.variants() { for field in variant.fields.iter() { - params_in_repr_ty(tcx, tcx.type_of(field.did), &mut params_in_repr); + params_in_repr_ty(tcx, tcx.type_of(field.did).subst_identity(), &mut params_in_repr); } } params_in_repr diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 41e837e8b754..2c50b766d21f 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -1,7 +1,9 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, +}; use rustc_session::config::TraitSolver; use rustc_span::def_id::{DefId, CRATE_DEF_ID}; use rustc_trait_selection::traits; @@ -103,7 +105,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { def.variants() .iter() .flat_map(|v| v.fields.last()) - .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))), + .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did).subst_identity())), ); debug!("adt_sized_constraint: {:?} => {:?}", def, result); @@ -299,7 +301,7 @@ fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List { - let self_ty = tcx.type_of(def_id); + let self_ty = tcx.type_of(def_id).subst_identity(); inputs.extend(self_ty.walk()); } @@ -355,7 +357,7 @@ fn instance_def_size_estimate<'tcx>( /// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. /// /// See [`ty::ImplOverlapKind::Issue33140`] for more details. -fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { +fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option>> { debug!("issue33140_self_ty({:?})", def_id); let trait_ref = tcx @@ -394,7 +396,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { if self_ty_matches { debug!("issue33140_self_ty - MATCHES!"); - Some(self_ty) + Some(EarlyBinder(self_ty)) } else { debug!("issue33140_self_ty - non-matching self type"); None @@ -434,7 +436,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet { +/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` +/// that produces `T` items. You could combine them with +/// `f(&iter.collect::>())`, but this requires allocating memory for the +/// `Vec`. +/// +/// This trait allows for faster implementations, intended for cases where the +/// number of items produced by the iterator is small. There is a blanket impl +/// for `T` items, but there is also a fallible impl for `Result` items. +pub trait CollectAndApply: Sized { type Output; - fn intern_with(self, f: F) -> Self::Output + + /// Produce a result of type `Self::Output` from `iter`. The result will + /// typically be produced by applying `f` on the elements produced by + /// `iter`, though this may not happen in some impls, e.g. if an error + /// occured during iteration. + fn collect_and_apply(iter: I, f: F) -> Self::Output where + I: Iterator, F: FnOnce(&[T]) -> R; } -impl InternAs for I -where - E: InternIteratorElement, - I: Iterator, -{ - type Output = E::Output; - fn intern_with(self, f: F) -> Self::Output +/// The blanket impl that always collects all elements and applies `f`. +impl CollectAndApply for T { + type Output = R; + + /// Equivalent to `f(&iter.collect::>())`. + fn collect_and_apply(mut iter: I, f: F) -> R where + I: Iterator, F: FnOnce(&[T]) -> R, { - E::intern_with(self, f) - } -} - -pub trait InternIteratorElement: Sized { - type Output; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output; -} - -impl InternIteratorElement for T { - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // Lengths 0, 1, and 2 typically account for ~95% of cases. If @@ -127,23 +126,17 @@ impl InternIteratorElement for T { } } -impl<'a, T, R> InternIteratorElement for &'a T -where - T: Clone + 'a, -{ - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { - // This code isn't hot. - f(&iter.cloned().collect::>()) - } -} - -impl InternIteratorElement for Result { +/// A fallible impl that will fail, without calling `f`, if there are any +/// errors during collection. +impl CollectAndApply for Result { type Output = Result; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { + + /// Equivalent to `Ok(f(&iter.collect::>>()?))`. + fn collect_and_apply(mut iter: I, f: F) -> Result + where + I: Iterator>, + F: FnOnce(&[T]) -> R, + { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // Lengths 0, 1, and 2 typically account for ~95% of cases. If diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 5a0b8594104e..9e3e13e70040 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(self, other: I) -> Option where diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 1675ed158c9c..ff7821fb9ff0 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -58,9 +58,10 @@ fn args(builder: &Builder<'_>) -> Vec { 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/compile.rs b/src/bootstrap/compile.rs index 07c0d2233cae..e7d7215166b4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -445,6 +445,72 @@ impl Step for StdLink { let libdir = builder.sysroot_libdir(target_compiler, target); let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); + + if compiler.stage == 0 { + // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0` + // work for stage0-sysroot + let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot"); + + let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib"); + let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap()); + let host_codegen_backends = + host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends"); + let sysroot_bin_dir = sysroot.join("bin"); + let sysroot_lib_dir = sysroot.join("lib"); + let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler); + + // Create the `bin` directory in stage0-sysroot + t!(fs::create_dir_all(&sysroot_bin_dir)); + + // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin` + if let Ok(files) = fs::read_dir(&host_bin_dir) { + for file in files { + let file = t!(file); + if file.file_name() == "rustfmt" { + // This is when `rustc` and `cargo` are set in `config.toml` + if !file.path().starts_with(&builder.out) { + builder.copy( + &file.path().into_boxed_path(), + &sysroot_bin_dir.join(file.file_name()), + ); + } else { + builder.copy( + &builder + .out + .join(&compiler.host.triple) + .join("rustfmt/bin/rustfmt"), + &sysroot_bin_dir.join(file.file_name()), + ); + } + } else { + builder.copy( + &file.path().into_boxed_path(), + &sysroot_bin_dir.join(file.file_name()), + ); + } + } + } + + // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib` + if let Ok(files) = fs::read_dir(&host_lib_dir) { + for file in files { + let file = t!(file); + let path = file.path(); + if path.is_file() + && is_dylib(&file.file_name().into_string().unwrap()) + && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path()) + { + builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap())); + } + } + } + + t!(fs::create_dir_all(&sysroot_codegen_backends)); + // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists. + if host_codegen_backends.exists() { + builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends); + } + } } } @@ -467,7 +533,12 @@ fn copy_sanitizers( let dst = libdir.join(&runtime.name); builder.copy(&runtime.path, &dst); - if target == "x86_64-apple-darwin" || target == "aarch64-apple-darwin" { + if target == "x86_64-apple-darwin" + || target == "aarch64-apple-darwin" + || target == "aarch64-apple-ios" + || target == "aarch64-apple-ios-sim" + || target == "x86_64-apple-ios" + { // Update the library’s install name to reflect that it has been renamed. apple_darwin_update_library_name(&dst, &format!("@rpath/{}", &runtime.name)); // Upon renaming the install name, the code signature of the file will invalidate, diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e5fad5389697..cd027a4abb7f 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, + /// `None` if we shouldn't download CI compiler artifacts, or the commit to download if we should. #[cfg(not(test))] download_rustc_commit: Option, @@ -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/configure.py b/src/bootstrap/configure.py index 0af329e7007a..04e798e3949d 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -379,8 +379,14 @@ cur_section = None sections[None] = [] section_order = [None] targets = {} +top_level_keys = [] for line in open(rust_dir + '/config.toml.example').read().split("\n"): + if cur_section == None: + if line.count('=') == 1: + top_level_key = line.split('=')[0] + top_level_key = top_level_key.strip(' #') + top_level_keys.append(top_level_key) if line.startswith('['): cur_section = line[1:-1] if cur_section.startswith('target'): @@ -459,12 +465,22 @@ def configure_section(lines, config): raise RuntimeError("failed to find config line for {}".format(key)) -for section_key in config: - section_config = config[section_key] - if section_key not in sections: - raise RuntimeError("config key {} not in sections".format(section_key)) +def configure_top_level_key(lines, top_level_key, value): + for i, line in enumerate(lines): + if line.startswith('#' + top_level_key + ' = ') or line.startswith(top_level_key + ' = '): + lines[i] = "{} = {}".format(top_level_key, value) + return - if section_key == 'target': + raise RuntimeError("failed to find config line for {}".format(top_level_key)) + + +for section_key, section_config in config.items(): + if section_key not in sections and section_key not in top_level_keys: + raise RuntimeError("config key {} not in sections or top_level_keys".format(section_key)) + if section_key in top_level_keys: + configure_top_level_key(sections[None], section_key, section_config) + + elif section_key == 'target': for target in section_config: configure_section(targets[target], section_config[target]) else: diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index ff927ed561b2..f07e710a9e6b 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, + + /// Arguments appearing after `--` to be forwarded to tools, + /// e.g. `--fix-broken` or test arguments. + pub free_args: Option>, } #[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 [options] [...] @@ -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/native.rs b/src/bootstrap/native.rs index 9235de75ec67..d6e63fb937ec 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -483,7 +483,7 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } - configure_cmake(builder, target, &mut cfg, true, ldflags); + configure_cmake(builder, target, &mut cfg, true, ldflags, &[]); configure_llvm(builder, target, &mut cfg); for (key, val) in &builder.config.llvm_build_config { @@ -574,6 +574,7 @@ fn configure_cmake( cfg: &mut cmake::Config, use_compiler_launcher: bool, mut ldflags: LdFlags, + extra_compiler_flags: &[&str], ) { // Do not print installation messages for up-to-date files. // LLVM and LLD builds can produce a lot of those and hit CI limits on log size. @@ -714,6 +715,9 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cflags.push(&format!(" --target={}", target)); } + for flag in extra_compiler_flags { + cflags.push(&format!(" {}", flag)); + } cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::Cxx).join(" ").into(); if let Some(ref s) = builder.config.llvm_cxxflags { @@ -723,6 +727,9 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cxxflags.push(&format!(" --target={}", target)); } + for flag in extra_compiler_flags { + cxxflags.push(&format!(" {}", flag)); + } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { if ar.is_absolute() { @@ -864,7 +871,7 @@ impl Step for Lld { } } - configure_cmake(builder, target, &mut cfg, true, ldflags); + configure_cmake(builder, target, &mut cfg, true, ldflags, &[]); configure_llvm(builder, target, &mut cfg); // Re-use the same flags as llvm to control the level of debug information @@ -1028,7 +1035,16 @@ impl Step for Sanitizers { // Unfortunately sccache currently lacks support to build them successfully. // Disable compiler launcher on Darwin targets to avoid potential issues. let use_compiler_launcher = !self.target.contains("apple-darwin"); - configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher, LdFlags::default()); + let extra_compiler_flags: &[&str] = + if self.target.contains("apple") { &["-fembed-bitcode=off"] } else { &[] }; + configure_cmake( + builder, + self.target, + &mut cfg, + use_compiler_launcher, + LdFlags::default(), + extra_compiler_flags, + ); t!(fs::create_dir_all(&out_dir)); cfg.out_dir(out_dir); @@ -1084,12 +1100,15 @@ fn supported_sanitizers( match &*target.triple { "aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), + "aarch64-apple-ios" => darwin_libs("ios", &["asan", "tsan"]), + "aarch64-apple-ios-sim" => darwin_libs("iossim", &["asan", "tsan"]), "aarch64-unknown-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]), "aarch64-unknown-linux-gnu" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) } "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), + "x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]), "x86_64-unknown-freebsd" => common_libs("freebsd", "x86_64", &["asan", "msan", "tsan"]), "x86_64-unknown-netbsd" => { common_libs("netbsd", "x86_64", &["asan", "lsan", "msan", "tsan"]) diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index e0280854541a..e14440f57a8a 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 f8835fe11a8c..9cd6107b43ac 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/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 70c3a445b864..262cef3454ad 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -531,6 +531,24 @@ LLVM KCFI is supported on the following targets: See the [Clang KernelControlFlowIntegrity documentation][clang-kcfi] for more details. +# KernelAddressSanitizer + +KernelAddressSanitizer (KASAN) is a freestanding version of AddressSanitizer +which is suitable for detecting memory errors in programs which do not have a +runtime environment, such as operating system kernels. KernelAddressSanitizer +requires manual implementation of the underlying functions used for tracking +KernelAddressSanitizer state. + +KernelAddressSanitizer is supported on the following targets: + +* `aarch64-unknown-none` +* `riscv64gc-unknown-none-elf` +* `riscv64imac-unknown-none-elf` +* `x86_64-unknown-none` + +See the [Linux Kernel's KernelAddressSanitizer documentation][linux-kasan] for +more details. + # LeakSanitizer LeakSanitizer is run-time memory leak detector. @@ -714,6 +732,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT * [AddressSanitizer in Clang][clang-asan] * [ControlFlowIntegrity in Clang][clang-cfi] * [HWAddressSanitizer in Clang][clang-hwasan] +* [Linux Kernel's KernelAddressSanitizer documentation][linux-kasan] * [LeakSanitizer in Clang][clang-lsan] * [MemorySanitizer in Clang][clang-msan] * [MemTagSanitizer in LLVM][llvm-memtag] @@ -727,4 +746,5 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html [clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html +[linux-kasan]: https://www.kernel.org/doc/html/latest/dev-tools/kasan.html [llvm-memtag]: https://llvm.org/docs/MemTagSanitizer.html diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 6c15eac2c192..9479b3ee0369 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -137,7 +137,7 @@ where pub(crate) fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec { let tcx = self.cx.tcx; let param_env = tcx.param_env(item_def_id); - let ty = tcx.type_of(item_def_id); + let ty = tcx.type_of(item_def_id).subst_identity(); let f = auto_trait::AutoTraitFinder::new(tcx); debug!("get_auto_trait_impls({:?})", ty); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index e6b2b2349452..bcdbbcacc4bc 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -15,7 +15,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec { let cx = &mut self.cx; let param_env = cx.tcx.param_env(item_def_id); - let ty = cx.tcx.bound_type_of(item_def_id); + let ty = cx.tcx.type_of(item_def_id); trace!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8bb8f122e226..148243683cbb 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -303,7 +303,8 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box { let predicates = cx.tcx.explicit_predicates_of(did); - let type_ = clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did)), cx, Some(did)); + let type_ = + clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()), cx, Some(did)); Box::new(clean::Typedef { type_, @@ -414,7 +415,9 @@ pub(crate) fn build_impl( let for_ = match &impl_item { Some(impl_) => clean_ty(impl_.self_ty, cx), - None => clean_middle_ty(ty::Binder::dummy(tcx.type_of(did)), cx, Some(did)), + None => { + clean_middle_ty(ty::Binder::dummy(tcx.type_of(did).subst_identity()), cx, Some(did)) + } }; // Only inline impl if the implementing type is @@ -652,14 +655,22 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { clean::Constant { - type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(def_id)), cx, Some(def_id)), + type_: clean_middle_ty( + ty::Binder::dummy(cx.tcx.type_of(def_id).subst_identity()), + cx, + Some(def_id), + ), kind: clean::ConstantKind::Extern { def_id }, } } fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { - type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did)), cx, Some(did)), + type_: clean_middle_ty( + ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()), + cx, + Some(did), + ), mutability: if mutable { Mutability::Mut } else { Mutability::Not }, expr: None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 65736bb16fc0..0c70d31ed607 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() { @@ -215,7 +217,11 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant { let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id(); Constant { - type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(def_id)), cx, Some(def_id)), + type_: clean_middle_ty( + ty::Binder::dummy(cx.tcx.type_of(def_id).subst_identity()), + cx, + Some(def_id), + ), kind: ConstantKind::Anonymous { body: constant.value.body }, } } @@ -314,6 +320,7 @@ pub(crate) fn clean_predicate<'tcx>( // FIXME(generic_const_exprs): should this do something? ty::PredicateKind::ConstEvaluatable(..) => None, ty::PredicateKind::WellFormed(..) => None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Subtype(..) | ty::PredicateKind::AliasEq(..) @@ -480,7 +487,7 @@ fn clean_generic_param_def<'tcx>( ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { Some(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def.def_id)), + ty::Binder::dummy(cx.tcx.type_of(def.def_id).subst_identity()), cx, Some(def.def_id), )) @@ -502,7 +509,12 @@ fn clean_generic_param_def<'tcx>( GenericParamDefKind::Const { did: def.def_id, ty: Box::new(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def.def_id)), + ty::Binder::dummy( + cx.tcx + .type_of(def.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + ), cx, Some(def.def_id), )), @@ -1212,7 +1224,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let kind = match assoc_item.kind { ty::AssocKind::Const => { let ty = clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id)), + ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), cx, Some(assoc_item.def_id), ); @@ -1251,7 +1263,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( if assoc_item.fn_has_self_parameter { let self_ty = match assoc_item.container { - ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)), + ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)).subst_identity(), ty::TraitContainer => tcx.types.self_param, }; let self_arg_ty = sig.input(0).skip_binder(); @@ -1398,7 +1410,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( AssocTypeItem( Box::new(Typedef { type_: clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id)), + ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), cx, Some(assoc_item.def_id), ), @@ -1416,7 +1428,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( AssocTypeItem( Box::new(Typedef { type_: clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id)), + ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), cx, Some(assoc_item.def_id), ), @@ -1926,7 +1938,11 @@ pub(crate) fn clean_middle_field<'tcx>(field: &ty::FieldDef, cx: &mut DocContext clean_field_with_def_id( field.did, field.name, - clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(field.did)), cx, Some(field.did)), + clean_middle_ty( + ty::Binder::dummy(cx.tcx.type_of(field.did).subst_identity()), + cx, + Some(field.did), + ), cx, ) } @@ -2079,8 +2095,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 +2112,149 @@ fn get_all_import_attributes<'hir>( tcx: TyCtxt<'hir>, target_def_id: LocalDefId, attributes: &mut Vec, + 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 { + 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, + 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 +2343,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] }) @@ -2257,9 +2389,11 @@ fn clean_impl<'tcx>( let for_ = clean_ty(impl_.self_ty, cx); let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) { - DefKind::TyAlias => { - Some(clean_middle_ty(ty::Binder::dummy(tcx.type_of(did)), cx, Some(did))) - } + DefKind::TyAlias => Some(clean_middle_ty( + ty::Binder::dummy(tcx.type_of(did).subst_identity()), + cx, + Some(did), + )), _ => None, }); let mut make_item = |trait_: Option, for_: Type, items: Vec| { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 4d8ce54dc5c6..5a564c2ac1c4 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -129,7 +129,7 @@ fn external_generic_args<'tcx>( }); GenericArgs::Parenthesized { inputs, output } } else { - GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() } + GenericArgs::AngleBracketed { args: args.into(), bindings } } } @@ -266,7 +266,7 @@ pub(crate) fn print_evaluated_const( underscores_and_type: bool, ) -> Option { tcx.const_eval_poly(def_id).ok().and_then(|val| { - let ty = tcx.type_of(def_id); + let ty = tcx.type_of(def_id).subst_identity(); match (val, ty.kind()) { (_, &ty::Ref(..)) => None, (ConstValue::Scalar(_), &ty::Adt(_, _)) => None, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b1db16cfe3ca..68bdd2bc531f 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -453,7 +453,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { | clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => { dids.insert(path.def_id()); if let Some(generics) = path.generics() && - let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).kind() && + let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).subst_identity().kind() && adt.is_fundamental() { for ty in generics { if let Some(did) = ty.def_id(self.cache) { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1ed0b0bc2d55..aa406f30cbe6 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/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4ff1c93dc5d5..387984a2b3bc 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1855,7 +1855,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { let tcx = cx.tcx(); let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); match tcx.layout_of(param_env.and(ty)) { Ok(ty_layout) => { writeln!( diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index b2208da9060d..d2c6e7ab0249 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -293,7 +293,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let ty_res = self.resolve_path(&path, TypeNS, item_id, module_id).ok_or_else(no_res)?; match ty_res { - Res::Def(DefKind::Enum, did) => match tcx.type_of(did).kind() { + Res::Def(DefKind::Enum, did) => match tcx.type_of(did).subst_identity().kind() { ty::Adt(def, _) if def.is_enum() => { if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) && let Some(field) = variant.fields.iter().find(|f| f.name == variant_field_name) { @@ -471,7 +471,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { /// This is used for resolving type aliases. fn def_id_to_res(&self, ty_id: DefId) -> Option { use PrimitiveType::*; - Some(match *self.cx.tcx.type_of(ty_id).kind() { + Some(match *self.cx.tcx.type_of(ty_id).subst_identity().kind() { ty::Bool => Res::Primitive(Bool), ty::Char => Res::Primitive(Char), ty::Int(ity) => Res::Primitive(ity.into()), @@ -572,7 +572,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { debug!("looking for associated item named {} for item {:?}", item_name, did); // Checks if item_name is a variant of the `SomeItem` enum if ns == TypeNS && def_kind == DefKind::Enum { - match tcx.type_of(did).kind() { + match tcx.type_of(did).subst_identity().kind() { ty::Adt(adt_def, _) => { for variant in adt_def.variants() { if variant.name == item_name { @@ -606,7 +606,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // something like [`ambi_fn`](::ambi_fn) .or_else(|| { resolve_associated_trait_item( - tcx.type_of(did), + tcx.type_of(did).subst_identity(), module_id, item_name, ns, @@ -639,7 +639,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // they also look like associated items (`module::Type::Variant`), // because they are real Rust syntax (unlike the intra-doc links // field syntax) and are handled by the compiler's resolver. - let def = match tcx.type_of(did).kind() { + let def = match tcx.type_of(did).subst_identity().kind() { ty::Adt(def, _) if !def.is_enum() => def, _ => return None, }; @@ -689,12 +689,12 @@ fn resolve_associated_trait_item<'a>( .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_) .map(|trait_assoc| { trait_assoc_to_impl_assoc_item(cx.tcx, impl_, trait_assoc.def_id) - .unwrap_or(trait_assoc) + .unwrap_or(*trait_assoc) }) }); // FIXME(#74563): warn about ambiguity debug!("the candidates were {:?}", candidates.clone().collect::>()); - candidates.next().copied() + candidates.next() } /// Find the associated item in the impl `impl_id` that corresponds to the @@ -711,7 +711,7 @@ fn trait_assoc_to_impl_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, impl_id: DefId, trait_assoc_id: DefId, -) -> Option<&'tcx ty::AssocItem> { +) -> Option { let trait_to_impl_assoc_map = tcx.impl_item_implementor_ids(impl_id); debug!(?trait_to_impl_assoc_map); let impl_assoc_id = *trait_to_impl_assoc_map.get(&trait_assoc_id)?; @@ -1710,7 +1710,7 @@ fn resolution_failure( Res::Primitive(_) => None, }; let is_struct_variant = |did| { - if let ty::Adt(def, _) = tcx.type_of(did).kind() + if let ty::Adt(def, _) = tcx.type_of(did).subst_identity().kind() && def.is_enum() && let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) { // ctor is `None` if variant is a struct diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 189b37b69d13..01ed4a60b3b8 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -109,7 +109,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // `Generics`. To avoid relying on the `impl` block, these // things would need to be created from wholecloth, in a // form that is valid for use in type inference. - let ty = tcx.type_of(def_id); + let ty = tcx.type_of(def_id).subst_identity(); match ty.kind() { ty::Slice(ty) | ty::Ref(_, ty, _) diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index f2ee99cd9d49..f28c164d61da 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -169,7 +169,7 @@ where }; let ident_span = path.ident.span; - (tcx.type_of(def_id), call_span, ident_span) + (tcx.type_of(def_id).subst_identity(), call_span, ident_span) } _ => { return; diff --git a/src/tools/cargo b/src/tools/cargo index 39c13e67a596..17b3d0de0897 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 39c13e67a5962466cc7253d41bc1099bbcb224c3 +Subproject commit 17b3d0de0897e1c6b8ca347bd39f850bb0a5b9f6 diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index 97054a0d1015..6c8ee296c751 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -66,7 +66,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned") && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.tcx.impl_of_method(def_id) - && cx.tcx.type_of(def_id).is_unsafe_ptr() + && cx.tcx.type_of(def_id).subst_identity().is_unsafe_ptr() { true } else { diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs index e38f77268530..0fc11523298f 100644 --- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs @@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator { of_trait: Some(ref trait_ref), .. }) = item.kind; - let ty = cx.tcx.type_of(item.owner_id); + let ty = cx.tcx.type_of(item.owner_id).subst_identity(); if is_copy(cx, ty); if let Some(trait_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id); diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index a04693f4637a..080d44e6398c 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { .fields .iter() .all(|field| { - is_copy(cx, cx.tcx.type_of(field.did)) + is_copy(cx, cx.tcx.type_of(field.did).subst_identity()) }); if !has_drop(cx, binding_type) || all_fields_are_copy; then { diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index f806ba238c7c..4e1a6cd4d735 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -167,7 +167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { .iter() .find_map(|f_def| { if f_def.ident(self.cx.tcx) == field.ident - { Some(self.cx.tcx.type_of(f_def.did)) } + { Some(self.cx.tcx.type_of(f_def.did).subst_identity()) } else { None } }); self.ty_bounds.push(bound.into()); diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 6c333afacc64..b4543aa2544f 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -735,7 +735,7 @@ fn walk_parents<'tcx>( span, .. }) if span.ctxt() == ctxt => { - let ty = cx.tcx.type_of(owner_id.def_id); + let ty = cx.tcx.type_of(owner_id.def_id).subst_identity(); Some(ty_auto_deref_stability(cx, ty, precedence).position_for_result(cx)) }, @@ -771,7 +771,7 @@ fn walk_parents<'tcx>( }) => variant_of_res(cx, cx.qpath_res(path, *hir_id)) .and_then(|variant| variant.fields.iter().find(|f| f.name == field.ident.name)) .map(|field_def| { - ty_auto_deref_stability(cx, cx.tcx.type_of(field_def.did), precedence).position_for_arg() + ty_auto_deref_stability(cx, cx.tcx.type_of(field_def.did).subst_identity(), precedence).position_for_arg() }), _ => None, }, diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index bc18e2e5ed5f..f95b8ccf067b 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -184,7 +184,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir); if let ImplItemKind::Fn(_, b) = &impl_item.kind; if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b); - if let Some(adt_def) = cx.tcx.type_of(item.owner_id).ty_adt_def(); + if let Some(adt_def) = cx.tcx.type_of(item.owner_id).subst_identity().ty_adt_def(); if let attrs = cx.tcx.hir().attrs(item.hir_id()); if !attrs.iter().any(|attr| attr.doc_str().is_some()); if let child_attrs = cx.tcx.hir().attrs(impl_item_hir); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index f8fc726d603f..1cdcccd5f146 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -211,7 +211,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { .. }) = item.kind { - let ty = cx.tcx.type_of(item.owner_id); + let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -347,7 +347,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { impls .iter() - .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) + .any(|&id| matches!(cx.tcx.type_of(id).subst_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) }); if !has_copy_impl { return; diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index 0570c2a10138..d94664daa561 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum { } if let ItemKind::Enum(..) = item.kind { - let ty = cx.tcx.type_of(item.owner_id); + let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); if adt.variants().is_empty() { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index da67888827d1..e275efaba25f 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { for var in def.variants { if let Some(anon_const) = &var.disr_expr { let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); - let mut ty = cx.tcx.type_of(def_id.to_def_id()); + let mut ty = cx.tcx.type_of(def_id.to_def_id()).subst_identity(); let constant = cx .tcx .const_eval_poly(def_id.to_def_id()) diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 3543910c3b55..ddade65c515c 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if check_inputs(cx, body.params, None, args); let callee_ty = cx.typeck_results().expr_ty_adjusted(callee); let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id) - .map_or(callee_ty, |id| cx.tcx.type_of(id)); + .map_or(callee_ty, |id| cx.tcx.type_of(id).subst_identity()); if check_sig(cx, closure_ty, call_ty); let substs = cx.typeck_results().node_substs(callee.hir_id); // This fixes some false positives that I don't entirely understand @@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if check_inputs(cx, body.params, Some(receiver), args); let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(body.value.hir_id); - let call_ty = cx.tcx.bound_type_of(method_def_id).subst(cx.tcx, substs); + let call_ty = cx.tcx.type_of(method_def_id).subst(cx.tcx, substs); if check_sig(cx, closure_ty, call_ty); then { span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| { @@ -233,7 +233,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs match assoc_item.container { ty::TraitContainer => cx.tcx.def_path_str(def_id), ty::ImplContainer => { - let ty = cx.tcx.type_of(def_id); + let ty = cx.tcx.type_of(def_id).skip_binder(); match ty.kind() { ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()), ty::Array(..) diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 29d59c26d92c..0c7aea6da8fe 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(const_id); if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl - if cx.tcx.type_of(impl_id).is_integral(); + if cx.tcx.type_of(impl_id).subst_identity().is_integral(); then { print_lint_and_sugg(cx, var_name, expr) } @@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(func_id); if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl - if cx.tcx.type_of(impl_id).is_integral(); + if cx.tcx.type_of(impl_id).subst_identity().is_integral(); then { print_lint_and_sugg(cx, var_name, expr) } diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index e9b2e31a769a..7c41699f307a 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -66,7 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { ) }) { for impl_id in impl_ids.iter().map(|id| id.expect_local()) { - match type_map.entry(cx.tcx.type_of(impl_id)) { + let impl_ty = cx.tcx.type_of(impl_id).subst_identity(); + match type_map.entry(impl_ty) { Entry::Vacant(e) => { // Store the id for the first impl block of this type. The span is retrieved lazily. e.insert(IdOrSpan::Id(impl_id)); diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index b8d4abdbb781..1c99bd2f3d02 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { return; } if let ItemKind::Enum(ref def, _) = item.kind { - let ty = cx.tcx.type_of(item.owner_id); + let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let Adt(adt, subst) = ty.kind() else { panic!("already checked whether this is an enum") }; diff --git a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs index 0aadb482acdd..d06bcdaa27f0 100644 --- a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs +++ b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs @@ -10,7 +10,7 @@ pub(crate) fn check(cx: &LateContext<'_>, pat: &Pat<'_>) { if !pat.span.from_expansion(); if let PatKind::Struct(QPath::Resolved(_, path), fields, true) = pat.kind; if let Some(def_id) = path.res.opt_def_id(); - let ty = cx.tcx.type_of(def_id); + let ty = cx.tcx.type_of(def_id).subst_identity(); if let ty::Adt(def, _) = ty.kind(); if def.is_struct() || def.is_union(); if fields.len() == def.non_enum_variant().fields.len(); diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs index 89aaad359d4a..46a20ad412ba 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs @@ -17,7 +17,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id); - if cx.tcx.type_of(impl_id).is_str(); + if cx.tcx.type_of(impl_id).subst_identity().is_str(); let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs(); if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String); then { diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index 0b3bf22743fa..7711aa78b239 100644 --- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).is_str(); + if cx.tcx.type_of(impl_id).subst_identity().is_str(); if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = arg.kind; if (2..=6).contains(&ext_literal.as_str().len()); let ext_str = ext_literal.as_str(); diff --git a/src/tools/clippy/clippy_lints/src/methods/get_first.rs b/src/tools/clippy/clippy_lints/src/methods/get_first.rs index cb17af608a3f..945bbf53bcf3 100644 --- a/src/tools/clippy/clippy_lints/src/methods/get_first.rs +++ b/src/tools/clippy/clippy_lints/src/methods/get_first.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).is_slice(); + if cx.tcx.type_of(impl_id).subst_identity().is_slice(); if let Some(_) = is_slice_of_primitives(cx, recv); if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs index 06ecbce4e70e..374eb29fc527 100644 --- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs @@ -53,7 +53,7 @@ pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir "to_vec" => cx .tcx .impl_of_method(method_def_id) - .filter(|&impl_did| cx.tcx.type_of(impl_did).is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none()) + .filter(|&impl_did| cx.tcx.type_of(impl_did).subst_identity().is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none()) .is_some(), _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs index 5b758f1e6547..b9a0ec779961 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs @@ -21,7 +21,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Option); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Option); if let ExprKind::Call(err_path, [err_arg]) = or_expr.kind; if is_res_lang_ctor(cx, path_res(cx, err_path), ResultErr); if is_ok_wrapping(cx, map_expr); diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs index 52cc1e0464bf..2b26ef014109 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs @@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id); if cx.tcx.impl_of_method(method_id) - .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id), sym::Option)) + .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id).subst_identity(), sym::Option)) || is_diag_trait_item(cx, method_id, sym::Iterator); if let hir::ExprKind::Closure(&hir::Closure{ body, .. }) = arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs index b773b3e423f4..a5beb291f326 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs @@ -9,7 +9,7 @@ use super::MAP_ERR_IGNORE; pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Result) + && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Result) && let ExprKind::Closure(&Closure { capture_clause: CaptureBy::Ref, body, diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index f1e8be7f2b87..6301b3ded20d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -3349,7 +3349,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let name = impl_item.ident.name.as_str(); let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id); + let self_ty = cx.tcx.type_of(item.owner_id).subst_identity(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind { diff --git a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs index b9593b3687d9..d0aa39d06275 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &' if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind(); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Mutex); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Mutex); then { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 82d3b830d4f3..8ddbacc3d7ad 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -173,7 +173,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) - && let substs = cx.tcx.mk_substs([GenericArg::from(typeck.expr_ty_adjusted(iter_expr))].into_iter()) + && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index 597af853dc68..c6a27cdd6fac 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -11,7 +11,7 @@ use super::NONSENSICAL_OPEN_OPTIONS; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && match_type(cx, cx.tcx.type_of(impl_id), &paths::OPEN_OPTIONS) + && match_type(cx, cx.tcx.type_of(impl_id).subst_identity(), &paths::OPEN_OPTIONS) { let mut options = Vec::new(); get_open_options(cx, recv, &mut options); diff --git a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs index 0cc28c0dcb3d..e3f2de3cd466 100644 --- a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::PathBuf); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::PathBuf); if let ExprKind::Lit(ref lit) = arg.kind; if let LitKind::Str(ref path_lit, _) = lit.node; if let pushed_path = Path::new(path_lit.as_str()); diff --git a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs index 09c8ca4cbe44..b5fd0ad8ce52 100644 --- a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs +++ b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs @@ -10,7 +10,7 @@ use super::STABLE_SORT_PRIMITIVE; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && cx.tcx.type_of(impl_id).is_slice() + && cx.tcx.type_of(impl_id).subst_identity().is_slice() && let Some(slice_type) = is_slice_of_primitives(cx, recv) { span_lint_and_then( diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs index 219a9edd6576..90ca66bd70c5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs @@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, se if let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(call_id); if cx.tcx.impl_trait_ref(impl_id).is_none(); - let self_ty = cx.tcx.type_of(impl_id); + let self_ty = cx.tcx.type_of(impl_id).subst_identity(); if self_ty.is_slice() || self_ty.is_str(); then { // Ignore empty slice and string literals when used with a literal count. diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index ed5a75b0f3ce..5201da52bbf1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -122,7 +122,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).is_slice(); + if cx.tcx.type_of(impl_id).subst_identity().is_slice(); if let ExprKind::Closure(&Closure { body, .. }) = arg.kind; if let closure_body = cx.tcx.hir().body(body); if let &[ diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index d50346c166ae..c96d69226972 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -143,7 +143,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> { if_chain! { if args.iter().all(|arg| !self.is_binding(arg)); if let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id); - let method_ty = self.cx.tcx.type_of(method_def_id); + let method_ty = self.cx.tcx.type_of(method_def_id).subst_identity(); let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder(); if matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not)); then { diff --git a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs index 02d8364cb295..b0cfc163fd08 100644 --- a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs @@ -20,7 +20,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Vec); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Vec); if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 4547ed7eafc8..e91aac41bc48 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { ExprKind::MethodCall(path, receiver, arguments, _) => { let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(e.hir_id); - let method_type = cx.tcx.bound_type_of(def_id).subst(cx.tcx, substs); + let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); check_arguments( cx, std::iter::once(receiver).chain(arguments.iter()).collect(), diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index faf9ec61ec50..653b1a8a05f6 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -98,14 +98,15 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if name == sym::new; if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id); let self_def_id = cx.tcx.hir().get_parent_item(id.into()); - let self_ty = cx.tcx.type_of(self_def_id); + let self_ty = cx.tcx.type_of(self_def_id).subst_identity(); if self_ty == return_ty(cx, id); if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default); then { if self.impling_types.is_none() { let mut impls = HirIdSet::default(); cx.tcx.for_each_impl(default_trait_id, |d| { - if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() { + let ty = cx.tcx.type_of(d).subst_identity(); + if let Some(ty_def) = ty.ty_adt_def() { if let Some(local_def_id) = ty_def.did().as_local() { impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id)); } @@ -118,7 +119,8 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // generics if_chain! { if let Some(ref impling_types) = self.impling_types; - if let Some(self_def) = cx.tcx.type_of(self_def_id).ty_adt_def(); + let self_def = cx.tcx.type_of(self_def_id).subst_identity(); + if let Some(self_def) = self_def.ty_adt_def(); if let Some(self_local_did) = self_def.did().as_local(); let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did); if impling_types.contains(&self_id); diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 07fd321d69fc..0bedab05eec6 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -313,7 +313,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // and, in that case, the definition is *not* generic. cx.tcx.normalize_erasing_regions( cx.tcx.param_env(of_trait_def_id), - cx.tcx.type_of(of_assoc_item), + cx.tcx.type_of(of_assoc_item).subst_identity(), ), )) .is_err(); diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index d88409c356e9..fc550936165e 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> = 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/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 245a02ea26e6..398329e455bf 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -11,8 +11,6 @@ use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::subst::GenericArg; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use std::iter; - declare_clippy_lint! { /// ### What it does /// Checks for redundant slicing expressions which use the full range, and @@ -136,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(iter::once(GenericArg::from(indexed_ty)))), + cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 3ce030cd721a..beca203c868d 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id); + let self_ty = cx.tcx.type_of(item.owner_id).subst_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); // Do not check trait impls diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index af0242348ac2..5e24213d07fd 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -273,7 +273,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> .non_enum_variant() .fields .iter() - .map(|f| cx.tcx.bound_type_of(f.did).subst(cx.tcx, substs)); + .map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs)); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure { raw_ptr_only: false }; }; diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 3cd35838961f..e7c54000684a 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -218,7 +218,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } else { hir_ty_to_ty(cx.tcx, hir_ty) }; - if same_type_and_consts(ty, cx.tcx.type_of(impl_id)); + if same_type_and_consts(ty, cx.tcx.type_of(impl_id).subst_identity()); then { span_lint(cx, hir_ty.span); } @@ -230,7 +230,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if !expr.span.from_expansion(); if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS); if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last(); - if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id); + if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).subst_identity(); then {} else { return; } } match expr.kind { @@ -254,7 +254,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if let PatKind::Path(QPath::Resolved(_, path)) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind; - if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id); + if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).subst_identity(); then { check_path(cx, path); } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs index 4b33d492a0e4..688a8b865f32 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs @@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol { for item in cx.tcx.module_children(def_id).iter() { if_chain! { if let Res::Def(DefKind::Const, item_def_id) = item.res; - let ty = cx.tcx.type_of(item_def_id); + let ty = cx.tcx.type_of(item_def_id).subst_identity(); if match_type(cx, ty, &paths::SYMBOL); if let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id); if let Ok(value) = value.to_u32(); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 9876a8a765cc..09f0f0d0adb6 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -39,6 +39,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { if self_ty_def.all_fields().any(|f| { cx.tcx .type_of(f.did) + .subst_identity() .walk() .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 7144363637a0..ee5e42bae0f1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -229,11 +229,11 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option read_mir_alloc_def_path( cx, cx.tcx.eval_static_initializer(def_id).ok()?.inner(), - cx.tcx.type_of(def_id), + cx.tcx.type_of(def_id).subst_identity(), ), Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? { ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => { - read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id)) + read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).subst_identity()) }, _ => None, }, diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 5c89dd3e49f4..6ff7728374f8 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -50,7 +50,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: let name = name.as_str(); let ty = match cx.tcx.impl_of_method(fn_id) { - Some(id) => cx.tcx.type_of(id), + Some(id) => cx.tcx.type_of(id).subst_identity(), None => return Lazy, }; @@ -71,7 +71,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: .variants() .iter() .flat_map(|v| v.fields.iter()) - .any(|x| matches!(cx.tcx.type_of(x.did).peel_refs().kind(), ty::Param(_))) + .any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_))) && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { PredicateKind::Clause(ty::Clause::Trait(pred)) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, _ => true, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 3b8713e2b108..b2edd1bbfef4 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -317,7 +317,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) /// Checks if a method is defined in an impl of a diagnostic item pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { - if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() { + if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { return cx.tcx.is_diagnostic_item(diag_item, adt.did()); } } @@ -812,7 +812,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< if let QPath::TypeRelative(_, method) = path { if method.ident.name == sym::new { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { - if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() { + if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { return std_types_symbols.iter().any(|&symbol| { cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string() }); diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 26b1d0197499..1a35fe05067f 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -30,7 +30,8 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) ty::Clause::RegionOutlives(_) | ty::Clause::TypeOutlives(_) | ty::Clause::Projection(_) - | ty::Clause::Trait(..), + | ty::Clause::Trait(..) + | ty::Clause::ConstArgHasType(..), ) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::ConstEvaluatable(..) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index d6af7a948a5c..2ed301fcc229 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -780,7 +780,7 @@ impl core::ops::Add for EnumValue { #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { - match tcx.type_of(id).kind() { + match tcx.type_of(id).subst_identity().kind() { ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), 2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16), @@ -903,7 +903,7 @@ pub fn variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<&'tcx Va let var_id = cx.tcx.parent(id); Some(cx.tcx.adt_def(cx.tcx.parent(var_id)).variant_with_id(var_id)) }, - Res::SelfCtor(id) => Some(cx.tcx.type_of(id).ty_adt_def().unwrap().non_enum_variant()), + Res::SelfCtor(id) => Some(cx.tcx.type_of(id).subst_identity().ty_adt_def().unwrap().non_enum_variant()), _ => None, } } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index e11ebca6ea9a..d9b39927ca4b 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -935,6 +935,7 @@ pub fn make_test_description( let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_cfi = util::CFI_SUPPORTED_TARGETS.contains(&&*config.target); let has_kcfi = util::KCFI_SUPPORTED_TARGETS.contains(&&*config.target); + let has_kasan = util::KASAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target); @@ -1010,6 +1011,7 @@ pub fn make_test_description( reason!(!has_asan && config.parse_name_directive(ln, "needs-sanitizer-address")); reason!(!has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi")); reason!(!has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi")); + reason!(!has_kasan && config.parse_name_directive(ln, "needs-sanitizer-kasan")); reason!(!has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak")); reason!(!has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory")); reason!(!has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread")); diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 67f49bb6397c..5f6a27e53663 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -11,6 +11,8 @@ mod tests; pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", "aarch64-unknown-fuchsia", "aarch64-linux-android", "aarch64-unknown-linux-gnu", @@ -19,6 +21,7 @@ pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[ "i686-linux-android", "i686-unknown-linux-gnu", "x86_64-apple-darwin", + "x86_64-apple-ios", "x86_64-unknown-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", @@ -45,6 +48,13 @@ pub const CFI_SUPPORTED_TARGETS: &[&str] = &[ pub const KCFI_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-none", "x86_64-linux-none"]; +pub const KASAN_SUPPORTED_TARGETS: &[&str] = &[ + "aarch64-unknown-none", + "riscv64gc-unknown-none-elf", + "riscv64imac-unknown-none-elf", + "x86_64-unknown-none", +]; + pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[ // FIXME: currently broken, see #88132 // "aarch64-apple-darwin", @@ -63,8 +73,11 @@ pub const MSAN_SUPPORTED_TARGETS: &[&str] = &[ pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", + "x86_64-apple-ios", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", "s390x-unknown-linux-gnu", diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index d61e17cbf9a4..ebb71b57ae39 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -363,7 +363,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx, ty::ParamEnv::reveal_all(), start_id, - tcx.mk_substs(::std::iter::once(ty::subst::GenericArg::from(main_ret_ty))), + tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap(); diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 269b441c5045..95b912d92c0c 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -907,8 +907,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { panic!("extern_statics cannot contain wildcards") }; let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id); + let def_ty = ecx.tcx.type_of(def_id).subst_identity(); let extern_decl_layout = - ecx.tcx.layout_of(ty::ParamEnv::empty().and(ecx.tcx.type_of(def_id))).unwrap(); + ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap(); if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align { throw_unsup_format!( "`extern` static `{name}` from crate `{krate}` has been declared \ diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index ef3abb9514f2..409f75631849 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/codegen/sanitizer-kasan-emits-instrumentation.rs b/tests/codegen/sanitizer-kasan-emits-instrumentation.rs new file mode 100644 index 000000000000..d6e3f2719df7 --- /dev/null +++ b/tests/codegen/sanitizer-kasan-emits-instrumentation.rs @@ -0,0 +1,47 @@ +// Verifies that `-Zsanitizer=kernel-address` emits sanitizer instrumentation. + +// compile-flags: -Zsanitizer=kernel-address +// revisions: aarch64 riscv64imac riscv64gc x86_64 +//[aarch64] compile-flags: --target aarch64-unknown-none +//[aarch64] needs-llvm-components: aarch64 +//[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf +//[riscv64imac] needs-llvm-components: riscv +//[riscv64imac] min-llvm-version: 16 +//[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf +//[riscv64gc] needs-llvm-components: riscv +//[riscv64gc] min-llvm-version: 16 +//[x86_64] compile-flags: --target x86_64-unknown-none +//[x86_64] needs-llvm-components: x86 + +#![crate_type = "rlib"] +#![feature(no_core, no_sanitize, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +impl Copy for u8 {} + +// CHECK-LABEL: ; sanitizer_kasan_emits_instrumentation::unsanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK-NOT: sanitize_address +// CHECK: start: +// CHECK-NOT: call void @__asan_report_load +// CHECK: } +#[no_sanitize(address)] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK-LABEL: ; sanitizer_kasan_emits_instrumentation::sanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK: sanitize_address +// CHECK: start: +// CHECK: call void @__asan_report_load +// CHECK: } +pub fn sanitized(b: &mut u8) -> u8 { + *b +} diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff index 5ebaacd4ba91..1f5c533815d7 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff @@ -86,8 +86,6 @@ bb6: { _10 = ((_7 as Some).0: usize); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 - StorageLive(_11); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46 - _11 = &mut (*_1); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46 StorageLive(_13); // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 _13 = _6; // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 StorageLive(_14); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 @@ -95,7 +93,7 @@ _15 = _10 as u32 (IntToInt); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75 _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79 - _0 = float_to_exponential_common_exact::(move _11, _2, move _13, move _14, _3) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87 + _0 = float_to_exponential_common_exact::(_1, _2, move _13, move _14, _3) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87 // mir::Constant // + span: $DIR/funky_arms.rs:26:9: 26:42 // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::}, val: Value() } @@ -104,16 +102,13 @@ bb7: { StorageDead(_14); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 StorageDead(_13); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 - StorageDead(_11); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 } bb8: { - StorageLive(_18); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49 - _18 = &mut (*_1); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49 StorageLive(_20); // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 _20 = _6; // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 - _0 = float_to_exponential_common_shortest::(move _18, _2, move _20, _3) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68 + _0 = float_to_exponential_common_shortest::(_1, _2, move _20, _3) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68 // mir::Constant // + span: $DIR/funky_arms.rs:28:9: 28:45 // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_shortest::}, val: Value() } @@ -121,7 +116,6 @@ bb9: { StorageDead(_20); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 - StorageDead(_18); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index dc0c32350437..6441a9668de6 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -8,7 +8,6 @@ fn a(_1: &mut [T]) -> &mut [T] { let mut _4: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:3:7: 3:15 debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } bb0: { @@ -16,10 +15,7 @@ fn a(_1: &mut [T]) -> &mut [T] { StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _3 = _4; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index b6aff30149fa..21570a88a6be 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -8,10 +8,8 @@ fn b(_1: &mut Box) -> &mut T { let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:7: 8:15 debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _7: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _8: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _6: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { @@ -19,15 +17,9 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _8 = (((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _6 = (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _3 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs new file mode 100644 index 000000000000..f6c23a1365f4 --- /dev/null +++ b/tests/rustdoc/reexport-attr-merge.rs @@ -0,0 +1,33 @@ +// Regression test for . +// 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 77ea8ef05209..d1b9d7a40b47 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 062b3768858d..c74186285f9f 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 0580e53c510a..ff795b507f21 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: 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 48787b0c352c..0911685b4280 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 7582082ac72a..061f510144bd 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 c2e6e001b179..a86cbbf1802e 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 8cf48060a635..c645dd381792 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 similarity index 100% rename from tests/ui/issues/issue-38821.rs rename to tests/ui/associated-types/issue-38821.rs diff --git a/tests/ui/issues/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr similarity index 100% rename from tests/ui/issues/issue-38821.stderr rename to tests/ui/associated-types/issue-38821.stderr diff --git a/tests/ui/issues/issue-83924.fixed b/tests/ui/borrowck/issue-83924.fixed similarity index 100% rename from tests/ui/issues/issue-83924.fixed rename to tests/ui/borrowck/issue-83924.fixed diff --git a/tests/ui/issues/issue-83924.rs b/tests/ui/borrowck/issue-83924.rs similarity index 100% rename from tests/ui/issues/issue-83924.rs rename to tests/ui/borrowck/issue-83924.rs diff --git a/tests/ui/issues/issue-83924.stderr b/tests/ui/borrowck/issue-83924.stderr similarity index 100% rename from tests/ui/issues/issue-83924.stderr rename to tests/ui/borrowck/issue-83924.stderr diff --git a/tests/ui/bounds-lifetime.stderr b/tests/ui/bounds-lifetime.stderr index a0395ed49045..f0bfe784cccc 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 #108185 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 Fn(); | ^ + | + = note: see issue #108185 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/const-bound.rs b/tests/ui/closures/binder/const-bound.rs new file mode 100644 index 000000000000..b1c79db13751 --- /dev/null +++ b/tests/ui/closures/binder/const-bound.rs @@ -0,0 +1,7 @@ +#![feature(closure_lifetime_binder, non_lifetime_binders)] +//~^ WARN is incomplete and may not be safe to use + +fn main() { + for || -> () {}; + //~^ ERROR late-bound const parameter not allowed on closures +} diff --git a/tests/ui/closures/binder/const-bound.stderr b/tests/ui/closures/binder/const-bound.stderr new file mode 100644 index 000000000000..c016465c101c --- /dev/null +++ b/tests/ui/closures/binder/const-bound.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/const-bound.rs:1:37 + | +LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: late-bound const parameter not allowed on closures + --> $DIR/const-bound.rs:5:9 + | +LL | for || -> () {}; + | ^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/closures/binder/disallow-const.stderr b/tests/ui/closures/binder/disallow-const.stderr index 3c3b43d8cf34..59f299315f85 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 || -> () {}; | ^ + | + = note: see issue #108185 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 51b6773edea9..3370e21bd711 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 || -> () {}; | ^ + | + = note: see issue #108185 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/type-bound-2.rs b/tests/ui/closures/binder/type-bound-2.rs new file mode 100644 index 000000000000..f4edcdaa9ca9 --- /dev/null +++ b/tests/ui/closures/binder/type-bound-2.rs @@ -0,0 +1,7 @@ +#![feature(closure_lifetime_binder, non_lifetime_binders)] +//~^ WARN is incomplete and may not be safe to use + +fn main() { + for || -> () {}; + //~^ ERROR late-bound type parameter not allowed on closures +} diff --git a/tests/ui/closures/binder/type-bound-2.stderr b/tests/ui/closures/binder/type-bound-2.stderr new file mode 100644 index 000000000000..14b2dbf03957 --- /dev/null +++ b/tests/ui/closures/binder/type-bound-2.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/type-bound-2.rs:1:37 + | +LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: late-bound type parameter not allowed on closures + --> $DIR/type-bound-2.rs:5:9 + | +LL | for || -> () {}; + | ^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/closures/binder/type-bound.rs b/tests/ui/closures/binder/type-bound.rs new file mode 100644 index 000000000000..59a3353f4965 --- /dev/null +++ b/tests/ui/closures/binder/type-bound.rs @@ -0,0 +1,7 @@ +#![feature(closure_lifetime_binder, non_lifetime_binders)] +//~^ WARN is incomplete and may not be safe to use + +fn main() { + for || -> T {}; + //~^ ERROR late-bound type parameter not allowed on closures +} diff --git a/tests/ui/closures/binder/type-bound.stderr b/tests/ui/closures/binder/type-bound.stderr new file mode 100644 index 000000000000..ef00a2dffcea --- /dev/null +++ b/tests/ui/closures/binder/type-bound.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/type-bound.rs:1:37 + | +LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: late-bound type parameter not allowed on closures + --> $DIR/type-bound.rs:5:9 + | +LL | for || -> T {}; + | ^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr index 4d6560e96e51..f733c09c22e6 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 #108185 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 #108185 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 #108185 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/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index cff02b0d445c..257a9e31e14b 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -1,3 +1,11 @@ +error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17>::value` in constants + --> $DIR/nested-type.rs:15:5 + | +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + error: `[u8; { struct Foo; @@ -24,5 +32,6 @@ LL | | }]>; = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/const-generics/nested-type.rs b/tests/ui/const-generics/nested-type.rs index 742340f430e2..5240f5c3b0b6 100644 --- a/tests/ui/const-generics/nested-type.rs +++ b/tests/ui/const-generics/nested-type.rs @@ -13,7 +13,7 @@ struct Foo::value() - //[full]~^ ERROR cannot call non-const fn + //~^ ERROR cannot call non-const fn }]>; fn main() {} diff --git a/tests/ui/issues/issue-33903.rs b/tests/ui/consts/issue-33903.rs similarity index 100% rename from tests/ui/issues/issue-33903.rs rename to tests/ui/consts/issue-33903.rs diff --git a/tests/ui/issues/issue-54582.rs b/tests/ui/consts/issue-54582.rs similarity index 100% rename from tests/ui/issues/issue-54582.rs rename to tests/ui/consts/issue-54582.rs diff --git a/tests/ui/issues/issue-2735-2.rs b/tests/ui/drop/issue-2735-2.rs similarity index 100% rename from tests/ui/issues/issue-2735-2.rs rename to 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 similarity index 100% rename from tests/ui/issues/issue-2735-3.rs rename to tests/ui/drop/issue-2735-3.rs diff --git a/tests/ui/issues/issue-2735.rs b/tests/ui/drop/issue-2735.rs similarity index 100% rename from tests/ui/issues/issue-2735.rs rename to tests/ui/drop/issue-2735.rs diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 163737895fea..9b0cf069824a 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 000000000000..221e9133fcc6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-non_lifetime_binders.rs @@ -0,0 +1,4 @@ +fn foo() where for 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 000000000000..01c8ee30c5f5 --- /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:, {} + | ^ + | + = note: see issue #108185 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 similarity index 100% rename from tests/ui/issues/issue-75307.rs rename to tests/ui/fmt/issue-75307.rs diff --git a/tests/ui/issues/issue-75307.stderr b/tests/ui/fmt/issue-75307.stderr similarity index 100% rename from tests/ui/issues/issue-75307.stderr rename to 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 f31aa5546347..765ea9f78540 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: Copy {} | ^ + | + = note: see issue #108185 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 [(); C]: Copy {} | ^ + | + = note: see issue #108185 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 similarity index 100% rename from tests/ui/issues/issue-39292.rs rename to 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 76645645464e..6db29bc61b12 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: 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 d3d670aa92ae..abf3543ddb9f 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 881a6e538ee4..608d2c7aff93 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 bb45fa083381..e544e4244034 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/lexer/issue-108019-bad-emoji-recovery.rs b/tests/ui/lexer/issue-108019-bad-emoji-recovery.rs new file mode 100644 index 000000000000..f0f862245601 --- /dev/null +++ b/tests/ui/lexer/issue-108019-bad-emoji-recovery.rs @@ -0,0 +1,45 @@ +#![allow(unused_labels)] + +// FIXME(#108019): outdated Unicode table +// fn foo() { +// '🥺 loop { +// break +// } +// } + +fn bar() { + '🐱 loop { + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR lifetimes or labels cannot contain emojis + break + } +} + +fn qux() { + 'a🐱 loop { + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR lifetimes or labels cannot contain emojis + break + } +} + +fn quux() { + '1🐱 loop { + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR lifetimes or labels cannot start with a number + break + } +} + +fn x<'🐱>() -> &'🐱 () { + //~^ ERROR lifetimes or labels cannot contain emojis + //~| ERROR lifetimes or labels cannot contain emojis + &() +} + +fn y() { + 'a🐱: loop {} + //~^ ERROR lifetimes or labels cannot contain emojis +} + +fn main() {} diff --git a/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr b/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr new file mode 100644 index 000000000000..be77ffdea349 --- /dev/null +++ b/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr @@ -0,0 +1,86 @@ +error: labeled expression must be followed by `:` + --> $DIR/issue-108019-bad-emoji-recovery.rs:11:5 + | +LL | '🐱 loop { + | ^--- help: add `:` after the label + | | + | _____the label + | | +LL | | +LL | | +LL | | break +LL | | } + | |_____^ + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: labeled expression must be followed by `:` + --> $DIR/issue-108019-bad-emoji-recovery.rs:19:5 + | +LL | 'a🐱 loop { + | ^---- help: add `:` after the label + | | + | _____the label + | | +LL | | +LL | | +LL | | break +LL | | } + | |_____^ + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: labeled expression must be followed by `:` + --> $DIR/issue-108019-bad-emoji-recovery.rs:27:5 + | +LL | '1🐱 loop { + | ^---- help: add `:` after the label + | | + | _____the label + | | +LL | | +LL | | +LL | | break +LL | | } + | |_____^ + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: lifetimes or labels cannot contain emojis + --> $DIR/issue-108019-bad-emoji-recovery.rs:11:5 + | +LL | '🐱 loop { + | ^^^ + +error: lifetimes or labels cannot contain emojis + --> $DIR/issue-108019-bad-emoji-recovery.rs:19:5 + | +LL | 'a🐱 loop { + | ^^^^ + +error: lifetimes or labels cannot start with a number + --> $DIR/issue-108019-bad-emoji-recovery.rs:27:5 + | +LL | '1🐱 loop { + | ^^^^ + +error: lifetimes or labels cannot contain emojis + --> $DIR/issue-108019-bad-emoji-recovery.rs:34:6 + | +LL | fn x<'🐱>() -> &'🐱 () { + | ^^^ + +error: lifetimes or labels cannot contain emojis + --> $DIR/issue-108019-bad-emoji-recovery.rs:34:16 + | +LL | fn x<'🐱>() -> &'🐱 () { + | ^^^ + +error: lifetimes or labels cannot contain emojis + --> $DIR/issue-108019-bad-emoji-recovery.rs:41:5 + | +LL | 'a🐱: loop {} + | ^^^^ + +error: aborting due to 9 previous errors + diff --git a/tests/ui/lint/issue-108155.rs b/tests/ui/lint/issue-108155.rs new file mode 100644 index 000000000000..4ae0cbd92ff1 --- /dev/null +++ b/tests/ui/lint/issue-108155.rs @@ -0,0 +1,15 @@ +// check-pass +// check that `deref_into_dyn_supertrait` doesn't cause ICE by eagerly converting +// a cancelled lint + +#![allow(deref_into_dyn_supertrait)] + +trait Trait {} +impl std::ops::Deref for dyn Trait + Send + Sync { + type Target = dyn Trait; + fn deref(&self) -> &Self::Target { + self + } +} + +fn main() {} diff --git a/tests/ui/issues/issue-50576.rs b/tests/ui/loops/issue-50576.rs similarity index 100% rename from tests/ui/issues/issue-50576.rs rename to tests/ui/loops/issue-50576.rs diff --git a/tests/ui/issues/issue-50576.stderr b/tests/ui/loops/issue-50576.stderr similarity index 100% rename from tests/ui/issues/issue-50576.stderr rename to 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 81269b73b9a7..0f37e8f09a96 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 3a895acbdb5d..cd483e7ad2c6 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 similarity index 100% rename from tests/ui/issues/issue-22536-copy-mustnt-zero.rs rename to 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 similarity index 100% rename from tests/ui/issues/issue-27583.rs rename to tests/ui/nll/issue-27583.rs diff --git a/tests/ui/issues/issue-48179.rs b/tests/ui/nll/issue-48179.rs similarity index 100% rename from tests/ui/issues/issue-48179.rs rename to tests/ui/nll/issue-48179.rs diff --git a/tests/ui/issues/issue-75777.rs b/tests/ui/nll/issue-75777.rs similarity index 100% rename from tests/ui/issues/issue-75777.rs rename to tests/ui/nll/issue-75777.rs diff --git a/tests/ui/issues/issue-75777.stderr b/tests/ui/nll/issue-75777.stderr similarity index 100% rename from tests/ui/issues/issue-75777.stderr rename to tests/ui/nll/issue-75777.stderr diff --git a/tests/ui/parser/numeric-lifetime.rs b/tests/ui/parser/numeric-lifetime.rs index 2d82354c62cc..a082a8a44df2 100644 --- a/tests/ui/parser/numeric-lifetime.rs +++ b/tests/ui/parser/numeric-lifetime.rs @@ -1,6 +1,6 @@ struct S<'1> { s: &'1 usize } -//~^ ERROR lifetimes cannot start with a number -//~| ERROR lifetimes cannot start with a number +//~^ ERROR lifetimes or labels cannot start with a number +//~| ERROR lifetimes or labels cannot start with a number fn main() { // verify that the parse error doesn't stop type checking let x: usize = ""; diff --git a/tests/ui/parser/numeric-lifetime.stderr b/tests/ui/parser/numeric-lifetime.stderr index 7c1bcb726317..66e35dca9231 100644 --- a/tests/ui/parser/numeric-lifetime.stderr +++ b/tests/ui/parser/numeric-lifetime.stderr @@ -6,13 +6,13 @@ LL | let x: usize = ""; | | | expected due to this -error: lifetimes cannot start with a number +error: lifetimes or labels cannot start with a number --> $DIR/numeric-lifetime.rs:1:10 | LL | struct S<'1> { s: &'1 usize } | ^^ -error: lifetimes cannot start with a number +error: lifetimes or labels cannot start with a number --> $DIR/numeric-lifetime.rs:1:20 | LL | struct S<'1> { s: &'1 usize } diff --git a/tests/ui/parser/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover-fn-ptr-with-generics.stderr index 1da9c18571b9..069fcffe9a0d 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(); | ^ 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; | ^ 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 similarity index 100% rename from tests/ui/issues/issue-40003.rs rename to tests/ui/recursion_limit/issue-40003.rs diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs new file mode 100644 index 000000000000..2acfde4be46d --- /dev/null +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -0,0 +1,52 @@ +// build-pass +// revisions: avr msp430 +// +// [avr] needs-llvm-components: avr +// [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib +// [msp430] needs-llvm-components: msp430 +// [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +#![feature(no_core, lang_items, intrinsics, staged_api)] +#![no_core] +#![crate_type = "lib"] +#![stable(feature = "", since = "")] +#![allow(dead_code)] + +// Test that the repr(C) attribute doesn't break compilation +// Previous bad assumption was that 32-bit enum default width is fine on msp430, avr +// But the width of the C int on these platforms is 16 bits, and C enums <= C int range +// so we want no more than that, usually. This resulted in errors like +// "layout decided on a larger discriminant type (I32) than typeck (I16)" +#[repr(C)] +enum Foo { + Bar, +} + +extern "rust-intrinsic" { + #[stable(feature = "", since = "")] + #[rustc_const_stable(feature = "", since = "")] + #[rustc_safe_intrinsic] + fn size_of() -> usize; +} + +#[lang="sized"] +trait Sized {} +#[lang="copy"] +trait Copy {} + +const EXPECTED: usize = 2; +const ACTUAL: usize = size_of::(); +// Validate that the size is indeed 16 bits, to match this C static_assert: +/** +```c +#include +enum foo { + BAR +}; +int main(void) +{ + /* passes on msp430-elf-gcc */ + static_assert(sizeof(enum foo) == 2); +} +``` +*/ +const _: [(); EXPECTED] = [(); ACTUAL]; diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index 964302e924c8..f803f9da2af1 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/sanitize/cfg-kasan.rs b/tests/ui/sanitize/cfg-kasan.rs new file mode 100644 index 000000000000..d721011f3ee5 --- /dev/null +++ b/tests/ui/sanitize/cfg-kasan.rs @@ -0,0 +1,28 @@ +// Verifies that when compiling with -Zsanitizer=kernel-address, +// the `#[cfg(sanitize = "address")]` attribute is configured. + +// check-pass +// compile-flags: -Zsanitizer=kernel-address --cfg kernel_address +// revisions: aarch64 riscv64imac riscv64gc x86_64 +//[aarch64] compile-flags: --target aarch64-unknown-none +//[aarch64] needs-llvm-components: aarch64 +//[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf +//[riscv64imac] needs-llvm-components: riscv +//[riscv64imac] min-llvm-version: 16 +//[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf +//[riscv64gc] needs-llvm-components: riscv +//[riscv64gc] min-llvm-version: 16 +//[x86_64] compile-flags: --target x86_64-unknown-none +//[x86_64] needs-llvm-components: x86 + +#![crate_type = "rlib"] +#![feature(cfg_sanitize, no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +const _: fn() -> () = main; + +#[cfg(all(sanitize = "address", kernel_address))] +fn main() {} diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index 15179954adcd..f0dea66f6128 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, 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 e97363638160..510b99bb5af7 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 000000000000..d254c0ae3ef9 --- /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 000000000000..39f974f962c2 --- /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/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs new file mode 100644 index 000000000000..0b1f9ab57c98 --- /dev/null +++ b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs @@ -0,0 +1,15 @@ +// Regression test for #108132: do not ICE upon unmet trait alias constraint in generic impl + +#![feature(trait_alias)] + +trait IteratorAlias = Iterator; + +struct Foo(I); + +impl Foo { + fn f() {} +} + +fn main() { + Foo::<()>::f() //~ trait bounds were not satisfied +} diff --git a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr new file mode 100644 index 000000000000..f1b259d5a652 --- /dev/null +++ b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr @@ -0,0 +1,25 @@ +error[E0599]: the function or associated item `f` exists for struct `Foo<()>`, but its trait bounds were not satisfied + --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:14:16 + | +LL | struct Foo(I); + | ------------- function or associated item `f` not found for this struct +... +LL | Foo::<()>::f() + | ^ function or associated item cannot be called on `Foo<()>` due to unsatisfied trait bounds + | +note: trait bound `(): Iterator` was not satisfied + --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:5:23 + | +LL | trait IteratorAlias = Iterator; + | ------------- ^^^^^^^^ unsatisfied trait bound introduced here +note: trait bound `(): IteratorAlias` was not satisfied + --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:9:9 + | +LL | impl Foo { + | ^^^^^^^^^^^^^ ------ + | | + | unsatisfied trait bound introduced here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. 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 000000000000..a797aae65dba --- /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` where clause. + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Trait {} + +impl Trait for T {} + +fn foo() +where + for 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 000000000000..0fd16c5d0ee0 --- /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 #108185 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 000000000000..460f68907e88 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/fail.rs @@ -0,0 +1,23 @@ +// Error reporting for where `for T: Trait` doesn't hold + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Trait {} + +fn fail() +where + for T: Trait, +{} + +fn auto_trait() +where + for 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 000000000000..c3f4fd6a88e4 --- /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 #108185 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: 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: 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 000000000000..8fb7dd27605f --- /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 {} + +fn foo() -> &'static dyn for Test { + //~^ 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 000000000000..95656f99976f --- /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 #108185 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 Test { + | ^ + +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 000000000000..0aaff52b6d8c --- /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 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 000000000000..3b17f7697b2b --- /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 #108185 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 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 75dfe716395a..7143c959478b 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, Vec)`, found `Vec` --> $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, Vec) */); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - groups.push(new_group, vec![process]); +LL + groups.push(/* (Vec, Vec) */); + | 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 a2686ab9440e..d8569ebf6b6e 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 ba8d15d0b731..429501c2762f 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 similarity index 100% rename from tests/ui/issues/issue-53712.rs rename to tests/ui/typeck/issue-53712.rs diff --git a/tests/ui/issues/issue-53712.stderr b/tests/ui/typeck/issue-53712.stderr similarity index 100% rename from tests/ui/issues/issue-53712.stderr rename to tests/ui/typeck/issue-53712.stderr diff --git a/tests/ui/issues/issue-7813.rs b/tests/ui/typeck/issue-7813.rs similarity index 100% rename from tests/ui/issues/issue-7813.rs rename to tests/ui/typeck/issue-7813.rs diff --git a/tests/ui/issues/issue-7813.stderr b/tests/ui/typeck/issue-7813.stderr similarity index 100% rename from tests/ui/issues/issue-7813.stderr rename to 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 b734bcd4eb04..72ddebab486c 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) {} | ^ ----------- -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 fbced928a8a9..57cbd1d2005c 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 883bc8720e2b..7a26457ab04c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -538,6 +538,7 @@ diagnostics = [ "@TaKO8Ki", ] parser = [ + "@compiler-errors", "@davidtwco", "@nnethercote", "@petrochenkov", @@ -567,6 +568,7 @@ borrowck = [ "@pnkfelix", ] ast_lowering = [ + "@compiler-errors", "@spastorino", ] fallback = [ @@ -630,7 +632,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", "@compiler-errors"] "/src/tools/linkchecker" = ["@ehuss"] "/src/tools/rust-installer" = ["bootstrap"] "/src/tools/rustbook" = ["@ehuss"]