diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 4d19d89b3ce24..da59f9f9ebd5d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -20,7 +20,7 @@ use rustc_middle::bug; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ - self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory, + self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, VarDebugInfoContents, @@ -30,13 +30,13 @@ use rustc_middle::ty::{ self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast, suggest_constraining_type_params, }; -use rustc_middle::util::CallKind; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::DesugaringKind; use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::FindExprBySpan; +use rustc_trait_selection::error_reporting::traits::call_kind::CallKind; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; @@ -46,7 +46,7 @@ use super::explain_borrow::{BorrowExplanation, LaterUseKind}; use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans}; use crate::borrow_set::{BorrowData, TwoPhaseActivation}; use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead; -use crate::diagnostics::{CapturedMessageOpt, Instance, find_all_local_uses}; +use crate::diagnostics::{CapturedMessageOpt, call_kind, find_all_local_uses}; use crate::prefixes::IsPrefixOf; use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors}; @@ -305,7 +305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } if let UseSpans::FnSelfUse { - kind: CallKind::DerefCoercion { deref_target, deref_target_ty, .. }, + kind: CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. }, .. } = use_spans { @@ -315,8 +315,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { )); // Check first whether the source is accessible (issue #87060) - if self.infcx.tcx.sess.source_map().is_span_accessible(deref_target) { - err.span_note(deref_target, "deref defined here"); + if let Some(deref_target_span) = deref_target_span + && self.infcx.tcx.sess.source_map().is_span_accessible(deref_target_span) + { + err.span_note(deref_target_span, "deref defined here"); } } @@ -3765,38 +3767,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) { let tcx = self.infcx.tcx; - if let ( - Some(Terminator { - kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. }, - .. - }), - Some((method_did, method_args)), - ) = ( - &self.body[loan.reserve_location.block].terminator, - rustc_middle::util::find_self_call( + if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) = + &self.body[loan.reserve_location.block].terminator + && let Some((method_did, method_args)) = rustc_middle::util::find_self_call( tcx, self.body, loan.assigned_place.local, loan.reserve_location.block, - ), - ) { - if tcx.is_diagnostic_item(sym::deref_method, method_did) { - let deref_target = - tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::try_resolve( - tcx, - self.infcx.typing_env(self.infcx.param_env), - deref_target, - method_args, - ) - .transpose() - }); - if let Some(Ok(instance)) = deref_target { - let deref_target_ty = - instance.ty(tcx, self.infcx.typing_env(self.infcx.param_env)); - err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`")); - err.span_note(tcx.def_span(instance.def_id()), "deref defined here"); - } + ) + && let CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. } = call_kind( + self.infcx.tcx, + self.infcx.typing_env(self.infcx.param_env), + method_did, + method_args, + *fn_span, + call_source.from_hir_call(), + Some(self.infcx.tcx.fn_arg_names(method_did)[0]), + ) + { + err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`")); + if let Some(deref_target_span) = deref_target_span { + err.span_note(deref_target_span, "deref defined here"); } } } diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a52dc447d7685..5c0c1d0eb86af 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -16,9 +16,9 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; -use rustc_middle::util::CallKind; use rustc_span::{DesugaringKind, Span, kw, sym}; use rustc_trait_selection::error_reporting::traits::FindExprBySpan; +use rustc_trait_selection::error_reporting::traits::call_kind::CallKind; use tracing::{debug, instrument}; use super::{RegionName, UseSpans, find_use}; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index d9d9ea75994f1..bd6f77156ca99 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -20,13 +20,13 @@ use rustc_middle::mir::{ StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::print::Print; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; -use rustc_middle::util::{CallDesugaringKind, call_kind}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; +use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{ FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions, @@ -63,7 +63,7 @@ pub(crate) use mutability_errors::AccessKind; pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder; pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; pub(crate) use region_name::{RegionName, RegionNameSource}; -pub(crate) use rustc_middle::util::CallKind; +pub(crate) use rustc_trait_selection::error_reporting::traits::call_kind::CallKind; pub(super) struct DescribePlaceOpt { including_downcast: bool, diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 08b774f8d6ec0..78c759bbe8c03 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use std::ffi::{CStr, CString}; use std::fs::File; -use std::mem::ManuallyDrop; use std::path::Path; use std::sync::Arc; use std::{io, iter, slice}; @@ -9,7 +8,7 @@ use std::{io, iter, slice}; use object::read::archive::ArchiveFile; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; use rustc_codegen_ssa::back::symbol_export; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, TargetMachineFactoryConfig}; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::fx::FxHashMap; @@ -706,18 +705,15 @@ pub(crate) unsafe fn optimize_thin_module( let dcx = dcx.handle(); let module_name = &thin_module.shared.module_names[thin_module.idx]; - let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap()); - let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(dcx, e))?; // Right now the implementation we've got only works over serialized // modules, so we create a fresh new LLVM context and parse the module // into that context. One day, however, we may do this for upstream // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. - let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) }; - let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _; + let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx)?; let mut module = ModuleCodegen { - module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }, + module_llvm, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 6707ebe7d1c84..7d103055a7c43 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -14,9 +14,11 @@ use rustc_middle::ty::{ self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, suggest_constraining_type_param, }; -use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind}; use rustc_session::parse::add_feature_diagnostics; use rustc_span::{BytePos, Pos, Span, Symbol, sym}; +use rustc_trait_selection::error_reporting::traits::call_kind::{ + CallDesugaringKind, CallKind, call_kind, +}; use rustc_trait_selection::traits::SelectionContext; use tracing::debug; @@ -324,10 +326,12 @@ fn build_error_for_const_call<'tcx>( note_trait_if_possible(&mut err, self_ty, trait_id); err } - CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => { + CallKind::DerefCoercion { deref_target_span, deref_target_ty, self_ty } => { // Check first whether the source is accessible (issue #87060) - let target = if tcx.sess.source_map().is_span_accessible(deref_target) { - Some(deref_target) + let target = if let Some(deref_target_span) = deref_target_span + && tcx.sess.source_map().is_span_accessible(deref_target_span) + { + Some(deref_target_span) } else { None }; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 6db512ace1b4d..0b034a2ae1075 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -68,6 +68,16 @@ impl UnstableFeatures { /// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly /// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work. pub fn from_environment(krate: Option<&str>) -> Self { + Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP")) + } + + /// Avoid unsafe `std::env::set_var()` by allowing tests to inject + /// `std::env::var("RUSTC_BOOTSTRAP")` with the `env_var_rustc_bootstrap` + /// arg. + fn from_environment_value( + krate: Option<&str>, + env_var_rustc_bootstrap: Result, + ) -> Self { // `true` if this is a feature-staged build, i.e., on the beta or stable channel. let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0"); @@ -75,7 +85,7 @@ impl UnstableFeatures { let is_unstable_crate = |var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name)); - let bootstrap = std::env::var("RUSTC_BOOTSTRAP").ok(); + let bootstrap = env_var_rustc_bootstrap.ok(); if let Some(val) = bootstrap.as_deref() { match val { val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat, diff --git a/compiler/rustc_feature/src/tests.rs b/compiler/rustc_feature/src/tests.rs index cc0e1f3120965..a5d589171d105 100644 --- a/compiler/rustc_feature/src/tests.rs +++ b/compiler/rustc_feature/src/tests.rs @@ -2,9 +2,11 @@ use super::UnstableFeatures; #[test] fn rustc_bootstrap_parsing() { - let is_bootstrap = |env, krate| { - std::env::set_var("RUSTC_BOOTSTRAP", env); - matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat) + let is_bootstrap = |env: &str, krate: Option<&str>| { + matches!( + UnstableFeatures::from_environment_value(krate, Ok(env.to_string())), + UnstableFeatures::Cheat + ) }; assert!(is_bootstrap("1", None)); assert!(is_bootstrap("1", Some("x"))); @@ -22,9 +24,11 @@ fn rustc_bootstrap_parsing() { assert!(!is_bootstrap("0", None)); // `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed. - let is_force_stable = |krate| { - std::env::set_var("RUSTC_BOOTSTRAP", "-1"); - matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Disallow) + let is_force_stable = |krate: Option<&str>| { + matches!( + UnstableFeatures::from_environment_value(krate, Ok("-1".to_string())), + UnstableFeatures::Disallow + ) }; assert!(is_force_stable(None)); // Does not support specifying any crate. diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 49b5588e261af..e4ded2c30f539 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def::Namespace; +use rustc_hir::def::{CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::FiniteBitSet; @@ -498,7 +498,8 @@ impl<'tcx> Instance<'tcx> { /// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly, /// this is used to find the precise code that will run for a trait method invocation, - /// if known. + /// if known. This should only be used for functions and consts. If you want to + /// resolve an associated type, use [`TyCtxt::try_normalize_erasing_regions`]. /// /// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance. /// For example, in a context like this, @@ -527,6 +528,23 @@ impl<'tcx> Instance<'tcx> { def_id: DefId, args: GenericArgsRef<'tcx>, ) -> Result>, ErrorGuaranteed> { + assert_matches!( + tcx.def_kind(def_id), + DefKind::Fn + | DefKind::AssocFn + | DefKind::Const + | DefKind::AssocConst + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::Static { .. } + | DefKind::Ctor(_, CtorKind::Fn) + | DefKind::Closure + | DefKind::SyntheticCoroutineBody, + "`Instance::try_resolve` should only be used to resolve instances of \ + functions, statics, and consts; to resolve associated types, use \ + `try_normalize_erasing_regions`." + ); + // Rust code can easily create exponentially-long types using only a // polynomial recursion depth. Even with the default recursion // depth, you can easily get cases that take >2^60 steps to run, diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs index 8dafc42264485..097a868191c15 100644 --- a/compiler/rustc_middle/src/util/mod.rs +++ b/compiler/rustc_middle/src/util/mod.rs @@ -1,9 +1,7 @@ pub mod bug; -pub mod call_kind; pub mod common; pub mod find_self_call; -pub use call_kind::{CallDesugaringKind, CallKind, call_kind}; pub use find_self_call::find_self_call; #[derive(Default, Copy, Clone)] diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs similarity index 55% rename from compiler/rustc_middle/src/util/call_kind.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index 0e39533168792..1c3e570b67695 100644 --- a/compiler/rustc_middle/src/util/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -2,12 +2,14 @@ //! as well as errors when attempting to call a non-const function in a const //! context. +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, lang_items}; +use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; use rustc_span::{DesugaringKind, Ident, Span, sym}; use tracing::debug; -use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; +use crate::traits::specialization_graph; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum CallDesugaringKind { @@ -55,7 +57,7 @@ pub enum CallKind<'tcx> { DerefCoercion { /// The `Span` of the `Target` associated type /// in the `Deref` impl we are using. - deref_target: Span, + deref_target_span: Option, /// The type `T::Deref` we are dereferencing to deref_target_ty: Ty<'tcx>, self_ty: Ty<'tcx>, @@ -89,61 +91,65 @@ pub fn call_kind<'tcx>( None }; - let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did); - // Check for a 'special' use of 'self' - // an FnOnce call, an operator (e.g. `<<`), or a // deref coercion. - let kind = if let Some(trait_id) = fn_call { - Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) }) + if let Some(trait_id) = fn_call { + return CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) }; } else if let Some(trait_id) = operator { - Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) }) - } else if is_deref { - let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::try_resolve(tcx, typing_env, deref_target, method_args).transpose() - }); - if let Some(Ok(instance)) = deref_target { - let deref_target_ty = instance.ty(tcx, typing_env); - Some(CallKind::DerefCoercion { - deref_target: tcx.def_span(instance.def_id()), - deref_target_ty, - self_ty: method_args.type_at(0), - }) + return CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) }; + } else if !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did) { + let deref_target_def_id = + tcx.get_diagnostic_item(sym::deref_target).expect("deref method but no deref target"); + let deref_target_ty = tcx.normalize_erasing_regions( + typing_env, + Ty::new_projection(tcx, deref_target_def_id, method_args), + ); + let deref_target_span = if let Ok(Some(instance)) = + Instance::try_resolve(tcx, typing_env, method_did, method_args) + && let instance_parent_def_id = tcx.parent(instance.def_id()) + && matches!(tcx.def_kind(instance_parent_def_id), DefKind::Impl { .. }) + && let Ok(instance) = + specialization_graph::assoc_def(tcx, instance_parent_def_id, deref_target_def_id) + && instance.is_final() + { + Some(tcx.def_span(instance.item.def_id)) + } else { + None + }; + return CallKind::DerefCoercion { + deref_target_ty, + deref_target_span, + self_ty: method_args.type_at(0), + }; + } + + // This isn't a 'special' use of `self` + debug!(?method_did, ?fn_call_span); + let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter) + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) + { + Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0))) + } else if tcx.is_lang_item(method_did, LangItem::IteratorNext) + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) + { + Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0))) + } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) { + if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) { + Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0))) + } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) { + Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0))) } else { None } + } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput) + && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock) + { + Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0))) + } else if fn_call_span.is_desugaring(DesugaringKind::Await) { + Some((CallDesugaringKind::Await, method_args.type_at(0))) } else { None }; - - kind.unwrap_or_else(|| { - // This isn't a 'special' use of `self` - debug!(?method_did, ?fn_call_span); - let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter) - && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) - { - Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0))) - } else if tcx.is_lang_item(method_did, LangItem::IteratorNext) - && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) - { - Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0))) - } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) { - if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) { - Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0))) - } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) { - Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0))) - } else { - None - } - } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput) - && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock) - { - Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0))) - } else if fn_call_span.is_desugaring(DesugaringKind::Await) { - Some((CallDesugaringKind::Await, method_args.type_at(0))) - } else { - None - }; - CallKind::Normal { self_arg, desugaring, method_did, method_args } - }) + CallKind::Normal { self_arg, desugaring, method_did, method_args } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index b108a9352a53d..cd4f77bb4cfed 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -1,4 +1,5 @@ pub mod ambiguity; +pub mod call_kind; mod fulfillment_errors; pub mod on_unimplemented; mod overflow; diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 35e920ab34476..7fd08a97f1f20 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -298,7 +298,7 @@ where } // Detect scheme on Redox -fn has_redox_scheme(s: &[u8]) -> bool { +pub(crate) fn has_redox_scheme(s: &[u8]) -> bool { cfg!(target_os = "redox") && s.contains(&b':') } @@ -2155,7 +2155,7 @@ impl Path { unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. - fn as_u8_slice(&self) -> &[u8] { + pub(crate) fn as_u8_slice(&self) -> &[u8] { self.inner.as_encoded_bytes() } @@ -2323,14 +2323,7 @@ impl Path { #[must_use] #[allow(deprecated)] pub fn is_absolute(&self) -> bool { - if cfg!(target_os = "redox") { - // FIXME: Allow Redox prefixes - self.has_root() || has_redox_scheme(self.as_u8_slice()) - } else { - self.has_root() - && (cfg!(any(unix, target_os = "hermit", target_os = "wasi")) - || self.prefix().is_some()) - } + sys::path::is_absolute(self) } /// Returns `true` if the `Path` is relative, i.e., not absolute. @@ -2353,7 +2346,7 @@ impl Path { !self.is_absolute() } - fn prefix(&self) -> Option> { + pub(crate) fn prefix(&self) -> Option> { self.components().prefix } diff --git a/library/std/src/sys/path/sgx.rs b/library/std/src/sys/path/sgx.rs index c805c15e70245..32c7752f605d9 100644 --- a/library/std/src/sys/path/sgx.rs +++ b/library/std/src/sys/path/sgx.rs @@ -23,3 +23,7 @@ pub const MAIN_SEP: char = '/'; pub(crate) fn absolute(_path: &Path) -> io::Result { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs index 2a7c025c3c46a..361e99964f18c 100644 --- a/library/std/src/sys/path/unix.rs +++ b/library/std/src/sys/path/unix.rs @@ -60,3 +60,14 @@ pub(crate) fn absolute(path: &Path) -> io::Result { Ok(normalized) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + if cfg!(target_os = "redox") { + // FIXME: Allow Redox prefixes + path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice()) + } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) { + path.has_root() + } else { + path.has_root() && path.prefix().is_some() + } +} diff --git a/library/std/src/sys/path/unsupported_backslash.rs b/library/std/src/sys/path/unsupported_backslash.rs index 855f443678c6c..30b06c132c98d 100644 --- a/library/std/src/sys/path/unsupported_backslash.rs +++ b/library/std/src/sys/path/unsupported_backslash.rs @@ -24,3 +24,7 @@ pub const MAIN_SEP: char = '\\'; pub(crate) fn absolute(_path: &Path) -> io::Result { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index de042fa3f82ab..1c53472191699 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -346,3 +346,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result { os2path, ) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs index 2c0f25fc6ff93..2d6df816bb1ec 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -11,7 +11,7 @@ impl Foo { //~^ ERROR invalid generic `self` parameter type //~| ERROR destructor of `R` cannot be evaluated at compile-time self.0 - //~^ ERROR cannot call conditionally-const method `::deref` in constant function + //~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index 90b63249eca1a..e6319d5a2c9c4 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -1,9 +1,10 @@ -error[E0658]: cannot call conditionally-const method `::deref` in constant functions +error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 | LL | self.0 | ^^^^^^ | + = note: attempting to deref into `Foo` = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #67792 for more information = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable