diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index c9dd92ff2f243..86671d0326da2 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -3,8 +3,6 @@ builtin_macros_alloc_must_statics = allocators must be statics builtin_macros_asm_attribute_not_supported = this attribute is not supported on assembly -builtin_macros_asm_cfg = - the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable builtin_macros_asm_clobber_abi = clobber_abi builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 971b68d14757a..2958686f86cd5 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -6,14 +6,13 @@ use rustc_expand::base::*; use rustc_index::bit_set::GrowableBitSet; use rustc_parse::parser::asm::*; use rustc_session::lint; -use rustc_session::parse::feature_err; use rustc_span::{ErrorGuaranteed, InnerSpan, Span, Symbol, sym}; use rustc_target::asm::InlineAsmArch; use smallvec::smallvec; use {rustc_ast as ast, rustc_parse_format as parse}; +use crate::errors; use crate::util::{ExprToSpannedString, expr_to_spanned_string}; -use crate::{errors, fluent_generated as fluent}; /// Validated assembly arguments, ready for macro expansion. struct ValidatedAsmArgs { @@ -64,22 +63,13 @@ fn validate_asm_args<'a>( for arg in args { for attr in arg.attributes.0.iter() { - match attr.name() { - Some(sym::cfg | sym::cfg_attr) => { - if !ecx.ecfg.features.asm_cfg() { - let span = attr.span(); - feature_err(ecx.sess, sym::asm_cfg, span, fluent::builtin_macros_asm_cfg) - .emit(); - } - } - _ => { - ecx.dcx().emit_err(errors::AsmAttributeNotSupported { span: attr.span() }); - } + if !matches!(attr.name(), Some(sym::cfg | sym::cfg_attr)) { + ecx.dcx().emit_err(errors::AsmAttributeNotSupported { span: attr.span() }); } } // Skip arguments that are configured out. - if ecx.ecfg.features.asm_cfg() && strip_unconfigured.configure(arg.attributes).is_none() { + if strip_unconfigured.configure(arg.attributes).is_none() { continue; } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 5af47d51b711d..7e765918d7b69 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -60,6 +60,8 @@ declare_features! ( (accepted, adx_target_feature, "1.61.0", Some(44839)), /// Allows explicit discriminants on non-unit enum variants. (accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)), + /// Allows #[cfg(...)] on inline assembly templates and operands. + (accepted, asm_cfg, "CURRENT_RUSTC_VERSION", Some(140364)), /// Allows using `const` operands in inline assembly. (accepted, asm_const, "1.82.0", Some(93332)), /// Allows using `label` operands in inline assembly. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 26612fda5a7fb..813d2fced865d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -382,8 +382,6 @@ declare_features! ( (unstable, arbitrary_self_types, "1.23.0", Some(44874)), /// Allows inherent and trait methods with arbitrary self types that are raw pointers. (unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)), - /// Allows #[cfg(...)] on inline assembly templates and operands. - (unstable, asm_cfg, "1.89.0", Some(140364)), /// Enables experimental inline assembly support for additional architectures. (unstable, asm_experimental_arch, "1.58.0", Some(93335)), /// Enables experimental register support in inline assembly. diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ccae524352a59..06738d99bf562 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1186,14 +1186,21 @@ pub(crate) fn check_static_item<'tcx>( ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item_id, |wfcx| { let span = tcx.ty_span(item_id); - let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let loc = Some(WellFormedLoc::Ty(item_id)); + let item_ty = wfcx.deeply_normalize(span, loc, ty); let is_foreign_item = tcx.is_foreign_item(item_id); + let is_structurally_foreign_item = || { + let tail = tcx.struct_tail_raw( + item_ty, + &ObligationCause::dummy(), + |ty| wfcx.deeply_normalize(span, loc, ty), + || {}, + ); - let forbid_unsized = !is_foreign_item || { - let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); - !matches!(tail.kind(), ty::Foreign(_)) + matches!(tail.kind(), ty::Foreign(_)) }; + let forbid_unsized = !(is_foreign_item && is_structurally_foreign_item()); wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(item_id)), item_ty.into()); if forbid_unsized { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a0d9e9a72386c..9a657ab159035 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -666,99 +666,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn report_no_match_method_error( + fn suggest_method_call_annotation( &self, - mut span: Span, + err: &mut Diag<'_>, + span: Span, rcvr_ty: Ty<'tcx>, item_ident: Ident, - expr_id: hir::HirId, + mode: Mode, source: SelfSource<'tcx>, - args: Option<&'tcx [hir::Expr<'tcx>]>, - sugg_span: Span, - no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, - trait_missing_method: bool, - within_macro_span: Option, - ) -> ErrorGuaranteed { - let mode = no_match_data.mode; - let tcx = self.tcx; - let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); - let mut ty_file = None; - let is_method = mode == Mode::MethodCall; - let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; - let similar_candidate = no_match_data.similar_candidate; - let item_kind = if is_method { - "method" - } else if rcvr_ty.is_enum() { - "variant or associated item" - } else { - match (item_ident.as_str().chars().next(), rcvr_ty.is_fresh_ty()) { - (Some(name), false) if name.is_lowercase() => "function or associated item", - (Some(_), false) => "associated item", - (Some(_), true) | (None, false) => "variant or associated item", - (None, true) => "variant", - } - }; - - // We could pass the file for long types into these two, but it isn't strictly necessary - // given how targeted they are. - if let Err(guar) = - self.report_failed_method_call_on_range_end(tcx, rcvr_ty, source, span, item_ident) - { - return guar; - } - if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( - tcx, - rcvr_ty, - source, - span, - item_kind, - item_ident, - &mut ty_file, - ) { - return guar; - } - span = item_ident.span; - - let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| { - tcx.is_diagnostic_item(sym::write_macro, def_id) - || tcx.is_diagnostic_item(sym::writeln_macro, def_id) - }) && item_ident.name == sym::write_fmt; - let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { - self.create_missing_writer_err(rcvr_ty, rcvr_expr, ty_file) - } else { - self.create_no_assoc_err( - rcvr_ty, - item_ident, - item_kind, - trait_missing_method, - source, - is_method, - sugg_span, - unsatisfied_predicates, - ) - }; - if rcvr_ty.references_error() { - err.downgrade_to_delayed_bug(); - } - - self.set_label_for_method_error( - &mut err, - source, - rcvr_ty, - item_ident, - expr_id, - span, - sugg_span, - within_macro_span, - args, - ); - + ) { if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source { self.suggest_await_before_method( - &mut err, + err, item_ident, rcvr_ty, cal, @@ -767,10 +689,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - self.suggest_on_pointer_type(&mut err, source, rcvr_ty, item_ident); + self.suggest_on_pointer_type(err, source, rcvr_ty, item_ident); if let SelfSource::MethodCall(rcvr_expr) = source { - self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { + self.suggest_fn_call(err, rcvr_expr, rcvr_ty, |output_ty| { let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); let probe = self.lookup_probe_for_diagnostic( item_ident, @@ -782,14 +704,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { probe.is_ok() }); self.note_internal_mutation_in_method( - &mut err, + err, rcvr_expr, expected.to_option(self), rcvr_ty, ); } + } - let mut custom_span_label = false; + fn suggest_static_method_candidates( + &self, + err: &mut Diag<'_>, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + source: SelfSource<'tcx>, + args: Option<&'tcx [hir::Expr<'tcx>]>, + sugg_span: Span, + no_match_data: &NoMatchData<'tcx>, + ) -> Vec { let mut static_candidates = no_match_data.static_candidates.clone(); // `static_candidates` may have same candidates appended by @@ -803,11 +736,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { functions must have a `self` parameter", ); err.span_label(span, "this is an associated function, not a method"); - custom_span_label = true; } if static_candidates.len() == 1 { self.suggest_associated_call_syntax( - &mut err, + err, &static_candidates, rcvr_ty, source, @@ -821,7 +753,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, args, span, - &mut err, + err, &mut static_candidates, None, ); @@ -832,23 +764,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, args, span, - &mut err, + err, &mut static_candidates, Some(sugg_span), ); } + static_candidates + } - let mut bound_spans: SortedMap> = Default::default(); + fn suggest_unsatisfied_ty_or_trait( + &self, + err: &mut Diag<'_>, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + item_kind: &str, + source: SelfSource<'tcx>, + unsatisfied_predicates: &UnsatisfiedPredicates<'tcx>, + static_candidates: &[CandidateSource], + ) -> Result<(bool, bool, bool, bool, SortedMap>), ()> { let mut restrict_type_params = false; let mut suggested_derive = false; let mut unsatisfied_bounds = false; - let mut ty_span = match rcvr_ty.kind() { - ty::Param(param_type) => { - Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id())) - } - ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), - _ => None, - }; + let mut custom_span_label = !static_candidates.is_empty(); + let mut bound_spans: SortedMap> = Default::default(); + let tcx = self.tcx; if item_ident.name == sym::count && self.is_slice_ty(rcvr_ty, span) { let msg = "consider using `len` instead"; @@ -873,7 +813,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - return err.emit(); + // Report to emit the diagnostic + return Err(()); } else if !unsatisfied_predicates.is_empty() { if matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in @@ -888,7 +829,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // suggestions. } else { self.handle_unsatisfied_predicates( - &mut err, + err, rcvr_ty, item_ident, item_kind, @@ -936,21 +877,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + Ok(( + restrict_type_params, + suggested_derive, + unsatisfied_bounds, + custom_span_label, + bound_spans, + )) + } - let mut find_candidate_for_method = false; - let should_label_not_found = match source { + fn suggest_surround_method_call( + &self, + err: &mut Diag<'_>, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + source: SelfSource<'tcx>, + similar_candidate: &Option, + ) -> bool { + match source { // If the method name is the name of a field with a function or closure type, // give a helping note that it has to be called as `(x.f)(...)`. SelfSource::MethodCall(expr) => { - !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_ident, &mut err) + !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_ident, err) && similar_candidate.is_none() } _ => true, - }; + } + } + + fn find_possible_candidates_for_method( + &self, + err: &mut Diag<'_>, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + item_kind: &str, + mode: Mode, + source: SelfSource<'tcx>, + no_match_data: &NoMatchData<'tcx>, + expected: Expectation<'tcx>, + should_label_not_found: bool, + custom_span_label: bool, + ) { + let mut find_candidate_for_method = false; + let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; if should_label_not_found && !custom_span_label { self.set_not_found_span_label( - &mut err, + err, rcvr_ty, item_ident, item_kind, @@ -963,7 +938,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if !find_candidate_for_method { self.lookup_segments_chain_for_no_match_method( - &mut err, + err, item_ident, item_kind, source, @@ -975,7 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // can't be called due to `typeof(expr): Clone` not holding. if unsatisfied_predicates.is_empty() { self.suggest_calling_method_on_field( - &mut err, + err, source, span, rcvr_ty, @@ -983,37 +958,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected.only_has_type(self), ); } + } - self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_ident); - - if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params || suggested_derive { - // skip suggesting traits to import - } else { - self.suggest_traits_to_import( - &mut err, - span, - rcvr_ty, - item_ident, - args.map(|args| args.len() + 1), - source, - no_match_data.out_of_scope_traits.clone(), - &static_candidates, - unsatisfied_bounds, - expected.only_has_type(self), - trait_missing_method, - ); - } - - self.suggest_enum_variant_for_method_call( - &mut err, - rcvr_ty, - item_ident, - span, - source, - unsatisfied_predicates, - ); + fn suggest_confusable_or_similarly_named_method( + &self, + err: &mut Diag<'_>, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + mode: Mode, + args: Option<&'tcx [hir::Expr<'tcx>]>, + unsatisfied_predicates: &UnsatisfiedPredicates<'tcx>, + similar_candidate: Option, + ) { let confusable_suggested = self.confusable_method_name( - &mut err, + err, rcvr_ty, item_ident, args.map(|args| { @@ -1033,18 +992,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // and if we aren't in an expansion. && !span.from_expansion() { - self.find_likely_intended_associated_item( - &mut err, - similar_candidate, - span, - args, - mode, - ); + self.find_likely_intended_associated_item(err, similar_candidate, span, args, mode); } } + } + fn suggest_method_not_found_because_of_unsatisfied_bounds( + &self, + err: &mut Diag<'_>, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + item_kind: &str, + bound_spans: SortedMap>, + ) { + let mut ty_span = match rcvr_ty.kind() { + ty::Param(param_type) => { + Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id())) + } + ty::Adt(def, _) if def.did().is_local() => Some(self.tcx.def_span(def.did())), + _ => None, + }; for (span, mut bounds) in bound_spans { - if !tcx.sess.source_map().is_span_accessible(span) { + if !self.tcx.sess.source_map().is_span_accessible(span) { continue; } bounds.sort(); @@ -1077,6 +1046,209 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); } + } + + fn report_no_match_method_error( + &self, + span: Span, + rcvr_ty: Ty<'tcx>, + item_ident: Ident, + expr_id: hir::HirId, + source: SelfSource<'tcx>, + args: Option<&'tcx [hir::Expr<'tcx>]>, + sugg_span: Span, + no_match_data: &mut NoMatchData<'tcx>, + expected: Expectation<'tcx>, + trait_missing_method: bool, + within_macro_span: Option, + ) -> ErrorGuaranteed { + let tcx = self.tcx; + let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); + + if let Err(guar) = rcvr_ty.error_reported() { + return guar; + } + + // We could pass the file for long types into these two, but it isn't strictly necessary + // given how targeted they are. + if let Err(guar) = + self.report_failed_method_call_on_range_end(tcx, rcvr_ty, source, span, item_ident) + { + return guar; + } + + let mut ty_file = None; + let mode = no_match_data.mode; + let is_method = mode == Mode::MethodCall; + let item_kind = if is_method { + "method" + } else if rcvr_ty.is_enum() { + "variant or associated item" + } else { + match (item_ident.as_str().chars().next(), rcvr_ty.is_fresh_ty()) { + (Some(name), false) if name.is_lowercase() => "function or associated item", + (Some(_), false) => "associated item", + (Some(_), true) | (None, false) => "variant or associated item", + (None, true) => "variant", + } + }; + + if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( + tcx, + rcvr_ty, + source, + span, + item_kind, + item_ident, + &mut ty_file, + ) { + return guar; + } + + let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; + let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| { + tcx.is_diagnostic_item(sym::write_macro, def_id) + || tcx.is_diagnostic_item(sym::writeln_macro, def_id) + }) && item_ident.name == sym::write_fmt; + let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { + self.create_missing_writer_err(rcvr_ty, rcvr_expr, ty_file) + } else { + self.create_no_assoc_err( + rcvr_ty, + item_ident, + item_kind, + trait_missing_method, + source, + is_method, + sugg_span, + unsatisfied_predicates, + ) + }; + + self.set_label_for_method_error( + &mut err, + source, + rcvr_ty, + item_ident, + expr_id, + item_ident.span, + sugg_span, + within_macro_span, + args, + ); + + self.suggest_method_call_annotation( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + mode, + source, + expected, + ); + + let static_candidates = self.suggest_static_method_candidates( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + source, + args, + sugg_span, + &no_match_data, + ); + + let Ok(( + restrict_type_params, + suggested_derive, + unsatisfied_bounds, + custom_span_label, + bound_spans, + )) = self.suggest_unsatisfied_ty_or_trait( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + item_kind, + source, + unsatisfied_predicates, + &static_candidates, + ) + else { + return err.emit(); + }; + + let similar_candidate = no_match_data.similar_candidate; + let should_label_not_found = self.suggest_surround_method_call( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + source, + &similar_candidate, + ); + + self.find_possible_candidates_for_method( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + item_kind, + mode, + source, + no_match_data, + expected, + should_label_not_found, + custom_span_label, + ); + + self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_ident); + + if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params || suggested_derive { + // skip suggesting traits to import + } else { + self.suggest_traits_to_import( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + args.map(|args| args.len() + 1), + source, + no_match_data.out_of_scope_traits.clone(), + &static_candidates, + unsatisfied_bounds, + expected.only_has_type(self), + trait_missing_method, + ); + } + + self.suggest_enum_variant_for_method_call( + &mut err, + rcvr_ty, + item_ident, + item_ident.span, + source, + unsatisfied_predicates, + ); + + self.suggest_confusable_or_similarly_named_method( + &mut err, + item_ident.span, + rcvr_ty, + item_ident, + mode, + args, + unsatisfied_predicates, + similar_candidate, + ); + + self.suggest_method_not_found_because_of_unsatisfied_bounds( + &mut err, + rcvr_ty, + item_ident, + item_kind, + bound_spans, + ); self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_ident, expected); self.suggest_bounds_for_range_to_method(&mut err, source, item_ident); diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 4597439e269ff..2643d78990e57 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -74,7 +74,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { } // delete comparison statement if it the value being switched on was moved, which means - // it can not be user later on + // it can not be used later on if opt.can_remove_bin_op_stmt { bb.statements[opt.bin_op_stmt_idx].make_nop(true); } else { 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 4ecd56dfa40b6..d27d80a086ad1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -74,6 +74,8 @@ where /// Consider a clause specifically for a `dyn Trait` self type. This requires /// additionally checking all of the supertraits and object bounds to hold, /// since they're not implied by the well-formedness of the object type. + /// `NormalizesTo` overrides this to not check the supertraits for backwards + /// compatibility with the old solver. cc trait-system-refactor-initiative#245. fn probe_and_consider_object_bound_candidate( ecx: &mut EvalCtxt<'_, D>, source: CandidateSource, 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 794bda7726a4a..c65e0bb25897c 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 @@ -184,6 +184,20 @@ where then(ecx) } + // Hack for trait-system-refactor-initiative#245. + // FIXME(-Zhigher-ranked-assumptions): this impl differs from trait goals and we should unify + // them again once we properly support binders. + fn probe_and_consider_object_bound_candidate( + ecx: &mut EvalCtxt<'_, D>, + source: CandidateSource, + goal: Goal, + assumption: I::Clause, + ) -> Result, NoSolution> { + Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + fn consider_additional_alias_assumptions( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index e40fc04d76645..4880a79ea9cf8 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -882,11 +882,11 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { DefPathData::OpaqueTy => 'i', DefPathData::SyntheticCoroutineBody => 's', DefPathData::NestedStatic => 'n', + DefPathData::GlobalAsm => 'a', // These should never show up as `print_path_with_simple` arguments. DefPathData::CrateRoot | DefPathData::Use - | DefPathData::GlobalAsm | DefPathData::Impl | DefPathData::MacroNs(_) | DefPathData::LifetimeNs(_) diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index b111dc0bd18f3..a9dd6e531c5d3 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -7,7 +7,6 @@ #![feature(compiler_builtins)] #![feature(core_intrinsics)] #![feature(linkage)] -#![feature(asm_cfg)] #![feature(naked_functions)] #![feature(repr_simd)] #![feature(macro_metavar_expr_concat)] diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 1e211ae66e79c..6c71e2216a71b 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -376,14 +376,10 @@ impl fmt::Debug for OnceCell { impl Clone for OnceCell { #[inline] fn clone(&self) -> OnceCell { - let res = OnceCell::new(); - if let Some(value) = self.get() { - match res.set(value.clone()) { - Ok(()) => (), - Err(_) => unreachable!(), - } + match self.get() { + Some(value) => OnceCell::from(value.clone()), + None => OnceCell::new(), } - res } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 9c8e599104be4..8740b5935973c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2020,13 +2020,11 @@ fn render_impl( let mut methods = Vec::new(); if !impl_.is_negative_trait_impl() { - for trait_item in &impl_.items { - match trait_item.kind { - clean::MethodItem(..) | clean::RequiredMethodItem(_) => { - methods.push(trait_item) - } + for impl_item in &impl_.items { + match impl_item.kind { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => methods.push(impl_item), clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { - assoc_types.push(trait_item) + assoc_types.push(impl_item) } clean::RequiredAssocConstItem(..) | clean::ProvidedAssocConstItem(_) @@ -2036,7 +2034,7 @@ fn render_impl( &mut default_impl_items, &mut impl_items, cx, - trait_item, + impl_item, if trait_.is_some() { &i.impl_item } else { parent }, link, render_mode, diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 8b6776ffa4b8c..9a8df53931394 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -582,18 +582,14 @@ impl TypeAliasPart { if let Some(ret) = &mut ret { ret.aliases.push(type_alias_fqp); } else { - let target_did = impl_ - .inner_impl() - .trait_ - .as_ref() - .map(|trait_| trait_.def_id()) - .or_else(|| impl_.inner_impl().for_.def_id(&cx.shared.cache)); + let target_trait_did = + impl_.inner_impl().trait_.as_ref().map(|trait_| trait_.def_id()); let provided_methods; - let assoc_link = if let Some(target_did) = target_did { + let assoc_link = if let Some(target_trait_did) = target_trait_did { provided_methods = impl_.inner_impl().provided_trait_methods(cx.tcx()); AssocItemLink::GotoSource( - ItemId::DefId(target_did), + ItemId::DefId(target_trait_did), &provided_methods, ) } else { diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index c0771583ab658..0ee2a66d4b689 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -786,3 +786,13 @@ pub mod tooltips { Vec::new() } } + +pub mod tyalias { + pub struct X(pub T); + + impl X { + pub fn blob(&self) {} + } + + pub type Y = X; +} diff --git a/tests/rustdoc-gui/type-alias.goml b/tests/rustdoc-gui/type-alias.goml new file mode 100644 index 0000000000000..a07f1b4eb8147 --- /dev/null +++ b/tests/rustdoc-gui/type-alias.goml @@ -0,0 +1,7 @@ +// This test ensures that we correctly generate links to methods on type aliases. +go-to: "file://" + |DOC_PATH| + "/test_docs/tyalias/type.Y.html" + +// It's generated with JS so we need to wait for it to be done generating. +wait-for: "#implementations" +// We check that it's "#method." and not "#tymethod.". +assert-text: ('#method\.blob a.fn[href="#method.blob"]', "blob") diff --git a/tests/ui/asm/cfg-parse-error.rs b/tests/ui/asm/cfg-parse-error.rs index 9b79d16a76dda..0c6b63872a432 100644 --- a/tests/ui/asm/cfg-parse-error.rs +++ b/tests/ui/asm/cfg-parse-error.rs @@ -1,5 +1,4 @@ //@ needs-asm-support -#![feature(asm_cfg)] use std::arch::asm; diff --git a/tests/ui/asm/cfg-parse-error.stderr b/tests/ui/asm/cfg-parse-error.stderr index 8a70d39a43dc6..726dee271108f 100644 --- a/tests/ui/asm/cfg-parse-error.stderr +++ b/tests/ui/asm/cfg-parse-error.stderr @@ -1,5 +1,5 @@ error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/cfg-parse-error.rs:16:13 + --> $DIR/cfg-parse-error.rs:15:13 | LL | a = out(reg) x, | - expected one of 11 possible tokens @@ -7,7 +7,7 @@ LL | "", | ^^ unexpected token error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/cfg-parse-error.rs:26:13 + --> $DIR/cfg-parse-error.rs:25:13 | LL | }, | - expected one of 11 possible tokens @@ -15,19 +15,19 @@ LL | "", | ^^ unexpected token error: expected token: `,` - --> $DIR/cfg-parse-error.rs:41:26 + --> $DIR/cfg-parse-error.rs:40:26 | LL | a = out(reg) x, | ^ expected `,` error: this attribute is not supported on assembly - --> $DIR/cfg-parse-error.rs:47:13 + --> $DIR/cfg-parse-error.rs:46:13 | LL | #[rustfmt::skip] | ^^^^^^^^^^^^^^^^ error: an inner attribute is not permitted in this context - --> $DIR/cfg-parse-error.rs:53:13 + --> $DIR/cfg-parse-error.rs:52:13 | LL | #![rustfmt::skip] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/cfg.rs b/tests/ui/asm/cfg.rs index bcf86340b9d8a..90b1b3d6ee650 100644 --- a/tests/ui/asm/cfg.rs +++ b/tests/ui/asm/cfg.rs @@ -3,7 +3,7 @@ //@ revisions: reva revb //@ only-x86_64 //@ run-pass -#![feature(asm_cfg, cfg_select)] +#![feature(cfg_select)] use std::arch::{asm, naked_asm}; diff --git a/tests/ui/feature-gates/feature-gate-asm_cfg.rs b/tests/ui/feature-gates/feature-gate-asm_cfg.rs deleted file mode 100644 index ef8bf75b6929d..0000000000000 --- a/tests/ui/feature-gates/feature-gate-asm_cfg.rs +++ /dev/null @@ -1,48 +0,0 @@ -//@ only-x86_64 -#![crate_type = "lib"] - -use std::arch::{asm, global_asm, naked_asm}; - -global_asm!( - "nop", - #[cfg(false)] - //~^ ERROR the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - "nop" -); - -#[unsafe(naked)] -#[no_mangle] -extern "C" fn naked() { - naked_asm!( - "mov rax, 5", - #[cfg(false)] - //~^ ERROR the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - "mov rax, {a}", - "ret", - #[cfg(false)] - //~^ ERROR the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - a = const 10, - ) -} - -fn asm() { - unsafe { - asm!( - "nop", - #[cfg(false)] - //~^ ERROR the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - clobber_abi("C"), - clobber_abi("C"), //~ ERROR `C` ABI specified multiple times - ); - } -} - -fn bad_attribute() { - unsafe { - asm!( - #[inline] - //~^ ERROR this attribute is not supported on assembly - "nop" - ) - }; -} diff --git a/tests/ui/feature-gates/feature-gate-asm_cfg.stderr b/tests/ui/feature-gates/feature-gate-asm_cfg.stderr deleted file mode 100644 index e92d1e8c48747..0000000000000 --- a/tests/ui/feature-gates/feature-gate-asm_cfg.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0658]: the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - --> $DIR/feature-gate-asm_cfg.rs:8:5 - | -LL | #[cfg(false)] - | ^^^^^^^^^^^^^ - | - = note: see issue #140364 for more information - = help: add `#![feature(asm_cfg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - --> $DIR/feature-gate-asm_cfg.rs:18:9 - | -LL | #[cfg(false)] - | ^^^^^^^^^^^^^ - | - = note: see issue #140364 for more information - = help: add `#![feature(asm_cfg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - --> $DIR/feature-gate-asm_cfg.rs:22:9 - | -LL | #[cfg(false)] - | ^^^^^^^^^^^^^ - | - = note: see issue #140364 for more information - = help: add `#![feature(asm_cfg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[cfg(/* ... */)]` and `#[cfg_attr(/* ... */)]` attributes on assembly are unstable - --> $DIR/feature-gate-asm_cfg.rs:32:13 - | -LL | #[cfg(false)] - | ^^^^^^^^^^^^^ - | - = note: see issue #140364 for more information - = help: add `#![feature(asm_cfg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: this attribute is not supported on assembly - --> $DIR/feature-gate-asm_cfg.rs:43:13 - | -LL | #[inline] - | ^^^^^^^^^ - -error: `C` ABI specified multiple times - --> $DIR/feature-gate-asm_cfg.rs:35:13 - | -LL | clobber_abi("C"), - | ---------------- previously specified here -LL | clobber_abi("C"), - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/static/extern-static-normalization-failure-issue-148161.rs b/tests/ui/static/extern-static-normalization-failure-issue-148161.rs new file mode 100644 index 0000000000000..2995c3ed2ec72 --- /dev/null +++ b/tests/ui/static/extern-static-normalization-failure-issue-148161.rs @@ -0,0 +1,21 @@ +// Regression test for https://github.com/rust-lang/rust/issues/148161 +trait Trait { + type Assoc; +} + +impl Trait for u8 { + type Assoc = i8; +} + +struct Struct { + member: T::Assoc, +} + +unsafe extern "C" { + // This used to be an ICE due to normalization failure on ` as Trait>::Assoc` + // while wf checking this static item. + static VAR: Struct; + //~^ ERROR: the trait bound `i8: Trait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr b/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr new file mode 100644 index 0000000000000..e2c7d30e2e434 --- /dev/null +++ b/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i8: Trait` is not satisfied + --> $DIR/extern-static-normalization-failure-issue-148161.rs:17:17 + | +LL | static VAR: Struct; + | ^^^^^^^^^^ the trait `Trait` is not implemented for `i8` + | +help: the trait `Trait` is implemented for `u8` + --> $DIR/extern-static-normalization-failure-issue-148161.rs:6:1 + | +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `Struct` + --> $DIR/extern-static-normalization-failure-issue-148161.rs:10:18 + | +LL | struct Struct { + | ^^^^^ required by this bound in `Struct` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/symbol-names/const-in-global-asm.rs b/tests/ui/symbol-names/const-in-global-asm.rs new file mode 100644 index 0000000000000..16aa15d9a2994 --- /dev/null +++ b/tests/ui/symbol-names/const-in-global-asm.rs @@ -0,0 +1,20 @@ +//@ build-pass +//@ compile-flags: -Clink-dead-code +//@ needs-asm-support + +#![allow(unused)] + +// Test that a symbol in a `global_asm` namespace doesn't cause an ICE during v0 symbol mangling +// due to a lack of missing namespace character for `global_asm`. +// +// FIXME: Can't use `#[rustc_symbol_name]` on the `foo` call to check its symbol, so just checking +// the test compiles. + +fn foo() {} + +core::arch::global_asm!("/* {} */", sym foo::<{ + || {}; + 0 +}>); + +fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs b/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs new file mode 100644 index 0000000000000..9b13b78d024b4 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs @@ -0,0 +1,39 @@ +//@ check-pass +//@ compile-flags: -Znext-solver +//@ edition: 2024 + +// A regression test for trait-system-refactor-initiative#245. +// The old solver doesn't check the supertraits of the principal trait +// when considering object candidate for normalization. +// And the new solver previously did, resulting in a placeholder error +// while normalizing inside of a generator witness. + +trait AsyncFn: Send + 'static { + type Fut: Future + Send; + + fn call(&self) -> Self::Fut; +} + +type BoxFuture<'a, T> = std::pin::Pin + Send + 'a>>; +type DynAsyncFnBoxed = dyn AsyncFn>; + +fn wrap_call(func: Box

) -> impl Future { + func.call() +} + +fn get_boxed_fn() -> Box { + todo!() +} + +async fn cursed_fut() { + wrap_call(get_boxed_fn()).await; +} + +fn observe_fut_not_send() { + fn assert_send(t: T) -> T { + t + } + assert_send(cursed_fut()); +} + +fn main() {}