about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-04 20:46:48 +0000
committerbors <bors@rust-lang.org>2024-05-04 20:46:48 +0000
commite82c861d7e5ecd766cb0dab0bf622445dec999dc (patch)
treeec1874052c44491c598be8bb8cb231932ccc8e1b /compiler
parentd568423a7a4ddb4b49323d96078a22f94df55fbd (diff)
parente1867404a81524b64147c6e1bb90bb044fd7b9d3 (diff)
Auto merge of #124726 - matthiaskrgr:rollup-m6i3day, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #124501 (add support to override lldb binary path for ./x test)
 - #124573 (add a reference link to the comment of the "cc" and "cmake".)
 - #124663 (Enable reusing CI Docker cache when running CI images locally)
 - #124690 (Only consider ambiguous goals when finding best obligation for ambiguities)
 - #124713 (Update Cargo specific diagnostics in check-cfg)
 - #124717 (Implement `do_not_recommend` in the new solver)
 - #124718 (Record impl args in the proof tree)
 - #124720 (interpret: Drop: always evaluate place)
 - #124721 (library/std: Fix build for NetBSD targets with 32-bit `c_long`)
 - #124723 (Use correct Hermit links in The `rustc` Book)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs15
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_lint/src/context/diagnostics/check_cfg.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs29
6 files changed, 42 insertions, 24 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index be5458523d1..26e429034dc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -540,7 +540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     //                \-------/
                     //
                     let virtual_drop = Instance {
-                        def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
+                        def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
                         args: drop_fn.args,
                     };
                     debug!("ty = {:?}", ty);
@@ -581,7 +581,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     //
                     // SO THEN WE CAN USE THE ABOVE CODE.
                     let virtual_drop = Instance {
-                        def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
+                        def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
                         args: drop_fn.args,
                     };
                     debug!("ty = {:?}", ty);
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 07425f9a686..b474003087b 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -169,10 +169,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             Drop { place, target, unwind, replace: _ } => {
-                let frame = self.frame();
-                let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
-                let ty = self.instantiate_from_frame_and_normalize_erasing_regions(frame, ty)?;
-                let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
+                let place = self.eval_place(place)?;
+                let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
                 if let ty::InstanceDef::DropGlue(_, None) = instance.def {
                     // This is the branch we enter if and only if the dropped type has no drop glue
                     // whatsoever. This can happen as a result of monomorphizing a drop of a
@@ -181,8 +179,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     self.go_to_block(target);
                     return Ok(());
                 }
-                let place = self.eval_place(place)?;
-                trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
+                trace!("TerminatorKind::drop: {:?}, type {}", place, place.layout.ty);
                 self.drop_in_place(&place, instance, target, unwind)?;
             }
 
@@ -952,6 +949,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // implementation fail -- a problem shared by rustc.
         let place = self.force_allocation(place)?;
 
+        // We behave a bit different from codegen here.
+        // Codegen creates an `InstanceDef::Virtual` with index 0 (the slot of the drop method) and
+        // then dispatches that to the normal call machinery. However, our call machinery currently
+        // only supports calling `VtblEntry::Method`; it would choke on a `MetadataDropInPlace`. So
+        // instead we do the virtual call stuff ourselves. It's easier here than in `eval_fn_call`
+        // since we can just get a place of the underlying type and use `mplace_to_ref`.
         let place = match place.layout.ty.kind() {
             ty::Dynamic(data, _, ty::Dyn) => {
                 // Dropping a trait object. Need to find actual drop fn.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 9c33cc8ed0b..dbb88e42a3e 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -518,7 +518,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // RFC 2397
     gated!(
         do_not_recommend, Normal, template!(Word), WarnFollowing,
-        EncodeCrossCrate::No, experimental!(do_not_recommend)
+        EncodeCrossCrate::Yes, experimental!(do_not_recommend)
     ),
 
     // `#[cfi_encoding = ""]`
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
index e9a6276192e..3c423b4e2aa 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
@@ -164,9 +164,9 @@ pub(super) fn unexpected_cfg_name(
 
     if is_from_cargo {
         if !is_feature_cfg {
-            diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
+            diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo::rustc-check-cfg={inst}\");` to the top of the `build.rs`"));
         }
-        diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
+        diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration");
     } else {
         diag.help(format!("to expect this configuration use `--check-cfg={inst}`"));
         diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration");
@@ -266,9 +266,9 @@ pub(super) fn unexpected_cfg_value(
                 diag.help("consider defining some features in `Cargo.toml`");
             }
         } else if !is_cfg_a_well_know_name {
-            diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
+            diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo::rustc-check-cfg={inst}\");` to the top of the `build.rs`"));
         }
-        diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
+        diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration");
     } else {
         if !is_cfg_a_well_know_name {
             diag.help(format!("to expect this configuration use `--check-cfg={inst}`"));
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index bae1c6b6011..773babde0d7 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -888,8 +888,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         self.infcx.resolve_vars_if_possible(value)
     }
 
-    pub(super) fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
-        self.infcx.fresh_args_for_item(DUMMY_SP, def_id)
+    pub(super) fn fresh_args_for_item(&mut self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
+        let args = self.infcx.fresh_args_for_item(DUMMY_SP, def_id);
+        for arg in args {
+            self.inspect.add_var_value(arg);
+        }
+        args
     }
 
     pub(super) fn translate_args(
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 796222129f1..fd4b5805f02 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -11,6 +11,7 @@ use rustc_infer::traits::{
 };
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::symbol::sym;
 
 use super::eval_ctxt::GenerateProofTree;
 use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
@@ -137,7 +138,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
             .collect();
 
         errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError {
-            obligation: find_best_leaf_obligation(infcx, &obligation),
+            obligation: find_best_leaf_obligation(infcx, &obligation, true),
             code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
             root_obligation: obligation,
         }));
@@ -198,7 +199,7 @@ fn fulfillment_error_for_no_solution<'tcx>(
     infcx: &InferCtxt<'tcx>,
     root_obligation: PredicateObligation<'tcx>,
 ) -> FulfillmentError<'tcx> {
-    let obligation = find_best_leaf_obligation(infcx, &root_obligation);
+    let obligation = find_best_leaf_obligation(infcx, &root_obligation, false);
 
     let code = match obligation.predicate.kind().skip_binder() {
         ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
@@ -266,7 +267,7 @@ fn fulfillment_error_for_stalled<'tcx>(
     });
 
     FulfillmentError {
-        obligation: find_best_leaf_obligation(infcx, &obligation),
+        obligation: find_best_leaf_obligation(infcx, &obligation, true),
         code,
         root_obligation: obligation,
     }
@@ -275,12 +276,13 @@ fn fulfillment_error_for_stalled<'tcx>(
 fn find_best_leaf_obligation<'tcx>(
     infcx: &InferCtxt<'tcx>,
     obligation: &PredicateObligation<'tcx>,
+    consider_ambiguities: bool,
 ) -> PredicateObligation<'tcx> {
     let obligation = infcx.resolve_vars_if_possible(obligation.clone());
     infcx
         .visit_proof_tree(
             obligation.clone().into(),
-            &mut BestObligation { obligation: obligation.clone() },
+            &mut BestObligation { obligation: obligation.clone(), consider_ambiguities },
         )
         .break_value()
         .unwrap_or(obligation)
@@ -288,6 +290,7 @@ fn find_best_leaf_obligation<'tcx>(
 
 struct BestObligation<'tcx> {
     obligation: PredicateObligation<'tcx>,
+    consider_ambiguities: bool,
 }
 
 impl<'tcx> BestObligation<'tcx> {
@@ -320,6 +323,14 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
             return ControlFlow::Break(self.obligation.clone());
         };
 
+        // Don't walk into impls that have `do_not_recommend`.
+        if let ProbeKind::TraitCandidate { source: CandidateSource::Impl(impl_def_id), result: _ } =
+            candidate.kind()
+            && goal.infcx().tcx.has_attr(impl_def_id, sym::do_not_recommend)
+        {
+            return ControlFlow::Break(self.obligation.clone());
+        }
+
         // FIXME: Could we extract a trait ref from a projection here too?
         // FIXME: Also, what about considering >1 layer up the stack? May be necessary
         // for normalizes-to.
@@ -355,11 +366,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                 }
             }
 
-            // Skip nested goals that hold.
-            //FIXME: We should change the max allowed certainty based on if we're
-            // visiting an ambiguity or error obligation.
-            if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
-                continue;
+            // Skip nested goals that aren't the *reason* for our goal's failure.
+            match self.consider_ambiguities {
+                true if matches!(nested_goal.result(), Ok(Certainty::Maybe(_))) => {}
+                false if matches!(nested_goal.result(), Err(_)) => {}
+                _ => continue,
             }
 
             self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;