diff options
| author | bors <bors@rust-lang.org> | 2024-03-01 19:06:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-01 19:06:39 +0000 |
| commit | 2dceda4f32b97f60b122f2b32491e0267ef5cc0c (patch) | |
| tree | 4989e8c8638ecb5f15eb0f2435bc8fa4dc1d634c /compiler | |
| parent | 17edacef07e8afc3b580ed8feead6c5e90d24a56 (diff) | |
| parent | ff22925e500e767ffcc5485d006174f7d74e21f0 (diff) | |
| download | rust-2dceda4f32b97f60b122f2b32491e0267ef5cc0c.tar.gz rust-2dceda4f32b97f60b122f2b32491e0267ef5cc0c.zip | |
Auto merge of #121859 - matthiaskrgr:rollup-i724wpm, r=matthiaskrgr
Rollup of 12 pull requests Successful merges: - #120646 (Fix incorrect suggestion for uninitialized binding in pattern) - #121416 (Improve error messages for generics with default parameters) - #121475 (Add tidy check for .stderr/.stdout files for non-existent test revisions) - #121580 (make unused_imports less assertive in test modules) - #121736 (Remove `Mutex::unlock` Function) - #121784 (Make the success arms of `if lhs || rhs` meet up in a separate block) - #121818 (CFI: Remove unused `typeid_for_fnsig`) - #121819 (Handle stashing of delayed bugs) - #121828 (Remove unused fluent messages) - #121831 (Fix typo in comment) - #121850 (Make `ZeroablePrimitive` trait unsafe.) - #121853 (normalizes-to: handle negative impls) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/messages.ftl | 6 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 50 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/lint.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context/diagnostics.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/generics.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/known_panics_lint.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 22 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/typeid.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs | 19 |
15 files changed, 109 insertions, 132 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1e869ae924f..0776f455efd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -613,7 +613,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if self.sugg_span.is_some() { return; } - if let hir::StmtKind::Local(hir::Local { span, ty, init: None, .. }) = &ex.kind + + // FIXME: We make sure that this is a normal top-level binding, + // but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern + if let hir::StmtKind::Local(hir::Local { span, ty, init: None, pat, .. }) = + &ex.kind + && let hir::PatKind::Binding(..) = pat.kind && span.contains(self.decl_span) { self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span)); diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index dda466b026d..bc2a9d5ad1e 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -221,12 +221,6 @@ builtin_macros_requires_cfg_pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required -builtin_macros_should_panic = functions using `#[should_panic]` must return `()` - -builtin_macros_test_arg_non_lifetime = functions used as tests can not have any non-lifetime generic parameters - -builtin_macros_test_args = functions used as tests can not have any arguments - builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests .label = `{$kind}` because of this diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0a533833e64..6b1ccbc5f7c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -712,6 +712,7 @@ impl DiagCtxt { /// Stashes a diagnostic for possible later improvement in a different, /// later stage of the compiler. Possible actions depend on the diagnostic /// level: + /// - Level::Bug, Level:Fatal: not allowed, will trigger a panic. /// - Level::Error: immediately counted as an error that has occurred, because it /// is guaranteed to be emitted eventually. Can be later accessed with the /// provided `span` and `key` through @@ -719,26 +720,39 @@ impl DiagCtxt { /// [`DiagCtxt::try_steal_replace_and_emit_err`]. These do not allow /// cancellation or downgrading of the error. Returns /// `Some(ErrorGuaranteed)`. + /// - Level::DelayedBug: this does happen occasionally with errors that are + /// downgraded to delayed bugs. It is not stashed, but immediately + /// emitted as a delayed bug. This is because stashing it would cause it + /// to be counted by `err_count` which we don't want. It doesn't matter + /// that we cannot steal and improve it later, because it's not a + /// user-facing error. Returns `Some(ErrorGuaranteed)` as is normal for + /// delayed bugs. /// - Level::Warning and lower (i.e. !is_error()): can be accessed with the /// provided `span` and `key` through [`DiagCtxt::steal_non_err()`]. This /// allows cancelling and downgrading of the diagnostic. Returns `None`. - /// - Others: not allowed, will trigger a panic. pub fn stash_diagnostic( &self, span: Span, key: StashKey, diag: DiagInner, ) -> Option<ErrorGuaranteed> { - let guar = if diag.level() == Level::Error { - // This `unchecked_error_guaranteed` is valid. It is where the - // `ErrorGuaranteed` for stashed errors originates. See - // `DiagCtxtInner::drop`. - #[allow(deprecated)] - Some(ErrorGuaranteed::unchecked_error_guaranteed()) - } else if !diag.is_error() { - None - } else { - self.span_bug(span, format!("invalid level in `stash_diagnostic`: {}", diag.level)); + let guar = match diag.level { + Bug | Fatal => { + self.span_bug( + span, + format!("invalid level in `stash_diagnostic`: {:?}", diag.level), + ); + } + Error => { + // This `unchecked_error_guaranteed` is valid. It is where the + // `ErrorGuaranteed` for stashed errors originates. See + // `DiagCtxtInner::drop`. + #[allow(deprecated)] + Some(ErrorGuaranteed::unchecked_error_guaranteed()) + } + DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), + ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow + | Expect(_) => None, }; // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic @@ -780,11 +794,11 @@ impl DiagCtxt { let err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); err.map(|(err, guar)| { // The use of `::<ErrorGuaranteed>` is safe because level is `Level::Error`. - assert_eq!(err.level, Level::Error); + assert_eq!(err.level, Error); assert!(guar.is_some()); let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err); modify_err(&mut err); - assert_eq!(err.level, Level::Error); + assert_eq!(err.level, Error); err.emit() }) } @@ -803,7 +817,7 @@ impl DiagCtxt { let old_err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); match old_err { Some((old_err, guar)) => { - assert_eq!(old_err.level, Level::Error); + assert_eq!(old_err.level, Error); assert!(guar.is_some()); // Because `old_err` has already been counted, it can only be // safely cancelled because the `new_err` supplants it. @@ -1367,7 +1381,7 @@ impl DiagCtxtInner { } if diagnostic.has_future_breakage() { - // Future breakages aren't emitted if they're Level::Allow, + // Future breakages aren't emitted if they're `Level::Allow`, // but they still need to be constructed and stashed below, // so they'll trigger the must_produce_diag check. self.suppressed_expected_diag = true; @@ -1453,7 +1467,7 @@ impl DiagCtxtInner { diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); if already_emitted { let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`"; - diagnostic.sub(Level::Note, msg, MultiSpan::new()); + diagnostic.sub(Note, msg, MultiSpan::new()); } if is_error { @@ -1623,7 +1637,7 @@ impl DiagCtxtInner { bug.arg("level", bug.level); let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level; let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call - bug.sub(Level::Note, msg, bug.span.primary_span().unwrap().into()); + bug.sub(Note, msg, bug.span.primary_span().unwrap().into()); } bug.level = Bug; @@ -1671,7 +1685,7 @@ impl DelayedDiagInner { diag.arg("emitted_at", diag.emitted_at.clone()); diag.arg("note", self.note); let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); // after the `arg` calls - diag.sub(Level::Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into()); + diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into()); diag } } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 89cd37e757f..e376411cd95 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -239,8 +239,6 @@ hir_analysis_missing_one_of_trait_item = not all trait items implemented, missin .label = missing one of `{$missing_items_msg}` in implementation .note = required because of this annotation -hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization - hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}` .label = missing `{$missing_items_msg}` in implementation diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 227254b4cc8..fb5f3426cea 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -1,5 +1,5 @@ use rustc_ast::TraitObjectSyntax; -use rustc_errors::{codes::*, Diag, EmissionGuarantee, Level, StashKey}; +use rustc_errors::{codes::*, Diag, EmissionGuarantee, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability}; @@ -237,15 +237,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // check if the impl trait that we are considering is a impl of a local trait self.maybe_lint_blanket_trait_impl(self_ty, &mut diag); - match diag.level() { - Level::Error => { - diag.stash(self_ty.span, StashKey::TraitMissingMethod); - } - Level::DelayedBug => { - diag.emit(); - } - _ => unreachable!(), - } + diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1cf990fef04..af1aa346c09 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1247,10 +1247,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { let did1 = def1.did(); let did2 = def2.did(); - let sub_no_defaults_1 = - self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1); - let sub_no_defaults_2 = - self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2); + + let generics1 = self.tcx.generics_of(did1); + let generics2 = self.tcx.generics_of(did2); + + let non_default_after_default = generics1 + .check_concrete_type_after_default(self.tcx, sub1) + || generics2.check_concrete_type_after_default(self.tcx, sub2); + let sub_no_defaults_1 = if non_default_after_default { + generics1.own_args(sub1) + } else { + generics1.own_args_no_defaults(self.tcx, sub1) + }; + let sub_no_defaults_2 = if non_default_after_default { + generics2.own_args(sub2) + } else { + generics2.own_args_no_defaults(self.tcx, sub2) + }; let mut values = (DiagStyledString::new(), DiagStyledString::new()); let path1 = self.tcx.def_path_str(did1); let path2 = self.tcx.def_path_str(did2); diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 14e4c79563b..728996f0741 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -104,7 +104,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiagnostics, diag: if let Some(span) = in_test_module { diag.span_help( sess.source_map().guess_head_span(span), - "consider adding a `#[cfg(test)]` to the containing module", + "if this is a test module, consider adding a `#[cfg(test)]` to the containing module", ); } } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index c81d9dfbc7d..2630b96869b 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -360,6 +360,30 @@ impl<'tcx> Generics { let own = &args[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { own } } + + /// Returns true if a concrete type is specified after a default type. + /// For example, consider `struct T<W = usize, X = Vec<W>>(W, X)` + /// `T<usize, String>` will return true + /// `T<usize>` will return false + pub fn check_concrete_type_after_default( + &'tcx self, + tcx: TyCtxt<'tcx>, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + let mut default_param_seen = false; + for param in self.params.iter() { + if let Some(inst) = + param.default_value(tcx).map(|default| default.instantiate(tcx, args)) + { + if inst == args[param.index as usize] { + default_param_seen = true; + } else if default_param_seen { + return true; + } + } + } + false + } } /// Bounds on generics. diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 641a278c1d3..6cdb78d1a94 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -93,8 +93,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { variable_source_info, true, )); - this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block); - rhs_success_block.unit() + + // Make the LHS and RHS success arms converge to a common block. + // (We can't just make LHS goto RHS, because `rhs_success_block` + // might contain statements that we don't want on the LHS path.) + let success_block = this.cfg.start_new_block(); + this.cfg.goto(lhs_success_block, variable_source_info, success_block); + this.cfg.goto(rhs_success_block, variable_source_info, success_block); + success_block.unit() } ExprKind::Unary { op: UnOp::Not, arg } => { let local_scope = this.local_scope(); diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 7cab6650994..27477769cef 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -586,7 +586,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } Aggregate(ref kind, ref fields) => { - // Do not const pop union fields as they can be + // Do not const prop union fields as they can be // made to produce values that don't match their // underlying layout's type (see ICE #121534). // If the last element of the `Adt` tuple diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 55baf6f9f2e..60cc138fd7b 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -284,9 +284,6 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}` parse_function_body_equals_expr = function body cannot be `= expression;` .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;` -parse_gen_fn = `gen` functions are not yet implemented - .help = for now you can use `gen {"{}"}` blocks and return `impl Iterator` instead - parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 0747685c35c..fa98338bbb6 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -8,10 +8,6 @@ resolve_add_as_non_derive = resolve_added_macro_use = have you added the `#[macro_use]` on the module/import? -resolve_ampersand_used_without_explicit_lifetime_name = - `&` without an explicit lifetime name cannot be used here - .note = explicit lifetime name needed here - resolve_ancestor_only = visibilities can only be restricted to ancestor modules @@ -100,12 +96,6 @@ resolve_const_param_in_non_trivial_anon_const = resolve_const_param_in_ty_of_const_param = const parameters may not be used in the type of const parameters -resolve_crate_may_not_be_imported = - `$crate` may not be imported - -resolve_crate_root_imports_must_be_named_explicitly = - crate root imports need to be explicitly named: `use crate as name;` - resolve_expected_found = expected module, found {$res} `{$path_str}` .label = not a module @@ -220,9 +210,6 @@ resolve_param_in_ty_of_const_param = the type of const parameters must not depend on other generic parameters .label = the type must not depend on the parameter `{$name}` -resolve_parent_module_reset_for_binding = - parent module is reset for binding - resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it .help = you can define integration tests in a directory named `tests` @@ -270,11 +257,6 @@ resolve_trait_impl_duplicate = .old_span_label = previous definition here .trait_item_span = item in trait -resolve_trait_impl_mismatch = - item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` - .label = does not match trait - .label_trait_item = item in trait - resolve_try_using_similarly_named_label = try using similarly named label @@ -295,10 +277,6 @@ resolve_undeclared_label = use of undeclared label `{$name}` .label = undeclared label `{$name}` -resolve_underscore_lifetime_name_cannot_be_used_here = - `'_` cannot be used here - .note = `'_` is a reserved lifetime name - resolve_unexpected_res_change_ty_to_const_param_sugg = you might have meant to write a const parameter here diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 838d9d774b2..e8763e49e62 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -4,13 +4,13 @@ /// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, /// see design document in the tracking issue #89653. use bitflags::bitflags; -use rustc_middle::ty::{FnSig, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{Instance, Ty, TyCtxt}; use rustc_target::abi::call::FnAbi; use std::hash::Hasher; use twox_hash::XxHash64; bitflags! { - /// Options for typeid_for_fnabi and typeid_for_fnsig. + /// Options for typeid_for_fnabi. #[derive(Clone, Copy, Debug)] pub struct TypeIdOptions: u32 { const GENERALIZE_POINTERS = 1; @@ -30,15 +30,6 @@ pub fn typeid_for_fnabi<'tcx>( typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options) } -/// Returns a type metadata identifier for the specified FnSig. -pub fn typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> String { - typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options) -} - /// Returns a type metadata identifier for the specified Instance. pub fn typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, @@ -61,19 +52,6 @@ pub fn kcfi_typeid_for_fnabi<'tcx>( hash.finish() as u32 } -/// Returns a KCFI type metadata identifier for the specified FnSig. -pub fn kcfi_typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> u32 { - // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the - // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) - let mut hash: XxHash64 = Default::default(); - hash.write(typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options).as_bytes()); - hash.finish() as u32 -} - /// Returns a KCFI type metadata identifier for the specified Instance. pub fn kcfi_typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index b5b3aa27060..87422042180 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1074,41 +1074,6 @@ pub fn typeid_for_fnabi<'tcx>( typeid } -/// Returns a type metadata identifier for the specified FnSig using the Itanium C++ ABI with vendor -/// extended type qualifiers and types for Rust types that are not used at the FFI boundary. -pub fn typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> String { - // A name is mangled by prefixing "_Z" to an encoding of its name, and in the case of functions - // its type. - let mut typeid = String::from("_Z"); - - // Clang uses the Itanium C++ ABI's virtual tables and RTTI typeinfo structure name as type - // metadata identifiers for function pointers. The typeinfo name encoding is a two-character - // code (i.e., 'TS') prefixed to the type encoding for the function. - typeid.push_str("TS"); - - // A dictionary of substitution candidates used for compression (see - // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression). - let mut dict: FxHashMap<DictKey<'tcx>, usize> = FxHashMap::default(); - - // Encode the function signature - typeid.push_str(&encode_fnsig(tcx, fn_sig, &mut dict, options)); - - // Add encoding suffixes - if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { - typeid.push_str(".normalized"); - } - - if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) { - typeid.push_str(".generalized"); - } - - typeid -} - /// Returns a type metadata identifier for the specified Instance using the Itanium C++ ABI with /// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary. pub fn typeid_for_instance<'tcx>( diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 3aba5c85abc..248985715c2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -162,15 +162,28 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let tcx = ecx.tcx(); let goal_trait_ref = goal.predicate.alias.trait_ref(tcx); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; - if !drcx.args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args) { + if !drcx.args_may_unify( + goal.predicate.trait_ref(tcx).args, + impl_trait_header.skip_binder().trait_ref.args, + ) { return Err(NoSolution); } + // We have to ignore negative impls when projecting. + let impl_polarity = impl_trait_header.skip_binder().polarity; + match impl_polarity { + ty::ImplPolarity::Negative => return Err(NoSolution), + ty::ImplPolarity::Reservation => { + unimplemented!("reservation impl for trait with assoc item: {:?}", goal) + } + ty::ImplPolarity::Positive => {} + }; + ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id); - let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args); + let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref; ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; |
