Skip to content

Commit

Permalink
Auto merge of #41413 - frewsxcv:rollup, r=frewsxcv
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

- Successful merges: #41214, #41369, #41377, #41378, #41390
- Failed merges:
  • Loading branch information
bors committed Apr 20, 2017
2 parents 1bb1530 + 204243f commit fa6b50f
Show file tree
Hide file tree
Showing 23 changed files with 197 additions and 49 deletions.
10 changes: 7 additions & 3 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// generic so we don't have to do anything quite this
// terrible.
let trace = TypeTrace::dummy(self.tcx);
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
// We can intentionally ignore obligations here, since
// this is part of a simple test for general
// "equatability". However, it's not entirely clear
// that we *ought* to be, perhaps a better thing would
// be to use a mini-fulfillment context or something
// like that.
})
})
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,15 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
debug!("overlap: b_impl_header={:?}", b_impl_header);

// Do `a` and `b` unify? If not, no overlap.
match selcx.infcx().eq_impl_headers(true,
let obligations = match selcx.infcx().eq_impl_headers(true,
&ObligationCause::dummy(),
&a_impl_header,
&b_impl_header) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
obligations
}
Err(_) => return None
}
};

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

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

if let Some(failing_obligation) = opt_failing_obligation {
Expand Down
28 changes: 13 additions & 15 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,22 +329,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Some(val) => Some(val),
None => {
span_err!(self.tcx.sess, err_sp, E0272,
"the #[rustc_on_unimplemented] \
attribute on \
trait definition for {} refers to \
non-existent type parameter {}",
trait_str, s);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} refers to non-existent type \
parameter {}",
trait_str, s);
errored = true;
None
}
},
_ => {
span_err!(self.tcx.sess, err_sp, E0273,
"the #[rustc_on_unimplemented] attribute \
on trait definition for {} must have \
named format arguments, eg \
`#[rustc_on_unimplemented = \
\"foo {{T}}\"]`", trait_str);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} must have named format arguments, eg \
`#[rustc_on_unimplemented = \"foo {{T}}\"]`",
trait_str);
errored = true;
None
}
Expand Down Expand Up @@ -485,8 +483,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"impl has stricter requirements than trait");

if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
err.span_label(trait_item_span,
&format!("definition of `{}` from trait", item_name));
let span = self.tcx.sess.codemap().def_span(trait_item_span);
err.span_label(span, &format!("definition of `{}` from trait", item_name));
}

err.span_label(
Expand Down Expand Up @@ -692,6 +690,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
assert!(type_def_id.is_local());
let span = self.hir.span_if_local(type_def_id).unwrap();
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(self.sess, span, E0072,
"recursive type `{}` has infinite size",
self.item_path_str(type_def_id));
Expand All @@ -709,13 +708,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> DiagnosticBuilder<'tcx>
{
let trait_str = self.item_path_str(trait_def_id);
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(
self.sess, span, E0038,
"the trait `{}` cannot be made into an object",
trait_str);
err.span_label(span, &format!(
"the trait `{}` cannot be made into an object", trait_str
));
err.span_label(span, &format!("the trait `{}` cannot be made into an object", trait_str));

let mut reported_violations = FxHashSet();
for violation in violations {
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
});
}

pub fn register_predicate_obligations(&mut self,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
obligations: Vec<PredicateObligation<'tcx>>)
{
for obligation in obligations {
self.register_predicate_obligation(infcx, obligation);
}
}


pub fn region_obligations(&self,
body_id: ast::NodeId)
-> &[RegionObligation<'tcx>]
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-> Result<&'tcx Substs<'tcx>, ()> {
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
target_impl,
target_substs);

Expand All @@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
&ObligationCause::dummy(),
source_trait_ref,
target_trait_ref) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty())
Ok(InferOk { obligations: o, .. }) => {
obligations.extend(o);
}
Err(_) => {
debug!("fulfill_implication: {:?} does not unify with {:?}",
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
match self.sub(t1, t2) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());
}
Err(ref e) => {
Expand All @@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
match self.lub(t1, t2) {
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

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

self.assert_eq(t, t_glb);
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trans/cabi_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType
};

if in_mem {
// `sret` / `byval` parameter thus one less integer register available
int_regs -= 1;

arg.make_indirect(ccx);
if is_arg {
arg.attrs.set(ArgAttribute::ByVal);
} else {
// `sret` parameter thus one less integer register available
int_regs -= 1;
}
} else {
// split into sized chunks passed individually
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
.map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
});
.map(|InferOk { obligations, .. }| {
inh.register_predicates(obligations);
});

if let Err(terr) = sub_result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.

let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

Expand All @@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
fulfillment_cx.register_predicate_obligations(infcx, obligations);
}
Err(_) => {
let item_span = tcx.hir.span(self_type_node_id);
Expand Down
17 changes: 12 additions & 5 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use rustc::infer::InferOk;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use session::config;
use util::common::time;

Expand Down Expand Up @@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
-> bool {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
let mut fulfill_cx = FulfillmentContext::new();
match infcx.eq_types(false, &cause, expected, actual) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
true
fulfill_cx.register_predicate_obligations(infcx, obligations);
}
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
}

match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => true,
Err(errors) => {
infcx.report_fulfillment_errors(&errors);
false
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/libstd/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,13 @@ impl Borrow<OsStr> for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
type Owned = OsString;
fn to_owned(&self) -> OsString { self.to_os_string() }
fn to_owned(&self) -> OsString {
self.to_os_string()
}
fn clone_into(&self, target: &mut OsString) {
target.clear();
target.push(self);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -863,4 +869,14 @@ mod tests {
let boxed = <Box<OsStr>>::default();
assert!(boxed.is_empty());
}

#[test]
fn test_os_str_clone_into() {
let mut os_string = OsString::with_capacity(123);
os_string.push("hello");
let os_str = OsStr::new("bonjour");
os_str.clone_into(&mut os_string);
assert_eq!(os_str, os_string);
assert!(os_string.capacity() >= 123);
}
}
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
#![feature(str_utf16)]
#![feature(test, rustc_private)]
#![feature(thread_local)]
#![feature(toowned_clone_into)]
#![feature(try_from)]
#![feature(unboxed_closures)]
#![feature(unicode)]
Expand Down
12 changes: 12 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,9 @@ impl ToOwned for Path {
fn to_owned(&self) -> PathBuf {
self.to_path_buf()
}
fn clone_into(&self, target: &mut PathBuf) {
self.inner.clone_into(&mut target.inner);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -3859,4 +3862,13 @@ mod tests {
assert_eq!(&*boxed, &*path_buf);
assert_eq!(&*path_buf, path);
}

#[test]
fn test_clone_into() {
let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
let path = Path::new("short");
path.clone_into(&mut path_buf);
assert_eq!(path, path_buf);
assert!(path_buf.into_os_string().capacity() >= 15);
}
}
19 changes: 19 additions & 0 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,25 @@ impl CodeMap {
}
}

/// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
pub fn span_until_char(&self, sp: Span, c: char) -> Span {
match self.span_to_snippet(sp) {
Ok(snippet) => {
let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
if snippet.len() > 0 && !snippet.contains('\n') {
Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp }
} else {
sp
}
}
_ => sp,
}
}

pub fn def_span(&self, sp: Span) -> Span {
self.span_until_char(sp, '{')
}

pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
for fm in self.files.borrow().iter() {
if filename == fm.name {
Expand Down
2 changes: 1 addition & 1 deletion src/stage0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
# released on `$date`

rustc: beta-2017-03-21
rustc: beta-2017-04-05
15 changes: 15 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, d, e, f should be byval pointer (on the stack)
// g passed via register (fixes #41375)
//
// Win64 ABI:
// a, b, d, e, f, g should be byval pointer
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
struct Huge d, struct Huge e, struct Huge f,
struct Rect g) {
assert(g.a == 123);
assert(g.b == 456);
assert(g.c == 789);
assert(g.d == 420);
}

// System V x86_64 & Win64 ABI:
// a, b should be in registers
// s should be split across 2 integer registers
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ extern {

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

fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);

fn split_rect(a: i32, b: i32, s: Rect);

fn split_rect_floats(a: f32, b: f32, s: FloatRect);
Expand Down Expand Up @@ -95,6 +97,12 @@ fn main() {
byval_many_rect(1, 2, 3, 4, 5, 6, s);
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
byval_rect_with_many_huge(v, v, v, v, v, v, Rect {
a: 123,
b: 456,
c: 789,
d: 420
});
split_rect(1, 2, s);
split_rect_floats(1., 2., u);
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
Expand Down
Loading

0 comments on commit fa6b50f

Please sign in to comment.