Skip to content

Commit fa6b50f

Browse files
committed
Auto merge of #41413 - frewsxcv:rollup, r=frewsxcv
Rollup of 5 pull requests - Successful merges: #41214, #41369, #41377, #41378, #41390 - Failed merges:
2 parents 1bb1530 + 204243f commit fa6b50f

File tree

23 files changed

+197
-49
lines changed

23 files changed

+197
-49
lines changed

src/librustc/infer/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
15971597
// generic so we don't have to do anything quite this
15981598
// terrible.
15991599
let trace = TypeTrace::dummy(self.tcx);
1600-
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
1601-
// FIXME(#32730) propagate obligations
1602-
assert!(obligations.is_empty());
1600+
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
1601+
// We can intentionally ignore obligations here, since
1602+
// this is part of a simple test for general
1603+
// "equatability". However, it's not entirely clear
1604+
// that we *ought* to be, perhaps a better thing would
1605+
// be to use a mini-fulfillment context or something
1606+
// like that.
16031607
})
16041608
})
16051609
}

src/librustc/traits/coherence.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,15 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
5555
debug!("overlap: b_impl_header={:?}", b_impl_header);
5656

5757
// Do `a` and `b` unify? If not, no overlap.
58-
match selcx.infcx().eq_impl_headers(true,
58+
let obligations = match selcx.infcx().eq_impl_headers(true,
5959
&ObligationCause::dummy(),
6060
&a_impl_header,
6161
&b_impl_header) {
6262
Ok(InferOk { obligations, .. }) => {
63-
// FIXME(#32730) propagate obligations
64-
assert!(obligations.is_empty());
63+
obligations
6564
}
6665
Err(_) => return None
67-
}
66+
};
6867

6968
debug!("overlap: unification check succeeded");
7069

@@ -78,6 +77,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
7877
.map(|p| Obligation { cause: ObligationCause::dummy(),
7978
recursion_depth: 0,
8079
predicate: p })
80+
.chain(obligations)
8181
.find(|o| !selcx.evaluate_obligation(o));
8282

8383
if let Some(failing_obligation) = opt_failing_obligation {

src/librustc/traits/error_reporting.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -329,22 +329,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
329329
Some(val) => Some(val),
330330
None => {
331331
span_err!(self.tcx.sess, err_sp, E0272,
332-
"the #[rustc_on_unimplemented] \
333-
attribute on \
334-
trait definition for {} refers to \
335-
non-existent type parameter {}",
336-
trait_str, s);
332+
"the #[rustc_on_unimplemented] attribute on trait \
333+
definition for {} refers to non-existent type \
334+
parameter {}",
335+
trait_str, s);
337336
errored = true;
338337
None
339338
}
340339
},
341340
_ => {
342341
span_err!(self.tcx.sess, err_sp, E0273,
343-
"the #[rustc_on_unimplemented] attribute \
344-
on trait definition for {} must have \
345-
named format arguments, eg \
346-
`#[rustc_on_unimplemented = \
347-
\"foo {{T}}\"]`", trait_str);
342+
"the #[rustc_on_unimplemented] attribute on trait \
343+
definition for {} must have named format arguments, eg \
344+
`#[rustc_on_unimplemented = \"foo {{T}}\"]`",
345+
trait_str);
348346
errored = true;
349347
None
350348
}
@@ -485,8 +483,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
485483
"impl has stricter requirements than trait");
486484

487485
if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
488-
err.span_label(trait_item_span,
489-
&format!("definition of `{}` from trait", item_name));
486+
let span = self.tcx.sess.codemap().def_span(trait_item_span);
487+
err.span_label(span, &format!("definition of `{}` from trait", item_name));
490488
}
491489

492490
err.span_label(
@@ -692,6 +690,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
692690
{
693691
assert!(type_def_id.is_local());
694692
let span = self.hir.span_if_local(type_def_id).unwrap();
693+
let span = self.sess.codemap().def_span(span);
695694
let mut err = struct_span_err!(self.sess, span, E0072,
696695
"recursive type `{}` has infinite size",
697696
self.item_path_str(type_def_id));
@@ -709,13 +708,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
709708
-> DiagnosticBuilder<'tcx>
710709
{
711710
let trait_str = self.item_path_str(trait_def_id);
711+
let span = self.sess.codemap().def_span(span);
712712
let mut err = struct_span_err!(
713713
self.sess, span, E0038,
714714
"the trait `{}` cannot be made into an object",
715715
trait_str);
716-
err.span_label(span, &format!(
717-
"the trait `{}` cannot be made into an object", trait_str
718-
));
716+
err.span_label(span, &format!("the trait `{}` cannot be made into an object", trait_str));
719717

720718
let mut reported_violations = FxHashSet();
721719
for violation in violations {

src/librustc/traits/fulfill.rs

+10
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
184184
});
185185
}
186186

187+
pub fn register_predicate_obligations(&mut self,
188+
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
189+
obligations: Vec<PredicateObligation<'tcx>>)
190+
{
191+
for obligation in obligations {
192+
self.register_predicate_obligation(infcx, obligation);
193+
}
194+
}
195+
196+
187197
pub fn region_obligations(&self,
188198
body_id: ast::NodeId)
189199
-> &[RegionObligation<'tcx>]

src/librustc/traits/specialize/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
218218
-> Result<&'tcx Substs<'tcx>, ()> {
219219
let selcx = &mut SelectionContext::new(&infcx);
220220
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
221-
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
221+
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
222222
target_impl,
223223
target_substs);
224224

@@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
227227
&ObligationCause::dummy(),
228228
source_trait_ref,
229229
target_trait_ref) {
230-
Ok(InferOk { obligations, .. }) => {
231-
// FIXME(#32730) propagate obligations
232-
assert!(obligations.is_empty())
230+
Ok(InferOk { obligations: o, .. }) => {
231+
obligations.extend(o);
233232
}
234233
Err(_) => {
235234
debug!("fulfill_implication: {:?} does not unify with {:?}",

src/librustc_driver/test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
376376
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
377377
match self.sub(t1, t2) {
378378
Ok(InferOk { obligations, .. }) => {
379-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
379+
// None of these tests should require nested obligations:
380380
assert!(obligations.is_empty());
381381
}
382382
Err(ref e) => {
@@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
400400
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
401401
match self.lub(t1, t2) {
402402
Ok(InferOk { obligations, value: t }) => {
403-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
403+
// None of these tests should require nested obligations:
404404
assert!(obligations.is_empty());
405405

406406
self.assert_eq(t, t_lub);
@@ -415,7 +415,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
415415
match self.glb(t1, t2) {
416416
Err(e) => panic!("unexpected error computing LUB: {:?}", e),
417417
Ok(InferOk { obligations, value: t }) => {
418-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
418+
// None of these tests should require nested obligations:
419419
assert!(obligations.is_empty());
420420

421421
self.assert_eq(t, t_glb);

src/librustc_trans/cabi_x86_64.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType
229229
};
230230

231231
if in_mem {
232-
// `sret` / `byval` parameter thus one less integer register available
233-
int_regs -= 1;
234-
235232
arg.make_indirect(ccx);
236233
if is_arg {
237234
arg.attrs.set(ArgAttribute::ByVal);
235+
} else {
236+
// `sret` parameter thus one less integer register available
237+
int_regs -= 1;
238238
}
239239
} else {
240240
// split into sized chunks passed individually

src/librustc_typeck/check/compare_method.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
294294
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
295295

296296
let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
297-
.map(|InferOk { obligations, .. }| {
298-
// FIXME(#32730) propagate obligations
299-
assert!(obligations.is_empty());
300-
});
297+
.map(|InferOk { obligations, .. }| {
298+
inh.register_predicates(obligations);
299+
});
301300

302301
if let Err(terr) = sub_result {
303302
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",

src/librustc_typeck/check/dropck.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
8282
// check that the impl type can be made to match the trait type.
8383

8484
let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
85-
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
85+
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
8686
let tcx = infcx.tcx;
8787
let mut fulfillment_cx = traits::FulfillmentContext::new();
8888

@@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
9797
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
9898
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
9999
Ok(InferOk { obligations, .. }) => {
100-
// FIXME(#32730) propagate obligations
101-
assert!(obligations.is_empty());
100+
fulfillment_cx.register_predicate_obligations(infcx, obligations);
102101
}
103102
Err(_) => {
104103
let item_span = tcx.hir.span(self_type_node_id);

src/librustc_typeck/lib.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ use rustc::infer::InferOk;
109109
use rustc::ty::subst::Substs;
110110
use rustc::ty::{self, Ty, TyCtxt};
111111
use rustc::ty::maps::Providers;
112-
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
112+
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
113113
use session::config;
114114
use util::common::time;
115115

@@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
153153
expected: Ty<'tcx>,
154154
actual: Ty<'tcx>)
155155
-> bool {
156-
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
156+
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
157+
let mut fulfill_cx = FulfillmentContext::new();
157158
match infcx.eq_types(false, &cause, expected, actual) {
158159
Ok(InferOk { obligations, .. }) => {
159-
// FIXME(#32730) propagate obligations
160-
assert!(obligations.is_empty());
161-
true
160+
fulfill_cx.register_predicate_obligations(infcx, obligations);
162161
}
163162
Err(err) => {
164163
infcx.report_mismatched_types(cause, expected, actual, err).emit();
164+
return false;
165+
}
166+
}
167+
168+
match fulfill_cx.select_all_or_error(infcx) {
169+
Ok(()) => true,
170+
Err(errors) => {
171+
infcx.report_fulfillment_errors(&errors);
165172
false
166173
}
167174
}

src/libstd/ffi/os_str.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,13 @@ impl Borrow<OsStr> for OsString {
677677
#[stable(feature = "rust1", since = "1.0.0")]
678678
impl ToOwned for OsStr {
679679
type Owned = OsString;
680-
fn to_owned(&self) -> OsString { self.to_os_string() }
680+
fn to_owned(&self) -> OsString {
681+
self.to_os_string()
682+
}
683+
fn clone_into(&self, target: &mut OsString) {
684+
target.clear();
685+
target.push(self);
686+
}
681687
}
682688

683689
#[stable(feature = "rust1", since = "1.0.0")]
@@ -863,4 +869,14 @@ mod tests {
863869
let boxed = <Box<OsStr>>::default();
864870
assert!(boxed.is_empty());
865871
}
872+
873+
#[test]
874+
fn test_os_str_clone_into() {
875+
let mut os_string = OsString::with_capacity(123);
876+
os_string.push("hello");
877+
let os_str = OsStr::new("bonjour");
878+
os_str.clone_into(&mut os_string);
879+
assert_eq!(os_str, os_string);
880+
assert!(os_string.capacity() >= 123);
881+
}
866882
}

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@
311311
#![feature(str_utf16)]
312312
#![feature(test, rustc_private)]
313313
#![feature(thread_local)]
314+
#![feature(toowned_clone_into)]
314315
#![feature(try_from)]
315316
#![feature(unboxed_closures)]
316317
#![feature(unicode)]

src/libstd/path.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,9 @@ impl ToOwned for Path {
14141414
fn to_owned(&self) -> PathBuf {
14151415
self.to_path_buf()
14161416
}
1417+
fn clone_into(&self, target: &mut PathBuf) {
1418+
self.inner.clone_into(&mut target.inner);
1419+
}
14171420
}
14181421

14191422
#[stable(feature = "rust1", since = "1.0.0")]
@@ -3859,4 +3862,13 @@ mod tests {
38593862
assert_eq!(&*boxed, &*path_buf);
38603863
assert_eq!(&*path_buf, path);
38613864
}
3865+
3866+
#[test]
3867+
fn test_clone_into() {
3868+
let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
3869+
let path = Path::new("short");
3870+
path.clone_into(&mut path_buf);
3871+
assert_eq!(path, path_buf);
3872+
assert!(path_buf.into_os_string().capacity() >= 15);
3873+
}
38623874
}

src/libsyntax/codemap.rs

+19
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,25 @@ impl CodeMap {
441441
}
442442
}
443443

444+
/// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
445+
pub fn span_until_char(&self, sp: Span, c: char) -> Span {
446+
match self.span_to_snippet(sp) {
447+
Ok(snippet) => {
448+
let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
449+
if snippet.len() > 0 && !snippet.contains('\n') {
450+
Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp }
451+
} else {
452+
sp
453+
}
454+
}
455+
_ => sp,
456+
}
457+
}
458+
459+
pub fn def_span(&self, sp: Span) -> Span {
460+
self.span_until_char(sp, '{')
461+
}
462+
444463
pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
445464
for fm in self.files.borrow().iter() {
446465
if filename == fm.name {

src/stage0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
1313
# released on `$date`
1414

15-
rustc: beta-2017-03-21
15+
rustc: beta-2017-04-05

src/test/run-make/extern-fn-struct-passing-abi/test.c

+15
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
137137
assert(s.d == 556);
138138
}
139139

140+
// System V x86_64 ABI:
141+
// a, b, d, e, f should be byval pointer (on the stack)
142+
// g passed via register (fixes #41375)
143+
//
144+
// Win64 ABI:
145+
// a, b, d, e, f, g should be byval pointer
146+
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
147+
struct Huge d, struct Huge e, struct Huge f,
148+
struct Rect g) {
149+
assert(g.a == 123);
150+
assert(g.b == 456);
151+
assert(g.c == 789);
152+
assert(g.d == 420);
153+
}
154+
140155
// System V x86_64 & Win64 ABI:
141156
// a, b should be in registers
142157
// s should be split across 2 integer registers

src/test/run-make/extern-fn-struct-passing-abi/test.rs

+8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ extern {
6464

6565
fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);
6666

67+
fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);
68+
6769
fn split_rect(a: i32, b: i32, s: Rect);
6870

6971
fn split_rect_floats(a: f32, b: f32, s: FloatRect);
@@ -95,6 +97,12 @@ fn main() {
9597
byval_many_rect(1, 2, 3, 4, 5, 6, s);
9698
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
9799
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
100+
byval_rect_with_many_huge(v, v, v, v, v, v, Rect {
101+
a: 123,
102+
b: 456,
103+
c: 789,
104+
d: 420
105+
});
98106
split_rect(1, 2, s);
99107
split_rect_floats(1., 2., u);
100108
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);

0 commit comments

Comments
 (0)