diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sso/set.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/wfcheck.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect/type_of.rs | 47 |
6 files changed, 48 insertions, 51 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 977b55a0890..9c032c55fe5 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -441,6 +441,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { msg, }) } + // Ensure we never consider the null pointer dereferencable. + if M::PointerTag::OFFSET_IS_ADDR { + assert_ne!(ptr.addr(), Size::ZERO); + } // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. if let Some(align) = align { diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index f71522d3714..4fda3adb7b8 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -126,9 +126,10 @@ impl<T: Eq + Hash> SsoHashSet<T> { /// Adds a value to the set. /// - /// If the set did not have this value present, `true` is returned. + /// Returns whether the value was newly inserted. That is: /// - /// If the set did have this value present, `false` is returned. + /// - If the set did not previously contain this value, `true` is returned. + /// - If the set already contained this value, `false` is returned. #[inline] pub fn insert(&mut self, elem: T) -> bool { self.map.insert(elem, ()).is_none() diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a71621a4d52..641b915f373 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -145,15 +145,28 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { } } -/// Takes the place of a +/// States returned from `poly_project_and_unify_type`. Takes the place +/// of the old return type, which was: +/// ```ignore (not-rust) /// Result< /// Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>, /// MismatchedProjectionTypes<'tcx>, /// > +/// ``` pub(super) enum ProjectAndUnifyResult<'tcx> { + /// The projection bound holds subject to the given obligations. If the + /// projection cannot be normalized because the required trait bound does + /// not hold, this is returned, with `obligations` being a predicate that + /// cannot be proven. Holds(Vec<PredicateObligation<'tcx>>), + /// The projection cannot be normalized due to ambiguity. Resolving some + /// inference variables in the projection may fix this. FailedNormalization, + /// The project cannot be normalized because `poly_project_and_unify_type` + /// is called recursively while normalizing the same projection. Recursive, + // the projection can be normalized, but is not equal to the expected type. + // Returns the type error that arose from the mismatch. MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>), } @@ -163,19 +176,6 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// ``` /// If successful, this may result in additional obligations. Also returns /// the projection cache key used to track these additional obligations. -/// -/// ## Returns -/// -/// - `Err(_)`: the projection can be normalized, but is not equal to the -/// expected type. -/// - `Ok(Err(InProgress))`: this is called recursively while normalizing -/// the same projection. -/// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity -/// (resolving some inference variables in the projection may fix this). -/// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to -/// the given obligations. If the projection cannot be normalized because -/// the required trait bound doesn't hold this returned with `obligations` -/// being a predicate that cannot be proven. #[instrument(level = "debug", skip(selcx))] pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0379b16334c..2ce2a44d3db 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -81,10 +81,17 @@ pub fn trait_obligations<'a, 'tcx>( body_id: hir::HirId, trait_ref: &ty::TraitRef<'tcx>, span: Span, - item: Option<&'tcx hir::Item<'tcx>>, + item: &'tcx hir::Item<'tcx>, ) -> Vec<traits::PredicateObligation<'tcx>> { - let mut wf = - WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item }; + let mut wf = WfPredicates { + infcx, + param_env, + body_id, + span, + out: vec![], + recursion_depth: 0, + item: Some(item), + }; wf.compute_trait_ref(trait_ref, Elaborate::All); debug!(obligations = ?wf.out); wf.normalize() diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index a6c7573b787..20ef97c085f 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1228,7 +1228,7 @@ fn check_impl<'tcx>( fcx.body_id, &trait_ref, ast_trait_ref.path.span, - Some(item), + item, ); debug!(?obligations); for obligation in obligations { diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 4b6f80ce57a..7e3fefe4502 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -161,38 +161,23 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // We've encountered an `AnonConst` in some path, so we need to // figure out which generic parameter it corresponds to and return // the relevant type. - let filtered = path.segments.iter().find_map(|seg| { - seg.args? - .args + let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| { + let args = seg.args?; + args.args + .iter() + .filter(|arg| arg.is_ty_or_const()) + .position(|arg| arg.id() == hir_id) + .map(|index| (index, seg)).or_else(|| args.bindings .iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.id() == hir_id) - .map(|index| (index, seg)) - }); - - // FIXME(associated_const_generics): can we blend this with iteration above? - let (arg_index, segment) = match filtered { - None => { - let binding_filtered = path.segments.iter().find_map(|seg| { - seg.args? - .bindings - .iter() - .filter_map(TypeBinding::opt_const) - .position(|ct| ct.hir_id == hir_id) - .map(|idx| (idx, seg)) - }); - match binding_filtered { - Some(inner) => inner, - None => { - tcx.sess.delay_span_bug( - tcx.def_span(def_id), - "no arg matching AnonConst in path", - ); - return None; - } - } - } - Some(inner) => inner, + .filter_map(TypeBinding::opt_const) + .position(|ct| ct.hir_id == hir_id) + .map(|idx| (idx, seg))) + }) else { + tcx.sess.delay_span_bug( + tcx.def_span(def_id), + "no arg matching AnonConst in path", + ); + return None; }; // Try to use the segment resolution if it is valid, otherwise we |
