Skip to content

Commit e64fee6

Browse files
committed
Auto merge of #57305 - pietroalbini:beta-rollup, r=pietroalbini
[beta] Rollup backports Cherry-picked: * #57053: Fix alignment for array indexing * #57181: resolve: Fix another ICE in import validation * #57185: resolve: Fix one more ICE in import validation * #57282: Wf-check the output type of a function in MIR-typeck * #55318: Ensure that Rustdoc discovers all necessary auto trait bounds * #56838: Call poly_project_and_unify_type on types that contain inference types Rolled up: * #57300: [beta] Update RLS to include 100% CPU on hover bugfix * #57301: beta: bootstrap from latest stable (1.31.1) * #57292: [BETA] Update cargo r? @ghost
2 parents fa64cc8 + 443165d commit e64fee6

File tree

24 files changed

+375
-57
lines changed

24 files changed

+375
-57
lines changed

src/librustc/traits/auto_trait.rs

+81-17
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
334334
continue;
335335
}
336336

337-
let result = select.select(&Obligation::new(dummy_cause.clone(), new_env, pred));
337+
// Call infcx.resolve_type_vars_if_possible to see if we can
338+
// get rid of any inference variables.
339+
let obligation = infcx.resolve_type_vars_if_possible(
340+
&Obligation::new(dummy_cause.clone(), new_env, pred)
341+
);
342+
let result = select.select(&obligation);
338343

339344
match &result {
340345
&Ok(Some(ref vtable)) => {
@@ -369,7 +374,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
369374
}
370375
&Ok(None) => {}
371376
&Err(SelectionError::Unimplemented) => {
372-
if self.is_of_param(pred.skip_binder().trait_ref.substs) {
377+
if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
373378
already_visited.remove(&pred);
374379
self.add_user_pred(
375380
&mut user_computed_preds,
@@ -631,18 +636,28 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
631636
finished_map
632637
}
633638

634-
pub fn is_of_param(&self, substs: &Substs<'_>) -> bool {
635-
if substs.is_noop() {
636-
return false;
637-
}
639+
fn is_param_no_infer(&self, substs: &Substs<'_>) -> bool {
640+
return self.is_of_param(substs.type_at(0)) &&
641+
!substs.types().any(|t| t.has_infer_types());
642+
}
638643

639-
return match substs.type_at(0).sty {
644+
pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
645+
return match ty.sty {
640646
ty::Param(_) => true,
641-
ty::Projection(p) => self.is_of_param(p.substs),
647+
ty::Projection(p) => self.is_of_param(p.self_ty()),
642648
_ => false,
643649
};
644650
}
645651

652+
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
653+
match p.ty().skip_binder().sty {
654+
ty::Projection(proj) if proj == p.skip_binder().projection_ty => {
655+
true
656+
},
657+
_ => false
658+
}
659+
}
660+
646661
pub fn evaluate_nested_obligations<
647662
'b,
648663
'c,
@@ -661,28 +676,77 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
661676
) -> bool {
662677
let dummy_cause = ObligationCause::misc(DUMMY_SP, ast::DUMMY_NODE_ID);
663678

664-
for (obligation, predicate) in nested
665-
.filter(|o| o.recursion_depth == 1)
679+
for (obligation, mut predicate) in nested
666680
.map(|o| (o.clone(), o.predicate.clone()))
667681
{
668682
let is_new_pred =
669683
fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone()));
670684

685+
// Resolve any inference variables that we can, to help selection succeed
686+
predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
687+
688+
// We only add a predicate as a user-displayable bound if
689+
// it involves a generic parameter, and doesn't contain
690+
// any inference variables.
691+
//
692+
// Displaying a bound involving a concrete type (instead of a generic
693+
// parameter) would be pointless, since it's always true
694+
// (e.g. u8: Copy)
695+
// Displaying an inference variable is impossible, since they're
696+
// an internal compiler detail without a defined visual representation
697+
//
698+
// We check this by calling is_of_param on the relevant types
699+
// from the various possible predicates
671700
match &predicate {
672701
&ty::Predicate::Trait(ref p) => {
673-
let substs = &p.skip_binder().trait_ref.substs;
702+
if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
703+
&& !only_projections
704+
&& is_new_pred {
674705

675-
if self.is_of_param(substs) && !only_projections && is_new_pred {
676706
self.add_user_pred(computed_preds, predicate);
677707
}
678708
predicates.push_back(p.clone());
679709
}
680710
&ty::Predicate::Projection(p) => {
681-
// If the projection isn't all type vars, then
682-
// we don't want to add it as a bound
683-
if self.is_of_param(p.skip_binder().projection_ty.substs) && is_new_pred {
684-
self.add_user_pred(computed_preds, predicate);
685-
} else {
711+
debug!("evaluate_nested_obligations: examining projection predicate {:?}",
712+
predicate);
713+
714+
// As described above, we only want to display
715+
// bounds which include a generic parameter but don't include
716+
// an inference variable.
717+
// Additionally, we check if we've seen this predicate before,
718+
// to avoid rendering duplicate bounds to the user.
719+
if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
720+
&& !p.ty().skip_binder().is_ty_infer()
721+
&& is_new_pred {
722+
debug!("evaluate_nested_obligations: adding projection predicate\
723+
to computed_preds: {:?}", predicate);
724+
725+
// Under unusual circumstances, we can end up with a self-refeential
726+
// projection predicate. For example:
727+
// <T as MyType>::Value == <T as MyType>::Value
728+
// Not only is displaying this to the user pointless,
729+
// having it in the ParamEnv will cause an issue if we try to call
730+
// poly_project_and_unify_type on the predicate, since this kind of
731+
// predicate will normally never end up in a ParamEnv.
732+
//
733+
// For these reasons, we ignore these weird predicates,
734+
// ensuring that we're able to properly synthesize an auto trait impl
735+
if self.is_self_referential_projection(p) {
736+
debug!("evaluate_nested_obligations: encountered a projection
737+
predicate equating a type with itself! Skipping");
738+
739+
} else {
740+
self.add_user_pred(computed_preds, predicate);
741+
}
742+
}
743+
744+
// We can only call poly_project_and_unify_type when our predicate's
745+
// Ty contains an inference variable - otherwise, there won't be anything to
746+
// unify
747+
if p.ty().skip_binder().has_infer_types() {
748+
debug!("Projecting and unifying projection predicate {:?}",
749+
predicate);
686750
match poly_project_and_unify_type(select, &obligation.with(p.clone())) {
687751
Err(e) => {
688752
debug!(

src/librustc_codegen_ssa/mir/place.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
335335
bx: &mut Bx,
336336
llindex: V
337337
) -> Self {
338+
// Statically compute the offset if we can, otherwise just use the element size,
339+
// as this will yield the lowest alignment.
340+
let layout = self.layout.field(bx, 0);
341+
let offset = if bx.is_const_integral(llindex) {
342+
layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
343+
} else {
344+
layout.size
345+
};
346+
338347
PlaceRef {
339348
llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
340349
llextra: None,
341-
layout: self.layout.field(bx.cx(), 0),
342-
align: self.align
350+
layout,
351+
align: self.align.restrict_for_offset(offset),
343352
}
344353
}
345354

src/librustc_codegen_ssa/mir/rvalue.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
131131
let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
132132
header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
133133

134+
let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size);
134135
cg_elem.val.store(&mut body_bx,
135-
PlaceRef::new_sized(current, cg_elem.layout, dest.align));
136+
PlaceRef::new_sized(current, cg_elem.layout, align));
136137

137138
let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]);
138139
body_bx.br(header_bx.llbb());

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
14151415
self.check_call_dest(mir, term, &sig, destination, term_location);
14161416

14171417
self.prove_predicates(
1418-
sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
1418+
sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
14191419
term_location.to_locations(),
14201420
ConstraintCategory::Boring,
14211421
);

src/librustc_mir/interpret/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
8686
type MemoryExtra: Default;
8787

8888
/// Extra data stored in every allocation.
89-
type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra>;
89+
type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra> + 'static;
9090

9191
/// Memory's allocation map
9292
type MemoryMap:

src/librustc_resolve/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1022,11 +1022,11 @@ enum ModuleOrUniformRoot<'a> {
10221022
CurrentScope,
10231023
}
10241024

1025-
impl<'a> PartialEq for ModuleOrUniformRoot<'a> {
1026-
fn eq(&self, other: &Self) -> bool {
1027-
match (*self, *other) {
1025+
impl ModuleOrUniformRoot<'_> {
1026+
fn same_def(lhs: Self, rhs: Self) -> bool {
1027+
match (lhs, rhs) {
10281028
(ModuleOrUniformRoot::Module(lhs),
1029-
ModuleOrUniformRoot::Module(rhs)) => ptr::eq(lhs, rhs),
1029+
ModuleOrUniformRoot::Module(rhs)) => lhs.def() == rhs.def(),
10301030
(ModuleOrUniformRoot::CrateRootAndExternPrelude,
10311031
ModuleOrUniformRoot::CrateRootAndExternPrelude) |
10321032
(ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) |

src/librustc_resolve/resolve_imports.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,10 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
465465
self.set_binding_parent_module(binding, module);
466466
self.update_resolution(module, ident, ns, |this, resolution| {
467467
if let Some(old_binding) = resolution.binding {
468+
if binding.def() == Def::Err {
469+
// Do not override real bindings with `Def::Err`s from error recovery.
470+
return Ok(());
471+
}
468472
match (old_binding.is_glob_import(), binding.is_glob_import()) {
469473
(true, true) => {
470474
if binding.def() != old_binding.def() {
@@ -836,7 +840,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
836840
PathResult::Module(module) => {
837841
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
838842
if let Some(initial_module) = directive.imported_module.get() {
839-
if module != initial_module && self.ambiguity_errors.is_empty() {
843+
if !ModuleOrUniformRoot::same_def(module, initial_module)
844+
&& self.ambiguity_errors.is_empty()
845+
{
840846
span_bug!(directive.span, "inconsistent resolution for an import");
841847
}
842848
} else {

src/stage0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
1313
# `0.x.0` for Cargo where they were released on `date`.
1414

15-
date: 2018-12-06
16-
rustc: 1.31.0
15+
date: 2018-12-20
16+
rustc: 1.31.1
1717
cargo: 0.32.0
1818

1919
# When making a stable release the process currently looks like:

src/test/codegen/issue-56927.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// compile-flags: -C no-prepopulate-passes
2+
3+
#![crate_type="rlib"]
4+
use std::usize;
5+
6+
#[repr(align(16))]
7+
pub struct S {
8+
arr: [u32; 4],
9+
}
10+
11+
// CHECK-LABEL: @test1
12+
// CHECK: store i32 0, i32* %{{.+}}, align 16
13+
// CHECK: store i32 1, i32* %{{.+}}, align 4
14+
// CHECK: store i32 2, i32* %{{.+}}, align 8
15+
// CHECK: store i32 3, i32* %{{.+}}, align 4
16+
#[no_mangle]
17+
pub fn test1(s: &mut S) {
18+
s.arr[0] = 0;
19+
s.arr[1] = 1;
20+
s.arr[2] = 2;
21+
s.arr[3] = 3;
22+
}
23+
24+
// CHECK-LABEL: @test2
25+
// CHECK: store i32 4, i32* %{{.+}}, align 4
26+
#[allow(const_err)]
27+
#[no_mangle]
28+
pub fn test2(s: &mut S) {
29+
s.arr[usize::MAX / 4 + 1] = 4;
30+
}
31+
32+
// CHECK-LABEL: @test3
33+
// CHECK: store i32 5, i32* %{{.+}}, align 4
34+
#[no_mangle]
35+
pub fn test3(s: &mut S, i: usize) {
36+
s.arr[i] = 5;
37+
}
38+
39+
// CHECK-LABEL: @test4
40+
// CHECK: store i32 6, i32* %{{.+}}, align 4
41+
#[no_mangle]
42+
pub fn test4(s: &mut S) {
43+
s.arr = [6; 4];
44+
}

src/test/codegen/packed.rs

+36
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,42 @@ pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
8484
BigPacked2 { dealign: 0, data: f() }
8585
}
8686

87+
// CHECK-LABEL: @write_packed_array1
88+
// CHECK: store i32 0, i32* %{{.+}}, align 1
89+
// CHECK: store i32 1, i32* %{{.+}}, align 1
90+
// CHECK: store i32 2, i32* %{{.+}}, align 1
91+
#[no_mangle]
92+
pub fn write_packed_array1(p: &mut BigPacked1) {
93+
p.data.0[0] = 0;
94+
p.data.0[1] = 1;
95+
p.data.0[2] = 2;
96+
}
97+
98+
// CHECK-LABEL: @write_packed_array2
99+
// CHECK: store i32 0, i32* %{{.+}}, align 2
100+
// CHECK: store i32 1, i32* %{{.+}}, align 2
101+
// CHECK: store i32 2, i32* %{{.+}}, align 2
102+
#[no_mangle]
103+
pub fn write_packed_array2(p: &mut BigPacked2) {
104+
p.data.0[0] = 0;
105+
p.data.0[1] = 1;
106+
p.data.0[2] = 2;
107+
}
108+
109+
// CHECK-LABEL: @repeat_packed_array1
110+
// CHECK: store i32 42, i32* %{{.+}}, align 1
111+
#[no_mangle]
112+
pub fn repeat_packed_array1(p: &mut BigPacked1) {
113+
p.data.0 = [42; 8];
114+
}
115+
116+
// CHECK-LABEL: @repeat_packed_array2
117+
// CHECK: store i32 42, i32* %{{.+}}, align 2
118+
#[no_mangle]
119+
pub fn repeat_packed_array2(p: &mut BigPacked2) {
120+
p.data.0 = [42; 8];
121+
}
122+
87123
#[repr(packed)]
88124
#[derive(Copy, Clone)]
89125
pub struct Packed1Pair(u8, u32);

src/test/rustdoc/issue-50159.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
pub trait Signal {
13+
type Item;
14+
}
15+
16+
pub trait Signal2 {
17+
type Item2;
18+
}
19+
20+
impl<B, C> Signal2 for B where B: Signal<Item = C> {
21+
type Item2 = C;
22+
}
23+
24+
// @has issue_50159/struct.Switch.html
25+
// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
26+
// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
27+
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
28+
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
29+
pub struct Switch<B: Signal> {
30+
pub inner: <B as Signal2>::Item2,
31+
}

0 commit comments

Comments
 (0)