diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index cd86172e9476f..1b04577adc15b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -222,7 +222,7 @@ pub(crate) fn parse_name_value( } }; - match cx.sess.psess.check_config.expecteds.get(&name) { + match cx.sess.check_config.expecteds.get(&name) { Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx .emit_lint_with_sess( UNEXPECTED_CFGS, @@ -232,7 +232,7 @@ pub(crate) fn parse_name_value( }, span, ), - None if cx.sess.psess.check_config.exhaustive_names => cx.emit_lint_with_sess( + None if cx.sess.check_config.exhaustive_names => cx.emit_lint_with_sess( UNEXPECTED_CFGS, move |dcx, level, sess| { check_cfg::unexpected_cfg_name(sess, (name, name_span), value).into_diag(dcx, level) @@ -280,7 +280,7 @@ pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResu } } CfgEntry::NameValue { name, value, span } => { - if sess.psess.config.contains(&(*name, *value)) { + if sess.config.contains(&(*name, *value)) { EvalConfigResult::True } else { EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } @@ -294,7 +294,7 @@ pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResu }; }; // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details - let min_version_ok = if sess.psess.assume_incomplete_release { + let min_version_ok = if sess.opts.unstable_opts.assume_incomplete_release { RustcVersion::current_overridable() > *min_version } else { RustcVersion::current_overridable() >= *min_version diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs index d6347c457b2b5..33db99c6bc520 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs @@ -25,9 +25,8 @@ fn sort_and_truncate_possibilities( } else { match filter_well_known_names { FilterWellKnownNames::Yes => { - possibilities.retain(|cfg_name| { - !sess.psess.check_config.well_known_names.contains(cfg_name) - }); + possibilities + .retain(|cfg_name| !sess.check_config.well_known_names.contains(cfg_name)); } FilterWellKnownNames::No => {} }; @@ -105,13 +104,12 @@ pub(crate) fn unexpected_cfg_name( value: Option<(Symbol, Span)>, ) -> errors::UnexpectedCfgName { #[allow(rustc::potential_query_instability)] - let possibilities: Vec = sess.psess.check_config.expecteds.keys().copied().collect(); + let possibilities: Vec = sess.check_config.expecteds.keys().copied().collect(); let mut names_possibilities: Vec<_> = if value.is_none() { // We later sort and display all the possibilities, so the order here does not matter. #[allow(rustc::potential_query_instability)] - sess.psess - .check_config + sess.check_config .expecteds .iter() .filter_map(|(k, v)| match v { @@ -167,7 +165,7 @@ pub(crate) fn unexpected_cfg_name( is_feature_cfg |= best_match == sym::feature; if let Some(ExpectedValues::Some(best_match_values)) = - sess.psess.check_config.expecteds.get(&best_match) + sess.check_config.expecteds.get(&best_match) { // We will soon sort, so the initial order does not matter. #[allow(rustc::potential_query_instability)] @@ -285,7 +283,7 @@ pub(crate) fn unexpected_cfg_value( (name, name_span): (Symbol, Span), value: Option<(Symbol, Span)>, ) -> errors::UnexpectedCfgValue { - let Some(ExpectedValues::Some(values)) = &sess.psess.check_config.expecteds.get(&name) else { + let Some(ExpectedValues::Some(values)) = &sess.check_config.expecteds.get(&name) else { panic!( "it shouldn't be possible to have a diagnostic on a value whose name is not in values" ); @@ -305,7 +303,7 @@ pub(crate) fn unexpected_cfg_value( let is_from_external_macro = name_span.in_external_macro(sess.source_map()); let code_sugg = if let Some((value, _)) = value - && sess.psess.check_config.well_known_names.contains(&name) + && sess.check_config.well_known_names.contains(&name) && let valid_names = possible_well_known_names_for_cfg_value(sess, value) && !valid_names.is_empty() { @@ -378,12 +376,12 @@ pub(crate) fn unexpected_cfg_value( // We don't want to encourage people to add values to a well-known names, as these are // defined by rustc/Rust itself. Users can still do this if they wish, but should not be // encouraged to do so. - let can_suggest_adding_value = !sess.psess.check_config.well_known_names.contains(&name) + let can_suggest_adding_value = !sess.check_config.well_known_names.contains(&name) // Except when working on rustc or the standard library itself, in which case we want to // suggest adding these cfgs to the "normal" place because of bootstrapping reasons. As a // basic heuristic, we use the "cheat" unstable feature enable method and the // non-ui-testing enabled option. - || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat) + || (matches!(sess.unstable_features, rustc_feature::UnstableFeatures::Cheat) && !sess.opts.unstable_opts.ui_testing); let inst = |escape_quotes| { @@ -429,13 +427,11 @@ pub(crate) fn unexpected_cfg_value( fn possible_well_known_names_for_cfg_value(sess: &Session, value: Symbol) -> Vec { #[allow(rustc::potential_query_instability)] let mut names = sess - .psess .check_config .well_known_names .iter() .filter(|name| { - sess.psess - .check_config + sess.check_config .expecteds .get(*name) .map(|expected_values| expected_values.contains(&Some(value))) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index e9983d11c127f..f8b5c99c304b4 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -514,6 +514,9 @@ fn print_target_cpus(sess: &Session, tm: &llvm::TargetMachine, out: &mut String) }; let mut cpus = cpu_names .lines() + .filter(|cpu_name| { + !sess.target.unsupported_cpus.contains(&std::borrow::Cow::Borrowed(*cpu_name)) + }) .map(|cpu_name| Cpu { cpu_name, remark: make_remark(cpu_name) }) .collect::>(); diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 508b9add24aa0..39123b8bade59 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -171,7 +171,7 @@ impl<'tcx> AssertModuleSource<'tcx> { /// Scan for a `cfg="foo"` attribute and check whether we have a /// cfg flag called `foo`. fn check_config(&self, value: Symbol) -> bool { - let config = &self.tcx.sess.psess.config; + let config = &self.tcx.sess.config; debug!("check_config(config={:?}, value={:?})", config, value); if config.iter().any(|&(name, _)| name == value) { debug!("check_config: matched"); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 50c439593c306..14f4dca532737 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -696,6 +696,13 @@ pub fn codegen_crate( tcx.dcx().emit_fatal(errors::CpuRequired); } + if let Some(target_cpu) = &tcx.sess.opts.cg.target_cpu + && tcx.sess.target.unsupported_cpus.contains(&target_cpu.into()) + { + // The target cpu is explicitly listed as an unsupported cpu + tcx.dcx().emit_fatal(errors::CpuUnsupported { target_cpu: target_cpu.clone() }); + } + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); // Run the monomorphization collector and partition the collected items into diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index f1112510af0f0..006b7f881ce23 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -540,6 +540,12 @@ pub(crate) struct InsufficientVSCodeProduct; #[diag("target requires explicitly specifying a cpu with `-C target-cpu`")] pub(crate) struct CpuRequired; +#[derive(Diagnostic)] +#[diag("target cpu `{$target_cpu}` is known but unsupported")] +pub(crate) struct CpuUnsupported { + pub target_cpu: String, +} + #[derive(Diagnostic)] #[diag("processing debug info with `dsymutil` failed: {$status}")] #[note("{$output}")] diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 24f731c01996d..4b1b0866f2eb9 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -387,8 +387,20 @@ pub fn target_spec_to_backend_features<'a>( sess: &'a Session, mut extend_backend_features: impl FnMut(&'a str, /* enable */ bool), ) { - // Compute implied features let mut rust_features = vec![]; + + // This check handles SM versions that defaults (by LLVM) to unsupported (by Rust) PTX ISA versions. + // sm_70, sm_72 and sm_75 defaults to PTX ISA versions with major version 6, while sm_80 default to 7.0 + if sess.target.arch == Arch::Nvptx64 + && matches!( + sess.opts.cg.target_cpu.as_deref(), + None | Some("sm_70") | Some("sm_72") | Some("sm_75") + ) + { + rust_features.push((true, "ptx70")); + } + + // Compute implied features parse_rust_feature_list( sess, &sess.target.features, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b05f5bc4a8e20..8d80e742a1b27 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -734,7 +734,6 @@ fn print_crate_info( } Cfg => { let mut cfgs = sess - .psess .config .iter() .filter_map(|&(name, value)| { @@ -763,7 +762,7 @@ fn print_crate_info( // INSTABILITY: We are sorting the output below. #[allow(rustc::potential_query_instability)] - for (name, expected_values) in &sess.psess.check_config.expecteds { + for (name, expected_values) in &sess.check_config.expecteds { use crate::config::ExpectedValues; match expected_values { ExpectedValues::Any => { @@ -791,9 +790,7 @@ fn print_crate_info( } check_cfgs.sort_unstable(); - if !sess.psess.check_config.exhaustive_names - && sess.psess.check_config.exhaustive_values - { + if !sess.check_config.exhaustive_names && sess.check_config.exhaustive_values { println_info!("cfg(any())"); } for check_cfg in check_cfgs { diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 7b345fe5f483a..41e550b8d6a3a 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -15,6 +15,7 @@ use rustc_proc_macro::bridge::{ DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree, server, }; use rustc_proc_macro::{Delimiter, Level}; +use rustc_session::Session; use rustc_session::parse::ParseSess; use rustc_span::def_id::CrateNum; use rustc_span::{BytePos, FileName, Pos, Span, Symbol, sym}; @@ -440,6 +441,10 @@ impl<'a, 'b> Rustc<'a, 'b> { } } + fn sess(&self) -> &Session { + &self.ecx.sess + } + fn psess(&self) -> &ParseSess { self.ecx.psess() } @@ -825,7 +830,7 @@ impl server::Server for Rustc<'_, '_> { /// since we've loaded `my_proc_macro` from disk in order to execute it). /// In this way, we have obtained a span pointing into `my_proc_macro` fn span_save_span(&mut self, span: Self::Span) -> usize { - self.psess().save_proc_macro_span(span) + self.sess().save_proc_macro_span(span) } fn span_recover_proc_macro_span(&mut self, id: usize) -> Self::Span { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 1fa08bbde9a24..0a13d6c97e7c3 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -2099,7 +2099,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for CoerceVisitor<'_, 'tcx> { ControlFlow::Break(()) } } - Ok(Certainty::Maybe { .. }) => { + Ok(Certainty::Maybe(_)) => { // FIXME: structurally normalize? if self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::Unsize) && let ty::Dynamic(..) = pred.skip_binder().trait_ref.args.type_at(1).kind() diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index 51e65573a3566..f57e69fa2486e 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -183,12 +183,7 @@ impl<'tcx> CleanVisitor<'tcx> { item_id: LocalDefId, attr: &RustcCleanAttribute, ) -> Option { - self.tcx - .sess - .psess - .config - .contains(&(attr.cfg, None)) - .then(|| self.assertion_auto(item_id, attr)) + self.tcx.sess.config.contains(&(attr.cfg, None)).then(|| self.assertion_auto(item_id, attr)) } /// Gets the "auto" assertion on pre-validated attr, along with the `except` labels. @@ -406,7 +401,7 @@ struct FindAllAttrs<'tcx> { impl<'tcx> FindAllAttrs<'tcx> { fn is_active_attr(&self, attr: &RustcCleanAttribute) -> bool { - self.tcx.sess.psess.config.contains(&(attr.cfg, None)) + self.tcx.sess.config.contains(&(attr.cfg, None)) } fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet) { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index a20aa317e06a4..ab8bc1c7f1b34 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -452,11 +452,11 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let cfg = parse_cfg(sess.dcx(), config.crate_cfg); let mut cfg = config::build_configuration(&sess, cfg); util::add_configuration(&mut cfg, &mut sess, &*codegen_backend); - sess.psess.config = cfg; + sess.config = cfg; let mut check_cfg = parse_check_cfg(sess.dcx(), config.crate_check_cfg); check_cfg.fill_well_known(&sess.target); - sess.psess.check_config = check_cfg; + sess.check_config = check_cfg; if let Some(psess_created) = config.psess_created { psess_created(&mut sess.psess); diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 1547648100d58..673a7444f90c0 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -309,7 +309,7 @@ fn add_library( // This error is probably a little obscure, but I imagine that it // can be refined over time. if link2 != link || link == RequireStatic { - let linking_to_rustc_driver = tcx.sess.psess.unstable_features.is_nightly_build() + let linking_to_rustc_driver = tcx.sess.unstable_features.is_nightly_build() && tcx.crates(()).iter().any(|&cnum| tcx.crate_name(cnum) == sym::rustc_driver); tcx.dcx().emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ece9dc52c292c..c77711354f459 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1984,7 +1984,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let stability = tcx.lookup_stability(CRATE_DEF_ID); let macros = self.lazy_array(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)); - for (i, span) in self.tcx.sess.psess.proc_macro_quoted_spans() { + for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { let span = self.lazy(span); self.tables.proc_macro_quoted_spans.set_some(i, span); } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index b2a4e90b5bfcb..5a73c99616815 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -9,7 +9,7 @@ use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::search_graph::CandidateHeadUsages; -use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; +use rustc_type_ir::solve::{AliasBoundKind, MaybeInfo, SizedTraitKind, StalledOnCoroutines}; use rustc_type_ir::{ self as ty, AliasTy, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, @@ -501,7 +501,7 @@ where pub(super) fn forced_ambiguity( &mut self, - cause: MaybeCause, + maybe: MaybeInfo, ) -> Result, NoSolution> { // This may fail if `try_evaluate_added_goals` overflows because it // fails to reach a fixpoint but ends up getting an error after @@ -512,7 +512,7 @@ where // created a minimization for an ICE in typenum, but that one no // longer fails here. cc trait-system-refactor-initiative#105. let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc); - let certainty = Certainty::Maybe { cause, opaque_types_jank: OpaqueTypesJank::AllGood }; + let certainty = Certainty::Maybe(maybe); self.probe_trait_candidate(source) .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)) } @@ -1031,7 +1031,7 @@ where }; if opaque_types.is_empty() { - candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity)); + candidates.extend(self.forced_ambiguity(MaybeInfo::AMBIGUOUS)); return; } @@ -1122,10 +1122,11 @@ where if candidates.is_empty() { let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc); - let certainty = Certainty::Maybe { + let certainty = Certainty::Maybe(MaybeInfo { cause: MaybeCause::Ambiguity, opaque_types_jank: OpaqueTypesJank::ErrorIfRigidSelfTy, - }; + stalled_on_coroutines: StalledOnCoroutines::No, + }); candidates .extend(self.probe_trait_candidate(source).enter(|this| { this.evaluate_added_goals_and_make_canonical_response(certainty) @@ -1178,7 +1179,7 @@ where // // We use `forced_ambiguity` here over `make_ambiguous_response_no_constraints` // because the former will also record a built-in candidate in the inspector. - return self.forced_ambiguity(MaybeCause::Ambiguity).map(|cand| cand.result); + return self.forced_ambiguity(MaybeInfo::AMBIGUOUS).map(|cand| cand.result); }; match proven_via { @@ -1326,13 +1327,14 @@ where { self.recursion_depth += 1; if self.recursion_depth > self.ecx.cx().recursion_limit() { - return ControlFlow::Break(Ok(Certainty::Maybe { + return ControlFlow::Break(Ok(Certainty::Maybe(MaybeInfo { cause: MaybeCause::Overflow { suggest_increasing_limit: true, keep_constraints: false, }, opaque_types_jank: OpaqueTypesJank::AllGood, - })); + stalled_on_coroutines: StalledOnCoroutines::No, + }))); } let result = ty.super_visit_with(self); self.recursion_depth -= 1; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index e224febd3c927..0b556f38dd072 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -8,7 +8,7 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind}; -use rustc_type_ir::solve::OpaqueTypesJank; +use rustc_type_ir::solve::{MaybeInfo, OpaqueTypesJank}; use rustc_type_ir::{ self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -217,7 +217,11 @@ where }) .is_ok_and(|r| match r.certainty { Certainty::Yes => true, - Certainty::Maybe { cause: _, opaque_types_jank } => match opaque_types_jank { + Certainty::Maybe(MaybeInfo { + cause: _, + opaque_types_jank, + stalled_on_coroutines: _, + }) => match opaque_types_jank { OpaqueTypesJank::AllGood => true, OpaqueTypesJank::ErrorIfRigidSelfTy => false, }, @@ -1268,10 +1272,13 @@ where } }; - if let Certainty::Maybe { - cause: cause @ MaybeCause::Overflow { keep_constraints: false, .. }, - opaque_types_jank, - } = certainty + if let Certainty::Maybe( + maybe_info @ MaybeInfo { + cause: MaybeCause::Overflow { keep_constraints: false, .. }, + opaque_types_jank: _, + stalled_on_coroutines: _, + }, + ) = certainty { // If we have overflow, it's probable that we're substituting a type // into itself infinitely and any partial substitutions in the query @@ -1284,7 +1291,7 @@ where // // Changing this to retain some constraints in the future // won't be a breaking change, so this is good enough for now. - return Ok(self.make_ambiguous_response_no_constraints(cause, opaque_types_jank)); + return Ok(self.make_ambiguous_response_no_constraints(maybe_info)); } let external_constraints = @@ -1317,14 +1324,13 @@ where /// ambiguity but return constrained variables to guide inference. pub(in crate::solve) fn make_ambiguous_response_no_constraints( &self, - cause: MaybeCause, - opaque_types_jank: OpaqueTypesJank, + maybe: MaybeInfo, ) -> CanonicalResponse { response_no_constraints_raw( self.cx(), self.max_input_universe, self.var_kinds, - Certainty::Maybe { cause, opaque_types_jank }, + Certainty::Maybe(maybe), ) } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 793d45f22d39b..1df5a80cf29ad 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -158,10 +158,7 @@ where if self.may_use_unstable_feature(param_env, symbol) { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Maybe { - cause: MaybeCause::Ambiguity, - opaque_types_jank: OpaqueTypesJank::AllGood, - }) + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } } @@ -279,21 +276,16 @@ where fn bail_with_ambiguity(&mut self, candidates: &[Candidate]) -> CanonicalResponse { debug_assert!(candidates.len() > 1); - let (cause, opaque_types_jank) = candidates.iter().fold( - (MaybeCause::Ambiguity, OpaqueTypesJank::AllGood), - |(c, jank), candidates| { - // We pull down the certainty of `Certainty::Yes` to ambiguity when combining - // these responses, b/c we're combining more than one response and this we - // don't know which one applies. - match candidates.result.value.certainty { - Certainty::Yes => (c, jank), - Certainty::Maybe { cause, opaque_types_jank } => { - (c.or(cause), jank.or(opaque_types_jank)) - } - } - }, - ); - self.make_ambiguous_response_no_constraints(cause, opaque_types_jank) + let maybe = candidates.iter().fold(MaybeInfo::AMBIGUOUS, |maybe, candidate| { + // We pull down the certainty of `Certainty::Yes` to ambiguity when combining + // these responses, b/c we're combining more than one response and this we + // don't know which one applies. + match candidate.result.value.certainty { + Certainty::Yes => maybe, + Certainty::Maybe(cand_maybe) => maybe.or(cand_maybe), + } + }); + self.make_ambiguous_response_no_constraints(maybe) } /// If we fail to merge responses we flounder and return overflow or ambiguity. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 1d74f1efe9136..d93b7843b2251 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,7 +6,6 @@ mod opaque_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; -use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _, }; @@ -17,8 +16,8 @@ use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes use crate::solve::assembly::{self, Candidate}; use crate::solve::inspect::ProbeKind; use crate::solve::{ - BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - NoSolution, QueryResult, + BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeInfo, + NoSolution, QueryResult, SizedTraitKind, }; impl EvalCtxt<'_, D> @@ -460,7 +459,7 @@ where goal_kind, )? else { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); + return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS); }; let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output); @@ -588,7 +587,7 @@ where // Bail if the upvars haven't been constrained. if tupled_upvars_ty.expect_ty().is_ty_var() { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); + return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS); } let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else { diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index ffe90da4cb0fe..b97d895bec15f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -5,7 +5,8 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::solve::{ - AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, SizedTraitKind, + AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, MaybeInfo, OpaqueTypesJank, + SizedTraitKind, }; use rustc_type_ir::{ self as ty, FieldInfo, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef, @@ -21,7 +22,8 @@ use crate::solve::assembly::{ use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - MergeCandidateInfo, NoSolution, ParamEnvSource, QueryResult, has_only_region_constraints, + MergeCandidateInfo, NoSolution, ParamEnvSource, QueryResult, StalledOnCoroutines, + has_only_region_constraints, }; impl assembly::GoalKind for TraitPredicate @@ -372,7 +374,7 @@ where goal_kind, )? else { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); + return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS); }; let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output); @@ -671,7 +673,7 @@ where // Match the old solver by treating unresolved inference variables as // ambiguous until `rustc_transmute` can compute their layout. if goal.has_non_region_infer() { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); + return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS); } ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { @@ -823,7 +825,7 @@ where (ty::Infer(ty::TyVar(..)), ..) => panic!("unexpected infer {a_ty:?} {b_ty:?}"), (_, ty::Infer(ty::TyVar(..))) => { - result_to_single(ecx.forced_ambiguity(MaybeCause::Ambiguity)) + result_to_single(ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)) } // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`. @@ -1248,7 +1250,7 @@ where // we probably don't want to treat an `impl !AutoTrait for i32` as // disqualifying the built-in auto impl for `i64: AutoTrait` either. ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { - Some(self.forced_ambiguity(MaybeCause::Ambiguity)) + Some(self.forced_ambiguity(MaybeInfo::AMBIGUOUS)) } // Backward compatibility for default auto traits. @@ -1564,7 +1566,11 @@ where } => { if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) { - return Some(self.forced_ambiguity(MaybeCause::Ambiguity)); + return Some(self.forced_ambiguity(MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: OpaqueTypesJank::AllGood, + stalled_on_coroutines: StalledOnCoroutines::Yes, + })); } } TypingMode::Coherence diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 1f18b178489de..c09e3eed37125 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -14,14 +14,13 @@ use rustc_errors::{ BufferedEarlyLint, ColorConfig, DecorateDiagCompat, Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, EmissionGuarantee, Level, MultiSpan, StashKey, }; -use rustc_feature::{GateIssue, UnstableFeatures, find_feature_issue}; +use rustc_feature::{GateIssue, find_feature_issue}; use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{Span, Symbol, sym}; use crate::Session; -use crate::config::{Cfg, CheckCfg}; use crate::errors::{ CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureDiagnosticSuggestion, FeatureGateError, SuggestUpgradeCompiler, @@ -182,7 +181,7 @@ pub fn add_feature_diagnostics_for_issue( } // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if sess.psess.unstable_features.is_nightly_build() { + if sess.unstable_features.is_nightly_build() { if feature_from_cli { err.subdiagnostic(CliFeatureDiagnosticHelp { feature }); } else if let Some(span) = inject_span { @@ -226,7 +225,7 @@ pub fn feature_err_unstable_feature_bound( let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() }); // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if sess.psess.unstable_features.is_nightly_build() { + if sess.unstable_features.is_nightly_build() { err.subdiagnostic(FeatureDiagnosticHelp { feature }); if feature == sym::rustc_attrs { @@ -245,9 +244,6 @@ pub fn feature_err_unstable_feature_bound( /// Info about a parsing session. pub struct ParseSess { dcx: DiagCtxt, - pub unstable_features: UnstableFeatures, - pub config: Cfg, - pub check_config: CheckCfg, pub edition: Edition, /// Places where raw identifiers were used. This is used to avoid complaining about idents /// clashing with keywords in new editions. @@ -264,11 +260,6 @@ pub struct ParseSess { pub ambiguous_block_expr_parse: Lock>, pub gated_spans: GatedSpans, pub symbol_gallery: SymbolGallery, - /// Whether cfg(version) should treat the current release as incomplete - pub assume_incomplete_release: bool, - /// Spans passed to `proc_macro::quote_span`. Each span has a numerical - /// identifier represented by its position in the vector. - proc_macro_quoted_spans: AppendOnlyVec, /// Used to generate new `AttrId`s. Every `AttrId` is unique. pub attr_id_generator: AttrIdGenerator, } @@ -288,9 +279,6 @@ impl ParseSess { pub fn with_dcx(dcx: DiagCtxt, source_map: Arc) -> Self { Self { dcx, - unstable_features: UnstableFeatures::from_environment(None), - config: Cfg::default(), - check_config: CheckCfg::default(), edition: ExpnId::root().expn_data().edition, raw_identifier_spans: Default::default(), bad_unicode_identifiers: Lock::new(Default::default()), @@ -299,8 +287,6 @@ impl ParseSess { ambiguous_block_expr_parse: Lock::new(Default::default()), gated_spans: GatedSpans::default(), symbol_gallery: SymbolGallery::default(), - assume_incomplete_release: false, - proc_macro_quoted_spans: Default::default(), attr_id_generator: AttrIdGenerator::new(), } } @@ -388,16 +374,6 @@ impl ParseSess { }); } - pub fn save_proc_macro_span(&self, span: Span) -> usize { - self.proc_macro_quoted_spans.push(span) - } - - pub fn proc_macro_quoted_spans(&self) -> impl Iterator { - // This is equivalent to `.iter().copied().enumerate()`, but that isn't possible for - // AppendOnlyVec, so we resort to this scheme. - self.proc_macro_quoted_spans.iter_enumerated() - } - pub fn dcx(&self) -> DiagCtxtHandle<'_> { self.dcx.handle() } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index a9e7f1503b9ca..623a246dc1b59 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -10,7 +10,9 @@ use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; -use rustc_data_structures::sync::{DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock}; +use rustc_data_structures::sync::{ + AppendOnlyVec, DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock, +}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination}; @@ -20,6 +22,7 @@ use rustc_errors::{ Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort, TerminalUrl, }; +use rustc_feature::UnstableFeatures; use rustc_hir::limit::Limit; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; @@ -36,8 +39,9 @@ use rustc_target::spec::{ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, - Input, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath, + self, Cfg, CheckCfg, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType, + FunctionReturn, Input, InstrumentCoverage, OptLevel, OutFileName, OutputType, + SwitchWithOptPath, }; use crate::filesearch::FileSearch; use crate::lint::LintId; @@ -91,6 +95,13 @@ pub struct Session { pub opts: config::Options, pub target_tlib_path: Arc, pub psess: ParseSess, + pub unstable_features: UnstableFeatures, + pub config: Cfg, + pub check_config: CheckCfg, + /// Spans passed to `proc_macro::quote_span`. Each span has a numerical + /// identifier represented by its position in the vector. + proc_macro_quoted_spans: AppendOnlyVec, + /// Input, input file path and output file path to this compilation process. pub io: CompilerIO, @@ -302,6 +313,16 @@ impl Session { self.psess.source_map() } + pub fn proc_macro_quoted_spans(&self) -> impl Iterator { + // This is equivalent to `.iter().copied().enumerate()`, but that isn't possible for + // AppendOnlyVec, so we resort to this scheme. + self.proc_macro_quoted_spans.iter_enumerated() + } + + pub fn save_proc_macro_span(&self, span: Span) -> usize { + self.proc_macro_quoted_spans.push(span) + } + /// Returns `true` if internal lints should be added to the lint store - i.e. if /// `-Zunstable-options` is provided and this isn't rustdoc (internal lints can trigger errors /// to be emitted under rustdoc). @@ -1045,8 +1066,7 @@ pub fn build_session( None }; - let mut psess = ParseSess::with_dcx(dcx, source_map); - psess.assume_incomplete_release = sopts.unstable_opts.assume_incomplete_release; + let psess = ParseSess::with_dcx(dcx, source_map); let host_triple = config::host_tuple(); let target_triple = sopts.target_triple.tuple(); @@ -1090,6 +1110,10 @@ pub fn build_session( opts: sopts, target_tlib_path, psess, + unstable_features: UnstableFeatures::from_environment(None), + config: Cfg::default(), + check_config: CheckCfg::default(), + proc_macro_quoted_spans: Default::default(), io, incr_comp_session: RwLock::new(IncrCompSession::NotInitialized), prof, diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index 5507af0866758..8448c2ab51b3d 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -116,6 +116,7 @@ impl Target { forward!(asm_args); forward!(cpu); forward!(need_explicit_cpu); + forward!(unsupported_cpus); forward!(features); forward!(dynamic_linking); forward_opt!(direct_access_external_data); @@ -320,6 +321,7 @@ impl ToJson for Target { target_option_val!(asm_args); target_option_val!(cpu); target_option_val!(need_explicit_cpu); + target_option_val!(unsupported_cpus); target_option_val!(features); target_option_val!(dynamic_linking); target_option_val!(direct_access_external_data); @@ -543,6 +545,7 @@ struct TargetSpecJson { asm_args: Option]>>, cpu: Option>, need_explicit_cpu: Option, + unsupported_cpus: Option]>>, features: Option>, dynamic_linking: Option, direct_access_external_data: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 768e43146a0c1..74cf01e77754e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2361,6 +2361,10 @@ pub struct TargetOptions { /// Whether a cpu needs to be explicitly set. /// Set to true if there is no default cpu. Defaults to false. pub need_explicit_cpu: bool, + /// A list of CPUs that are provided by LLVM but are considered unsupported by Rust. + /// These CPUs are omitted from `--print target-cpus` output and will cause an error + /// if used with `-Ctarget-cpu`. + pub unsupported_cpus: StaticCow<[StaticCow]>, /// Default (Rust) target features to enable for this target. These features /// overwrite `-Ctarget-cpu` but can be overwritten with `-Ctarget-features`. /// Corresponds to `llc -mattr=$llvm_features` where `$llvm_features` is the @@ -2818,6 +2822,7 @@ impl Default for TargetOptions { asm_args: cvs![], cpu: "generic".into(), need_explicit_cpu: false, + unsupported_cpus: cvs![], features: "".into(), direct_access_external_data: None, dynamic_linking: false, diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index 87c2693e9877f..d8a0bd50ee204 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -1,6 +1,6 @@ use crate::spec::{ Arch, LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, Os, PanicStrategy, Target, - TargetMetadata, TargetOptions, + TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -22,7 +22,13 @@ pub(crate) fn target() -> Target { linker_flavor: LinkerFlavor::Llbc, // With `ptx-linker` approach, it can be later overridden via link flags. - cpu: "sm_30".into(), + cpu: "sm_70".into(), + + // No longer supported architectures + unsupported_cpus: cvs!( + "sm_20", "sm_21", "sm_30", "sm_32", "sm_35", "sm_37", "sm_50", "sm_52", "sm_53", + "sm_60", "sm_61", "sm_62" + ), // FIXME: create tests for the atomics. max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 963b167be424d..8a64242d64f31 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -536,19 +536,7 @@ const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start - ("sm_20", Unstable(sym::nvptx_target_feature), &[]), - ("sm_21", Unstable(sym::nvptx_target_feature), &["sm_20"]), - ("sm_30", Unstable(sym::nvptx_target_feature), &["sm_21"]), - ("sm_32", Unstable(sym::nvptx_target_feature), &["sm_30"]), - ("sm_35", Unstable(sym::nvptx_target_feature), &["sm_32"]), - ("sm_37", Unstable(sym::nvptx_target_feature), &["sm_35"]), - ("sm_50", Unstable(sym::nvptx_target_feature), &["sm_37"]), - ("sm_52", Unstable(sym::nvptx_target_feature), &["sm_50"]), - ("sm_53", Unstable(sym::nvptx_target_feature), &["sm_52"]), - ("sm_60", Unstable(sym::nvptx_target_feature), &["sm_53"]), - ("sm_61", Unstable(sym::nvptx_target_feature), &["sm_60"]), - ("sm_62", Unstable(sym::nvptx_target_feature), &["sm_61"]), - ("sm_70", Unstable(sym::nvptx_target_feature), &["sm_62"]), + ("sm_70", Unstable(sym::nvptx_target_feature), &[]), ("sm_72", Unstable(sym::nvptx_target_feature), &["sm_70"]), ("sm_75", Unstable(sym::nvptx_target_feature), &["sm_72"]), ("sm_80", Unstable(sym::nvptx_target_feature), &["sm_75"]), @@ -567,19 +555,7 @@ const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("sm_120a", Unstable(sym::nvptx_target_feature), &["sm_120"]), // tidy-alphabetical-end // tidy-alphabetical-start - ("ptx32", Unstable(sym::nvptx_target_feature), &[]), - ("ptx40", Unstable(sym::nvptx_target_feature), &["ptx32"]), - ("ptx41", Unstable(sym::nvptx_target_feature), &["ptx40"]), - ("ptx42", Unstable(sym::nvptx_target_feature), &["ptx41"]), - ("ptx43", Unstable(sym::nvptx_target_feature), &["ptx42"]), - ("ptx50", Unstable(sym::nvptx_target_feature), &["ptx43"]), - ("ptx60", Unstable(sym::nvptx_target_feature), &["ptx50"]), - ("ptx61", Unstable(sym::nvptx_target_feature), &["ptx60"]), - ("ptx62", Unstable(sym::nvptx_target_feature), &["ptx61"]), - ("ptx63", Unstable(sym::nvptx_target_feature), &["ptx62"]), - ("ptx64", Unstable(sym::nvptx_target_feature), &["ptx63"]), - ("ptx65", Unstable(sym::nvptx_target_feature), &["ptx64"]), - ("ptx70", Unstable(sym::nvptx_target_feature), &["ptx65"]), + ("ptx70", Unstable(sym::nvptx_target_feature), &[]), ("ptx71", Unstable(sym::nvptx_target_feature), &["ptx70"]), ("ptx72", Unstable(sym::nvptx_target_feature), &["ptx71"]), ("ptx73", Unstable(sym::nvptx_target_feature), &["ptx72"]), diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs index 5d200c4d340ba..518861fbd031d 100644 --- a/compiler/rustc_trait_selection/src/solve.rs +++ b/compiler/rustc_trait_selection/src/solve.rs @@ -7,7 +7,7 @@ mod normalize; mod select; pub(crate) use delegate::SolverDelegate; -pub use fulfill::{FulfillmentCtxt, NextSolverError, StalledOnCoroutines}; +pub use fulfill::{FulfillmentCtxt, NextSolverError}; pub(crate) use normalize::deeply_normalize_for_diagnostics; pub use normalize::{ deeply_normalize, deeply_normalize_with_skipped_universes, diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 26a9f392e2a47..8848b4c40f510 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -1,29 +1,23 @@ use std::marker::PhantomData; use std::mem; -use std::ops::ControlFlow; -use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::{ FromSolverError, PredicateObligation, PredicateObligations, TraitEngine, }; -use rustc_middle::ty::{ - self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - TypingMode, -}; +use rustc_middle::ty::{TyCtxt, TypeVisitableExt, TypingMode}; use rustc_next_trait_solver::delegate::SolverDelegate as _; use rustc_next_trait_solver::solve::{ - GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _, + GoalEvaluation, GoalStalledOn, HasChanged, MaybeInfo, SolverDelegateEvalExt as _, + StalledOnCoroutines, }; -use rustc_span::Span; use thin_vec::ThinVec; use tracing::instrument; use self::derive_errors::*; use super::Certainty; use super::delegate::SolverDelegate; -use super::inspect::{self, InferCtxtProofTreeExt}; use crate::traits::{FulfillmentError, ScrubbedTraitError}; mod derive_errors; @@ -87,10 +81,10 @@ impl<'tcx> ObligationStorage<'tcx> { fn drain_pending( &mut self, - cond: impl Fn(&PredicateObligation<'tcx>) -> bool, + cond: impl Fn(&PredicateObligation<'tcx>, &Option>>) -> bool, ) -> PendingObligations<'tcx> { let (unstalled, pending) = - mem::take(&mut self.pending).into_iter().partition(|(o, _)| cond(o)); + mem::take(&mut self.pending).into_iter().partition(|(o, s)| cond(o, s)); self.pending = pending; unstalled } @@ -183,7 +177,7 @@ where let mut errors = Vec::new(); loop { let mut any_changed = false; - for (mut obligation, stalled_on) in self.obligations.drain_pending(|_| true) { + for (mut obligation, stalled_on) in self.obligations.drain_pending(|_, _| true) { if !infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) { self.obligations.on_fulfillment_overflow(infcx); // Only return true errors that we have accumulated while processing. @@ -203,7 +197,7 @@ where // // Only goals proven via the trait solver should be region dependent. Certainty::Yes => {} - Certainty::Maybe { .. } => { + Certainty::Maybe(_) => { self.obligations.register(obligation, None); } } @@ -257,7 +251,7 @@ where infcx.push_hir_typeck_potentially_region_dependent_goal(obligation); } } - Certainty::Maybe { .. } => self.obligations.register(obligation, stalled_on), + Certainty::Maybe(_) => self.obligations.register(obligation, stalled_on), } } @@ -296,18 +290,14 @@ where } self.obligations - .drain_pending(|obl| { - infcx.probe(|_| { - infcx - .visit_proof_tree( - obl.as_goal(), - &mut StalledOnCoroutines { - stalled_coroutines, - span: obl.cause.span, - cache: Default::default(), - }, - ) - .is_break() + .drain_pending(|_, stalled_on| { + stalled_on.as_ref().is_some_and(|s| match s.stalled_certainty { + Certainty::Maybe(MaybeInfo { + cause: _, + opaque_types_jank: _, + stalled_on_coroutines: StalledOnCoroutines::Yes, + }) => true, + Certainty::Maybe(_) | Certainty::Yes => false, }) }) .into_iter() @@ -316,58 +306,6 @@ where } } -/// Detect if a goal is stalled on a coroutine that is owned by the current typeck root. -/// -/// This function can (erroneously) fail to detect a predicate, i.e. it doesn't need to -/// be complete. However, this will lead to ambiguity errors, so we want to make it -/// accurate. -/// -/// This function can be also return false positives, which will lead to poor diagnostics -/// so we want to keep this visitor *precise* too. -pub struct StalledOnCoroutines<'tcx> { - pub stalled_coroutines: &'tcx ty::List, - pub span: Span, - pub cache: DelayedSet>, -} - -impl<'tcx> inspect::ProofTreeVisitor<'tcx> for StalledOnCoroutines<'tcx> { - type Result = ControlFlow<()>; - - fn span(&self) -> rustc_span::Span { - self.span - } - - fn visit_goal(&mut self, inspect_goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result { - inspect_goal.goal().predicate.visit_with(self)?; - - if let Some(candidate) = inspect_goal.unique_applicable_candidate() { - candidate.visit_nested_no_probe(self) - } else { - ControlFlow::Continue(()) - } - } -} - -impl<'tcx> TypeVisitor> for StalledOnCoroutines<'tcx> { - type Result = ControlFlow<()>; - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - if !self.cache.insert(ty) { - return ControlFlow::Continue(()); - } - - if let ty::Coroutine(def_id, _) = *ty.kind() - && def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id)) - { - ControlFlow::Break(()) - } else if ty.has_coroutines() { - ty.super_visit_with(self) - } else { - ControlFlow::Continue(()) - } - } -} - pub enum NextSolverError<'tcx> { TrueError(PredicateObligation<'tcx>), Ambiguity(PredicateObligation<'tcx>), diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 0cd374aedb6f8..12dfe730aa303 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -11,7 +11,7 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _}; +use rustc_next_trait_solver::solve::{GoalEvaluation, MaybeInfo, SolverDelegateEvalExt as _}; use tracing::{instrument, trace}; use crate::solve::delegate::SolverDelegate; @@ -96,16 +96,22 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>( None, ) { Ok(GoalEvaluation { - certainty: Certainty::Maybe { cause: MaybeCause::Ambiguity, .. }, + certainty: + Certainty::Maybe(MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: _, + stalled_on_coroutines: _, + }), .. }) => (FulfillmentErrorCode::Ambiguity { overflow: None }, true), Ok(GoalEvaluation { certainty: - Certainty::Maybe { + Certainty::Maybe(MaybeInfo { cause: MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ }, - .. - }, + opaque_types_jank: _, + stalled_on_coroutines: _, + }), .. }) => ( FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }, @@ -271,7 +277,14 @@ impl<'tcx> BestObligation<'tcx> { ); // Skip nested goals that aren't the *reason* for our goal's failure. match (self.consider_ambiguities, nested_goal.result()) { - (true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })) + ( + true, + Ok(Certainty::Maybe(MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: _, + stalled_on_coroutines: _, + })), + ) | (false, Err(_)) => {} _ => continue, } @@ -413,8 +426,15 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { let tcx = goal.infcx().tcx; // Skip goals that aren't the *reason* for our goal's failure. match (self.consider_ambiguities, goal.result()) { - (true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })) | (false, Err(_)) => { - } + ( + true, + Ok(Certainty::Maybe(MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: _, + stalled_on_coroutines: _, + })), + ) + | (false, Err(_)) => {} _ => return ControlFlow::Continue(()), } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 370aa36e5f770..ad66078025bc4 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{TyCtxt, VisitorResult, try_visit}; use rustc_middle::{bug, ty}; use rustc_next_trait_solver::canonical::instantiate_canonical_state; use rustc_next_trait_solver::resolve::eager_resolve_vars; -use rustc_next_trait_solver::solve::{MaybeCause, SolverDelegateEvalExt as _, inspect}; +use rustc_next_trait_solver::solve::{MaybeCause, MaybeInfo, SolverDelegateEvalExt as _, inspect}; use rustc_span::Span; use tracing::instrument; @@ -332,7 +332,11 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => { assert_matches!( shallow_certainty.replace(c), - None | Some(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. }) + None | Some(Certainty::Maybe(MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: _, + stalled_on_coroutines: _, + })) ); } inspect::ProbeStep::NestedProbe(ref probe) => { diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index 1feaab2404153..b413b8b5ed9c7 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -62,7 +62,7 @@ impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select { // Don't winnow until `Certainty::Yes` -- we don't need to winnow until // codegen, and only on the good path. - if matches!(goal.result().unwrap(), Certainty::Maybe { .. }) { + if matches!(goal.result().unwrap(), Certainty::Maybe(_)) { return ControlFlow::Break(Ok(None)); } @@ -95,7 +95,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>( ) -> bool { // Don't winnow until `Certainty::Yes` -- we don't need to winnow until // codegen, and only on the good path. - if matches!(other.result().unwrap(), Certainty::Maybe { .. }) { + if matches!(other.result().unwrap(), Certainty::Maybe(_)) { return false; } @@ -145,13 +145,13 @@ fn to_selection<'tcx>( span: Span, cand: inspect::InspectCandidate<'_, 'tcx>, ) -> Option> { - if let Certainty::Maybe { .. } = cand.shallow_certainty() { + if let Certainty::Maybe(_) = cand.shallow_certainty() { return None; } let nested = match cand.result().expect("expected positive result") { Certainty::Yes => thin_vec![], - Certainty::Maybe { .. } => cand + Certainty::Maybe(_) => cand .instantiate_nested_goals(span) .into_iter() .map(|nested| { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 689b96779dca8..7b316f383997c 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -742,7 +742,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { // was irrelevant. match goal.result() { Ok(Certainty::Yes) | Err(NoSolution) => return, - Ok(Certainty::Maybe { .. }) => {} + Ok(Certainty::Maybe(_)) => {} } // For bound predicates we simply call `infcx.enter_forall` diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 11ff9911469e1..2992e396c1b99 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,4 +1,5 @@ use std::marker::PhantomData; +use std::ops::ControlFlow; use rustc_data_structures::obligation_forest::{ Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult, @@ -13,10 +14,9 @@ use rustc_middle::bug; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode, - may_use_unstable_feature, + self, Binder, Const, DelayedSet, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, TypingMode, may_use_unstable_feature, }; -use rustc_span::DUMMY_SP; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, debug_span, instrument}; @@ -29,7 +29,6 @@ use super::{ }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; -use crate::solve::StalledOnCoroutines; use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; @@ -207,11 +206,37 @@ where type OUT = Outcome; fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool { + struct StalledOnCoroutines<'tcx> { + pub stalled_coroutines: &'tcx ty::List, + pub cache: DelayedSet>, + } + + impl<'tcx> TypeVisitor> for StalledOnCoroutines<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if !self.cache.insert(ty) { + return ControlFlow::Continue(()); + } + + if let ty::Coroutine(def_id, _) = ty.kind() + && def_id + .as_local() + .is_some_and(|def_id| self.stalled_coroutines.contains(&def_id)) + { + ControlFlow::Break(()) + } else if ty.has_coroutines() { + ty.super_visit_with(self) + } else { + ControlFlow::Continue(()) + } + } + } + self.infcx .resolve_vars_if_possible(pending_obligation.obligation.predicate) .visit_with(&mut StalledOnCoroutines { stalled_coroutines: self.stalled_coroutines, - span: DUMMY_SP, cache: Default::default(), }) .is_break() diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index fe779b66dc245..43c9cf69b6199 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -289,7 +289,39 @@ impl NestedNormalizationGoals { #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum Certainty { Yes, - Maybe { cause: MaybeCause, opaque_types_jank: OpaqueTypesJank }, + Maybe(MaybeInfo), +} + +#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub struct MaybeInfo { + pub cause: MaybeCause, + pub opaque_types_jank: OpaqueTypesJank, + pub stalled_on_coroutines: StalledOnCoroutines, +} + +impl MaybeInfo { + pub const AMBIGUOUS: MaybeInfo = MaybeInfo { + cause: MaybeCause::Ambiguity, + opaque_types_jank: OpaqueTypesJank::AllGood, + stalled_on_coroutines: StalledOnCoroutines::No, + }; + + fn and(self, other: MaybeInfo) -> MaybeInfo { + MaybeInfo { + cause: self.cause.and(other.cause), + opaque_types_jank: self.opaque_types_jank.and(other.opaque_types_jank), + stalled_on_coroutines: self.stalled_on_coroutines.and(other.stalled_on_coroutines), + } + } + + pub fn or(self, other: MaybeInfo) -> MaybeInfo { + MaybeInfo { + cause: self.cause.or(other.cause), + opaque_types_jank: self.opaque_types_jank.or(other.opaque_types_jank), + stalled_on_coroutines: self.stalled_on_coroutines.or(other.stalled_on_coroutines), + } + } } /// Supporting not-yet-defined opaque types in HIR typeck is somewhat @@ -348,11 +380,33 @@ impl OpaqueTypesJank { } } +#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub enum StalledOnCoroutines { + Yes, + No, +} + +impl StalledOnCoroutines { + fn and(self, other: StalledOnCoroutines) -> StalledOnCoroutines { + match (self, other) { + (StalledOnCoroutines::No, StalledOnCoroutines::No) => StalledOnCoroutines::No, + (StalledOnCoroutines::Yes, _) | (_, StalledOnCoroutines::Yes) => { + StalledOnCoroutines::Yes + } + } + } + + pub fn or(self, other: StalledOnCoroutines) -> StalledOnCoroutines { + // `StalledOnCoroutines::Yes` is contagious: obtaining `Certainty::Maybe` + // while a candidate is stalled on a coroutine might have been + // `Certainty::Yes` or `NoSolution` if it were not stalled. + StalledOnCoroutines::and(self, other) + } +} + impl Certainty { - pub const AMBIGUOUS: Certainty = Certainty::Maybe { - cause: MaybeCause::Ambiguity, - opaque_types_jank: OpaqueTypesJank::AllGood, - }; + pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeInfo::AMBIGUOUS); /// Use this function to merge the certainty of multiple nested subgoals. /// @@ -371,21 +425,18 @@ impl Certainty { (Certainty::Yes, Certainty::Yes) => Certainty::Yes, (Certainty::Yes, Certainty::Maybe { .. }) => other, (Certainty::Maybe { .. }, Certainty::Yes) => self, - ( - Certainty::Maybe { cause: a_cause, opaque_types_jank: a_jank }, - Certainty::Maybe { cause: b_cause, opaque_types_jank: b_jank }, - ) => Certainty::Maybe { - cause: a_cause.and(b_cause), - opaque_types_jank: a_jank.and(b_jank), - }, + (Certainty::Maybe(a_maybe), Certainty::Maybe(b_maybe)) => { + Certainty::Maybe(a_maybe.and(b_maybe)) + } } } pub const fn overflow(suggest_increasing_limit: bool) -> Certainty { - Certainty::Maybe { + Certainty::Maybe(MaybeInfo { cause: MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false }, opaque_types_jank: OpaqueTypesJank::AllGood, - } + stalled_on_coroutines: StalledOnCoroutines::No, + }) } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 79694c46f2dcc..3451b2976bb73 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -209,7 +209,7 @@ use prelude::rust_2024::*; #[macro_use] mod macros; -#[stable(feature = "assert_matches", since = "1.95.0")] +#[stable(feature = "assert_matches", since = "1.96.0")] pub use crate::macros::{assert_matches, debug_assert_matches}; #[unstable(feature = "derive_from", issue = "144889")] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 08a12b6447e61..5fd7766633ce8 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -164,7 +164,7 @@ macro_rules! assert_ne { /// assert_matches!(a, Some(x) if x > 100); /// // assert_matches!(a, Some(x) if x < 100); // panics /// ``` -#[stable(feature = "assert_matches", since = "1.95.0")] +#[stable(feature = "assert_matches", since = "1.96.0")] #[allow_internal_unstable(panic_internals)] #[rustc_macro_transparency = "semiopaque"] pub macro assert_matches { @@ -391,7 +391,7 @@ macro_rules! debug_assert_ne { /// debug_assert_matches!(a, Some(x) if x > 100); /// // debug_assert_matches!(a, Some(x) if x < 100); // panics /// ``` -#[stable(feature = "assert_matches", since = "1.95.0")] +#[stable(feature = "assert_matches", since = "1.96.0")] #[allow_internal_unstable(assert_matches)] #[rustc_macro_transparency = "semiopaque"] pub macro debug_assert_matches($($arg:tt)*) { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 37bb7c8f77762..bb280f698b852 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -746,7 +746,7 @@ pub use core::{ assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, r#try, unimplemented, unreachable, write, writeln, }; -#[stable(feature = "assert_matches", since = "1.95.0")] +#[stable(feature = "assert_matches", since = "1.96.0")] pub use core::{assert_matches, debug_assert_matches}; // Re-export unstable derive macro defined through core. diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 2d9fc85dad33d..02510d9f3dee2 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -25,13 +25,23 @@ There are two options for using the core library: ### Target and features -It is generally necessary to specify the target, such as `-C target-cpu=sm_89`, because the default is very old. This implies two target features: `sm_89` and `ptx78` (and all preceding features within `sm_*` and `ptx*`). Rust will default to using the oldest PTX version that supports the target processor (see [this table](https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#release-notes-ptx-release-history)), which maximizes driver compatibility. -One can use `-C target-feature=+ptx80` to choose a later PTX version without changing the target (the default in this case, `ptx78`, requires CUDA driver version 11.8, while `ptx80` would require driver version 12.0). +It is often beneficial to specify the target SM architecture, such as `-C target-cpu=sm_89`, because the default prioritizes broad compatibility rather than performance. Doing so also selects the PTX version as the *maximum* of (a) the oldest PTX version that supports the chosen target processor (see [this table](https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#release-notes-ptx-release-history)) and (b) the oldest PTX version supported by the Rust toolchain, which maximizes driver compatibility. +One can use `-C target-feature=+ptx80` to choose a later PTX version without changing the target SM architecture (the default in this case, `ptx78`, requires CUDA driver version 11.8, while `ptx80` would require driver version 12.0). Later PTX versions may allow more efficient code generation. Although Rust follows LLVM in representing `ptx*` and `sm_*` as target features, they should be thought of as having crate granularity, set via (either via `-Ctarget-cpu` and optionally `-Ctarget-feature`). While the compiler accepts `#[target_feature(enable = "ptx80", enable = "sm_89")]`, it is not supported, may not behave as intended, and may become erroneous in the future. +## Minimum SM and PTX support by Rust version +Support for old hardware architectures and PTX ISA versions is periodically dropped. This table shows the minimum supported versions per Rust version. + +| Rust | SM minimum | PTX ISA minimum | +| ------------ | -------------- | --------------- | +| - 1.96 | 2.0 | 3.2 | +| 1.97 - TBD | 7.0 (Volta+) | 7.0 (CUDA 11+) | + +For a full overview of which GPUs support code built for a specific SM version, see the [CUDA GPU Compute Capability documentation](https://developer.nvidia.com/cuda/gpus). + ## Building Rust kernels A `no_std` crate containing one or more functions with `extern "ptx-kernel"` can be compiled to PTX using a command like the following. diff --git a/tests/assembly-llvm/nvptx-arch-default.rs b/tests/assembly-llvm/nvptx-arch-default.rs index 22b4a680e322c..e71304e453303 100644 --- a/tests/assembly-llvm/nvptx-arch-default.rs +++ b/tests/assembly-llvm/nvptx-arch-default.rs @@ -8,5 +8,6 @@ extern crate breakpoint_panic_handler; // Verify default target arch with ptx-linker. -// CHECK: .target sm_30 +// CHECK: .version 7.0 +// CHECK: .target sm_70 // CHECK: .address_size 64 diff --git a/tests/assembly-llvm/nvptx-arch-emit-asm.rs b/tests/assembly-llvm/nvptx-arch-emit-asm.rs index e47f8e78e3679..9266309c6202e 100644 --- a/tests/assembly-llvm/nvptx-arch-emit-asm.rs +++ b/tests/assembly-llvm/nvptx-arch-emit-asm.rs @@ -5,5 +5,6 @@ #![no_std] // Verify default arch without ptx-linker involved. -// CHECK: .target sm_30 +// CHECK: .version 7.0 +// CHECK: .target sm_70 // CHECK: .address_size 64 diff --git a/tests/assembly-llvm/nvptx-arch-target-cpu.rs b/tests/assembly-llvm/nvptx-arch-target-cpu.rs index e02ad0d558a96..b5062f1ba20d7 100644 --- a/tests/assembly-llvm/nvptx-arch-target-cpu.rs +++ b/tests/assembly-llvm/nvptx-arch-target-cpu.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -C target-cpu=sm_50 +//@ compile-flags: --crate-type cdylib -C target-cpu=sm_87 //@ only-nvptx64 #![no_std] @@ -8,5 +8,5 @@ extern crate breakpoint_panic_handler; // Verify target arch override via `target-cpu`. -// CHECK: .target sm_50 +// CHECK: .target sm_87 // CHECK: .address_size 64 diff --git a/tests/ui/associated-consts/associated-const-trait-bound.rs b/tests/ui/associated-consts/associated-const-trait-bound.rs index 6dfdbff85c03a..8069c676637a7 100644 --- a/tests/ui/associated-consts/associated-const-trait-bound.rs +++ b/tests/ui/associated-consts/associated-const-trait-bound.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass trait ConstDefault { const DEFAULT: Self; diff --git a/tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs deleted file mode 100644 index 85d6c5aaf3c6f..0000000000000 --- a/tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs +++ /dev/null @@ -1,182 +0,0 @@ -// Traits: - -pub trait Alpha { - fn alpha(self) -> usize; -} - -pub trait Beta { - type Gamma; - fn gamma(&self) -> Self::Gamma; -} - -pub trait Delta { - fn delta(self) -> usize; -} - -pub trait Epsilon<'a> { - type Zeta; - fn zeta(&'a self) -> Self::Zeta; - - fn epsilon(&'a self) -> usize; -} - -pub trait Eta { - fn eta(self) -> usize; -} - -// Assertions: - -pub fn assert_alpha(x: T) -> usize { x.alpha() } -pub fn assert_static(_: T) -> usize { 24 } -pub fn assert_delta(x: T) -> usize { x.delta() } -pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } -pub fn assert_epsilon_forall Epsilon<'a>>() {} -pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize -where - T: for<'a> Epsilon<'a>, - for<'a> >::Zeta: Eta, -{ - x.epsilon() + x.zeta().eta() -} - -// Implementations and types: - -#[derive(Copy, Clone)] -pub struct BetaType; - -#[derive(Copy, Clone)] -pub struct GammaType; - -#[derive(Copy, Clone)] -pub struct ZetaType; - -impl Beta for &(dyn Beta + Send) { - type Gamma = T; - fn gamma(&self) -> Self::Gamma { (*self).gamma() } -} - -impl Beta for BetaType { - type Gamma = GammaType; - fn gamma(&self) -> Self::Gamma { GammaType } -} - -impl<'a> Beta for &'a BetaType { - type Gamma = GammaType; - fn gamma(&self) -> Self::Gamma { GammaType } -} - -impl Beta for GammaType { - type Gamma = Self; - fn gamma(&self) -> Self::Gamma { Self } -} - -impl Alpha for GammaType { - fn alpha(self) -> usize { 42 } -} - -impl Delta for GammaType { - fn delta(self) -> usize { 1337 } -} - -impl<'a> Epsilon<'a> for GammaType { - type Zeta = ZetaType; - fn zeta(&'a self) -> Self::Zeta { ZetaType } - - fn epsilon(&'a self) -> usize { 7331 } -} - -impl Eta for ZetaType { - fn eta(self) -> usize { 7 } -} - -// Desugared forms to check against: - -pub fn desugared_bound(beta: &B) -> usize -where - B: Beta, - B::Gamma: Alpha -{ - let gamma: B::Gamma = beta.gamma(); - assert_alpha::(gamma) -} - -pub fn desugared_bound_region(beta: &B) -> usize -where - B: Beta, - B::Gamma: 'static, -{ - assert_static::(beta.gamma()) -} - -pub fn desugared_bound_multi(beta: B) -> usize -where - B: Copy + Beta, - B::Gamma: Alpha + 'static + Delta, -{ - assert_alpha::(beta.gamma()) + - assert_static::(beta.gamma()) + - assert_delta::(beta.gamma()) -} - -pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize -where - B: Beta, - B::Gamma: 'a + Epsilon<'a>, -{ - assert_epsilon_specific::(gamma) -} - -pub fn desugared_bound_region_forall(beta: &B) -> usize -where - B: Beta, - B::Gamma: Copy + for<'a> Epsilon<'a>, -{ - assert_epsilon_forall::(); - let g1: B::Gamma = beta.gamma(); - let g2: B::Gamma = g1; - assert_epsilon_specific::(&g1) + - assert_epsilon_specific::(&g2) -} - -pub fn desugared_bound_region_forall2(beta: &B) -> usize -where - B: Beta, - B::Gamma: Copy + for<'a> Epsilon<'a>, - for<'a> >::Zeta: Eta, -{ - let gamma = beta.gamma(); - assert_forall_epsilon_zeta_satisfies_eta::(gamma) -} - -pub fn desugared_contraint_region_forall(beta: &B) -> usize -where - for<'a> &'a B: Beta, - for<'a> <&'a B as Beta>::Gamma: Alpha, -{ - let g1 = beta.gamma(); - let g2 = beta.gamma(); - assert_alpha(g1) + assert_alpha(g2) -} - -pub fn desugared_bound_nested(beta: &B) -> usize -where - B: Beta, - B::Gamma: Copy + Alpha + Beta, - ::Gamma: Delta, -{ - let go = beta.gamma(); - let gi = go.gamma(); - go.alpha() + gi.delta() -} - -pub fn desugared() { - let beta = BetaType; - let gamma = beta.gamma(); - - assert_eq!(42, desugared_bound(&beta)); - assert_eq!(24, desugared_bound_region(&beta)); - assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); - assert_eq!(7331, desugared_bound_region_specific::(&gamma)); - assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); - assert_eq!(42 + 1337, desugared_bound_nested(&beta)); -} diff --git a/tests/ui/associated-type-bounds/entails-sized-dyn-compatibility.rs b/tests/ui/associated-type-bounds/entails-sized-dyn-compatibility.rs index 943df68493fb1..d5e8252ff19da 100644 --- a/tests/ui/associated-type-bounds/entails-sized-dyn-compatibility.rs +++ b/tests/ui/associated-type-bounds/entails-sized-dyn-compatibility.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass trait Tr1: Sized { type As1; } trait Tr2<'a>: Sized { type As2; } diff --git a/tests/ui/associated-type-bounds/trait-params.rs b/tests/ui/associated-type-bounds/trait-params.rs index 72a445351e760..87f52fad9f9c5 100644 --- a/tests/ui/associated-type-bounds/trait-params.rs +++ b/tests/ui/associated-type-bounds/trait-params.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass use std::iter::Once; use std::ops::Range; diff --git a/tests/ui/async-await/async-closures/is-not-fn.next.stderr b/tests/ui/async-await/async-closures/is-not-fn.next.stderr index 970970a915114..0fab1c15f27df 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.next.stderr +++ b/tests/ui/async-await/async-closures/is-not-fn.next.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25} == ()` +error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to return `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}` --> $DIR/is-not-fn.rs:8:14 | LL | needs_fn(async || {}); - | -------- ^^^^^^^^^^^ types differ + | -------- ^^^^^^^^^^^ expected `()`, found `async` closure body | | | required by a bound introduced by this call | + = note: expected unit type `()` + found `async` closure body `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}` note: required by a bound in `needs_fn` --> $DIR/is-not-fn.rs:7:25 | diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs index c09ccb3fc2b09..e5ab4742daba1 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.rs +++ b/tests/ui/async-await/async-closures/is-not-fn.rs @@ -6,6 +6,5 @@ fn main() { fn needs_fn(x: impl FnOnce()) {} needs_fn(async || {}); - //[current]~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to return `()` - //[next]~^^ ERROR type mismatch resolving `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25} == ()` + //~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to return `()` } diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index b53419c512b08..981c173242408 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -229,18 +229,6 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `power9-altivec` `power9-vector` `prfchw` -`ptx32` -`ptx40` -`ptx41` -`ptx42` -`ptx43` -`ptx50` -`ptx60` -`ptx61` -`ptx62` -`ptx63` -`ptx64` -`ptx65` `ptx70` `ptx71` `ptx72` @@ -290,18 +278,6 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `sm_101a` `sm_120` `sm_120a` -`sm_20` -`sm_21` -`sm_30` -`sm_32` -`sm_35` -`sm_37` -`sm_50` -`sm_52` -`sm_53` -`sm_60` -`sm_61` -`sm_62` `sm_70` `sm_72` `sm_75` diff --git a/tests/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs b/tests/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs index f0e20d67fa6c9..804dcc5488b1e 100644 --- a/tests/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs +++ b/tests/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass #![allow(warnings)] diff --git a/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs b/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs index 799dc8bf08999..9454845362947 100644 --- a/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs +++ b/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs b/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs index e9109ddff1a74..9bb6246a119a7 100644 --- a/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs +++ b/tests/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/tests/ui/closures/closure_promotion.rs b/tests/ui/closures/closure_promotion.rs index c790e423a806b..3b3c498c7a843 100644 --- a/tests/ui/closures/closure_promotion.rs +++ b/tests/ui/closures/closure_promotion.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass fn main() { let x: &'static _ = &|| { let z = 3; z }; diff --git a/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs index 593661c8d7661..57077fcbc47c6 100644 --- a/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs +++ b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs @@ -2,7 +2,7 @@ // `MyType: !MyTrait` along with other "fundamental" wrappers. //@ aux-build:coherence_copy_like_lib.rs -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass // skip-codgen #![allow(dead_code)] diff --git a/tests/ui/deprecation/derive_on_deprecated.rs b/tests/ui/deprecation/derive_on_deprecated.rs index b3d784aec37b3..5aaa25eae8fb1 100644 --- a/tests/ui/deprecation/derive_on_deprecated.rs +++ b/tests/ui/deprecation/derive_on_deprecated.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass #![deny(deprecated)] diff --git a/tests/ui/deprecation/derive_on_deprecated_forbidden.rs b/tests/ui/deprecation/derive_on_deprecated_forbidden.rs index c240a6938fc55..247d8a4d6ffcc 100644 --- a/tests/ui/deprecation/derive_on_deprecated_forbidden.rs +++ b/tests/ui/deprecation/derive_on_deprecated_forbidden.rs @@ -1,4 +1,4 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass #![forbid(deprecated)] diff --git a/tests/ui/dyn-compatibility/by-value-self.rs b/tests/ui/dyn-compatibility/by-value-self.rs index a057a7ff0b57a..88d5dd2069b68 100644 --- a/tests/ui/dyn-compatibility/by-value-self.rs +++ b/tests/ui/dyn-compatibility/by-value-self.rs @@ -1,6 +1,6 @@ // Check that a trait with by-value self is considered dyn-compatible. -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass #![allow(dead_code)] #![allow(trivial_casts)] diff --git a/tests/ui/dyn-compatibility/phantom-fn.rs b/tests/ui/dyn-compatibility/phantom-fn.rs index 9e410da82eed5..53cd02dc19202 100644 --- a/tests/ui/dyn-compatibility/phantom-fn.rs +++ b/tests/ui/dyn-compatibility/phantom-fn.rs @@ -1,6 +1,6 @@ // Check that `Self` appearing in a phantom fn does not make a trait dyn-incompatible. -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass #![allow(dead_code)] trait Baz { diff --git a/tests/ui/extern/auxiliary/reexport-should-still-link.rs b/tests/ui/extern/auxiliary/reexport-should-still-link.rs deleted file mode 100644 index 237ea8dfcf3f8..0000000000000 --- a/tests/ui/extern/auxiliary/reexport-should-still-link.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use foo::bar; - -mod foo { - pub fn bar() {} -} diff --git a/tests/ui/linkage-attr/auxiliary/def_colliding_external.rs b/tests/ui/linkage-attr/auxiliary/def_colliding_external.rs deleted file mode 100644 index 60b55b3e27bc8..0000000000000 --- a/tests/ui/linkage-attr/auxiliary/def_colliding_external.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![feature(linkage)] -#![crate_type = "lib"] - -extern "C" { - #[linkage = "external"] - pub static collision: *const i32; -} diff --git a/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs b/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs deleted file mode 100644 index 4bc56efecdbf5..0000000000000 --- a/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_derive(Unstable)] -pub fn derive(_input: TokenStream) -> TokenStream { - - " - #[rustc_foo] - fn foo() {} - ".parse().unwrap() -} diff --git a/tests/ui/static/auxiliary/static-priv-by-default.rs b/tests/ui/static/auxiliary/static-priv-by-default.rs deleted file mode 100644 index f36f87c5736a1..0000000000000 --- a/tests/ui/static/auxiliary/static-priv-by-default.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ aux-build:static_priv_by_default.rs - -extern crate static_priv_by_default; - -mod child { - pub mod childs_child { - static private: isize = 0; - pub static public: isize = 0; - } -} - -fn foo(_: isize) {} - -fn full_ref() { - foo(static_priv_by_default::private); //~ ERROR: static `private` is private - foo(static_priv_by_default::public); - foo(child::childs_child::private); //~ ERROR: static `private` is private - foo(child::childs_child::public); -} - -fn medium_ref() { - use child::childs_child; - foo(childs_child::private); //~ ERROR: static `private` is private - foo(childs_child::public); -} - -fn main() {} diff --git a/tests/ui/target-cpu/unsupported-target-cpu.nvptx-sm60.stderr b/tests/ui/target-cpu/unsupported-target-cpu.nvptx-sm60.stderr new file mode 100644 index 0000000000000..76092b8391f33 --- /dev/null +++ b/tests/ui/target-cpu/unsupported-target-cpu.nvptx-sm60.stderr @@ -0,0 +1,4 @@ +error: target cpu `sm_60` is known but unsupported + +error: aborting due to 1 previous error + diff --git a/tests/ui/target-cpu/unsupported-target-cpu.rs b/tests/ui/target-cpu/unsupported-target-cpu.rs new file mode 100644 index 0000000000000..dafbfbc015ec1 --- /dev/null +++ b/tests/ui/target-cpu/unsupported-target-cpu.rs @@ -0,0 +1,14 @@ +//! Check that certain target *respect* the unsupported-cpus in `-C target-cpu`. + +//@ revisions: nvptx-sm60 + +//@[nvptx-sm60] compile-flags: --target=nvptx64-nvidia-cuda --crate-type=rlib -Ctarget-cpu=sm_60 +//@[nvptx-sm60] needs-llvm-components: nvptx +//@[nvptx-sm60] build-fail +//@ ignore-backends: gcc + +#![feature(no_core)] +#![no_core] +#![crate_type = "rlib"] + +//[nvptx-sm60]~? ERROR target cpu `sm_60` is known but unsupported diff --git a/tests/ui/traits/next-solver/deeply-nested-stalled-on-coroutines.rs b/tests/ui/traits/next-solver/deeply-nested-stalled-on-coroutines.rs new file mode 100644 index 0000000000000..9c481b2779e72 --- /dev/null +++ b/tests/ui/traits/next-solver/deeply-nested-stalled-on-coroutines.rs @@ -0,0 +1,41 @@ +//@ compile-flags: -Znext-solver +//@ check-pass +//@ edition: 2024 + +// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/270 + +struct Wrap(T); + +impl Wrap { + fn nest(self) -> Wrap { + Wrap(self) + } +} + +fn assert_send(s: S) -> S { + s +} + +// We need an indirection so that the goal stalled on coroutine is not the root goal +fn mk_opaque(f: F) -> impl Future +where + F: AsyncFnOnce(), +{ + f() +} + +fn test() { + let coroutine = async || {}; + let opaque = mk_opaque(coroutine); + // This `deep_nested: Send` is ambiguous because it contains nested obligation whose self_ty is + // coroutine. + // It should be collected into `stalled_coroutine_obligation` before report ambiguity errors. + // But it used to be not, because we were collecting them with a `ProofTreeVisitor`, which has + // a recursion limit. + let deep_nested = + Wrap(opaque).nest().nest().nest().nest().nest().nest().nest().nest().nest().nest().nest(); + + assert_send(deep_nested); +} + +fn main() {} diff --git a/tests/ui/variance/variance-use-contravariant-struct-2.rs b/tests/ui/variance/variance-use-contravariant-struct-2.rs index ef6264d334811..cb2c5698dddd7 100644 --- a/tests/ui/variance/variance-use-contravariant-struct-2.rs +++ b/tests/ui/variance/variance-use-contravariant-struct-2.rs @@ -2,7 +2,7 @@ // they permit lifetimes to be approximated as expected. #![allow(dead_code)] -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass struct SomeStruct(fn(T)); diff --git a/tests/ui/variance/variance-use-covariant-struct-2.rs b/tests/ui/variance/variance-use-covariant-struct-2.rs index 14f5d541c690a..ac5d5cccd51fe 100644 --- a/tests/ui/variance/variance-use-covariant-struct-2.rs +++ b/tests/ui/variance/variance-use-covariant-struct-2.rs @@ -2,7 +2,7 @@ // be shortened. #![allow(dead_code)] -//@ build-pass (FIXME(62277): could be check-pass?) +//@ check-pass struct SomeStruct(T);