Skip to content

Commit c14ecfe

Browse files
committed
---
yaml --- r: 94183 b: refs/heads/try c: 5aad292 h: refs/heads/master i: 94181: 81a9a96 94179: 9cef0ec 94175: 84092da v: v3
1 parent 2c6899e commit c14ecfe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1716
-504
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 0da105a8b7b6b1e0568e8ff20f6ff4b13cc7ecc2
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
5-
refs/heads/try: c935a88a971f3b1e988e74182a3d8bba869fabbe
5+
refs/heads/try: 5aad292fb99f7e9a2730b35ed535bda0ab9c6117
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/doc/tutorial-ffi.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ for the rust task is plenty for the C function to have.
152152

153153
A planned future improvement (net yet implemented at the time of this writing)
154154
is to have a guard page at the end of every rust stack. No rust function will
155-
hit this guard page (due to rust's usage of LLVM's __morestack). The intention
155+
hit this guard page (due to Rust's usage of LLVM's `__morestack`). The intention
156156
for this unmapped page is to prevent infinite recursion in C from overflowing
157157
onto other rust stacks. If the guard page is hit, then the process will be
158158
terminated with a message saying that the guard page was hit.
@@ -166,30 +166,39 @@ the stack of the task which is spawned.
166166

167167
# Destructors
168168

169-
Foreign libraries often hand off ownership of resources to the calling code,
170-
which should be wrapped in a destructor to provide safety and guarantee their
171-
release.
169+
Foreign libraries often hand off ownership of resources to the calling code.
170+
When this occurs, we must use Rust's destructors to provide safety and guarantee
171+
the release of these resources (especially in the case of failure).
172172

173-
A type with the same functionality as owned boxes can be implemented by
174-
wrapping `malloc` and `free`:
173+
As an example, we give a reimplementation of owned boxes by wrapping `malloc`
174+
and `free`:
175175

176176
~~~~
177177
use std::cast;
178178
use std::libc::{c_void, size_t, malloc, free};
179179
use std::ptr;
180180
use std::unstable::intrinsics;
181181
182-
// a wrapper around the handle returned by the foreign code
182+
// Define a wrapper around the handle returned by the foreign code.
183+
// Unique<T> has the same semantics as ~T
183184
pub struct Unique<T> {
185+
// It contains a single raw, mutable pointer to the object in question.
184186
priv ptr: *mut T
185187
}
186188
189+
// Implement methods for creating and using the values in the box.
190+
// NB: For simplicity and correctness, we require that T has kind Send
191+
// (owned boxes relax this restriction, and can contain managed (GC) boxes).
192+
// This is because, as implemented, the garbage collector would not know
193+
// about any shared boxes stored in the malloc'd region of memory.
187194
impl<T: Send> Unique<T> {
188195
pub fn new(value: T) -> Unique<T> {
189196
unsafe {
190197
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
191198
assert!(!ptr::is_null(ptr));
192199
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
200+
// move_val_init moves a value into this memory without
201+
// attempting to drop the original value.
193202
intrinsics::move_val_init(&mut *ptr, value);
194203
Unique{ptr: ptr}
195204
}
@@ -206,12 +215,20 @@ impl<T: Send> Unique<T> {
206215
}
207216
}
208217
218+
// The key ingredient for safety, we associate a destructor with
219+
// Unique<T>, making the struct manage the raw pointer: when the
220+
// struct goes out of scope, it will automatically free the raw pointer.
221+
// NB: This is an unsafe destructor, because rustc will not normally
222+
// allow destructors to be associated with parametrized types, due to
223+
// bad interaction with managed boxes. (With the Send restriction,
224+
// we don't have this problem.)
209225
#[unsafe_destructor]
210226
impl<T: Send> Drop for Unique<T> {
211227
fn drop(&mut self) {
212228
unsafe {
213-
let x = intrinsics::init(); // dummy value to swap in
214-
// moving the object out is needed to call the destructor
229+
let x = intrinsics::uninit(); // dummy value to swap in
230+
// We need to move the object out of the box, so that
231+
// the destructor is called (at the end of this scope.)
215232
ptr::replace_ptr(self.ptr, x);
216233
free(self.ptr as *c_void)
217234
}

branches/try/doc/tutorial-rustpkg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ Now you can install and use it! Go anywhere else in your filesystem:
198198

199199
~~~ {.notrust}
200200
$ cd ~/src/foo
201-
$ rustpkg install github/YOUR_USERNAME/hello
201+
$ rustpkg install github.com/YOUR_USERNAME/hello
202202
WARNING: The Rust package manager is experimental and may be unstable
203203
note: Installed package github.com/YOUR_USERNAME/hello-0.1 to /home/yourusername/src/hello/.rust
204204
~~~

branches/try/src/etc/emacs/rust-mode-tests.el

Lines changed: 226 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,24 @@ Also, the result should be the same regardless of whether the code is at the beg
5252
(loop
5353
for pad-at-beginning from 0 to 1
5454
do (loop for pad-at-end from 0 to 1
55-
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
56-
with padding-end = (if (= 0 pad-at-end) "" padding)
57-
with padding-adjust = (* padding-len pad-at-beginning)
58-
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
59-
with padding-end = (if (= 0 pad-at-end) "" padding)
60-
;; If we're adding space to the beginning, and our start position
61-
;; is at the very beginning, we want to test within the added space.
62-
;; Otherwise adjust the start and end for the beginning padding.
63-
with start-pos = (if (= 1 start-pos) 1 (+ padding-adjust start-pos))
64-
with end-pos = (+ end-pos padding-adjust)
65-
do (loop for pos from start-pos to end-pos
66-
do (rust-test-manip-code
67-
(concat padding-beginning unfilled padding-end)
68-
pos
69-
(lambda ()
70-
(let ((fill-column rust-test-fill-column))
71-
(fill-paragraph)))
72-
(concat padding-beginning expected padding-end)))))))
55+
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
56+
with padding-end = (if (= 0 pad-at-end) "" padding)
57+
with padding-adjust = (* padding-len pad-at-beginning)
58+
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
59+
with padding-end = (if (= 0 pad-at-end) "" padding)
60+
;; If we're adding space to the beginning, and our start position
61+
;; is at the very beginning, we want to test within the added space.
62+
;; Otherwise adjust the start and end for the beginning padding.
63+
with start-pos = (if (= 1 start-pos) 1 (+ padding-adjust start-pos))
64+
with end-pos = (+ end-pos padding-adjust)
65+
do (loop for pos from start-pos to end-pos
66+
do (rust-test-manip-code
67+
(concat padding-beginning unfilled padding-end)
68+
pos
69+
(lambda ()
70+
(let ((fill-column rust-test-fill-column))
71+
(fill-paragraph)))
72+
(concat padding-beginning expected padding-end)))))))
7373

7474
(ert-deftest fill-paragraph-top-level-multi-line-style-doc-comment-second-line ()
7575
(test-fill-paragraph
@@ -262,14 +262,14 @@ fn bar() { }" 14 67))
262262
/// "
263263
103
264264
"This is the second really really really really really really long paragraph"
265-
"/// This is the first really
265+
"/// This is the first really
266266
/// really really really really
267267
/// really really long paragraph
268268
///
269269
/// This is the second really
270270
/// really really really really
271271
/// really long paragraph"
272-
))
272+
))
273273

274274
(ert-deftest auto-fill-multi-line-prefixless ()
275275
(test-auto-fill
@@ -295,7 +295,7 @@ very very very long string
295295

296296
(ert-deftest indent-struct-fields-aligned ()
297297
(test-indent
298-
"
298+
"
299299
struct Foo { bar: int,
300300
baz: int }
301301
@@ -305,7 +305,7 @@ struct Blah {x:int,
305305

306306
(ert-deftest indent-doc-comments ()
307307
(test-indent
308-
"
308+
"
309309
/**
310310
* This is a doc comment
311311
*
@@ -411,7 +411,7 @@ fn nexted_fns(a: fn(b:int,
411411
0
412412
}
413413
"
414-
))
414+
))
415415

416416
(ert-deftest indent-multi-line-expr ()
417417
(test-indent
@@ -423,4 +423,206 @@ fn foo()
423423
b();
424424
}
425425
"
426-
))
426+
))
427+
428+
(setq rust-test-motion-string
429+
"
430+
fn fn1(arg: int) -> bool {
431+
let x = 5;
432+
let y = b();
433+
true
434+
}
435+
436+
fn fn2(arg: int) -> bool {
437+
let x = 5;
438+
let y = b();
439+
true
440+
}
441+
442+
pub fn fn3(arg: int) -> bool {
443+
let x = 5;
444+
let y = b();
445+
true
446+
}
447+
448+
struct Foo {
449+
x: int
450+
}
451+
"
452+
rust-test-region-string rust-test-motion-string
453+
;; Symbol -> (line column)
454+
rust-test-positions-alist '((start-of-fn1 (2 0))
455+
(start-of-fn1-middle-of-line (2 15))
456+
(middle-of-fn1 (3 7))
457+
(end-of-fn1 (6 0))
458+
(between-fn1-fn2 (7 0))
459+
(start-of-fn2 (8 0))
460+
(middle-of-fn2 (10 4))
461+
(before-start-of-fn1 (1 0))
462+
(after-end-of-fn2 (13 0))
463+
(beginning-of-fn3 (14 0))
464+
(middle-of-fn3 (16 4))
465+
(middle-of-struct (21 10))
466+
(before-start-of-struct (19 0))
467+
(after-end-of-struct (23 0))))
468+
469+
(defun rust-get-buffer-pos (pos-symbol)
470+
"Get buffer position from POS-SYMBOL.
471+
472+
POS-SYMBOL is a symbol found in `rust-test-positions-alist'.
473+
Convert the line-column information from that list into a buffer position value."
474+
(interactive "P")
475+
(pcase-let ((`(,line ,column) (cadr (assoc pos-symbol rust-test-positions-alist))))
476+
(save-excursion
477+
(goto-line line)
478+
(move-to-column column)
479+
(point))))
480+
481+
;;; TODO: Maybe add an ERT explainer function (something that shows the
482+
;;; surrounding code of the final point, not just the position).
483+
(defun rust-test-motion (source-code init-pos final-pos manip-func &optional &rest args)
484+
"Test that MANIP-FUNC moves point from INIT-POS to FINAL-POS.
485+
486+
If ARGS are provided, send them to MANIP-FUNC.
487+
488+
INIT-POS, FINAL-POS are position symbols found in `rust-test-positions-alist'."
489+
(with-temp-buffer
490+
(rust-mode)
491+
(insert source-code)
492+
(goto-char (rust-get-buffer-pos init-pos))
493+
(apply manip-func args)
494+
(should (equal (point) (rust-get-buffer-pos final-pos)))))
495+
496+
(defun rust-test-region (source-code init-pos reg-beg reg-end manip-func &optional &rest args)
497+
"Test that MANIP-FUNC marks region from REG-BEG to REG-END.
498+
499+
INIT-POS is the initial position of point.
500+
If ARGS are provided, send them to MANIP-FUNC.
501+
All positions are position symbols found in `rust-test-positions-alist'."
502+
(with-temp-buffer
503+
(rust-mode)
504+
(insert source-code)
505+
(goto-char (rust-get-buffer-pos init-pos))
506+
(apply manip-func args)
507+
(should (equal (list (region-beginning) (region-end))
508+
(list (rust-get-buffer-pos reg-beg)
509+
(rust-get-buffer-pos reg-end))))))
510+
511+
(ert-deftest rust-beginning-of-defun-from-middle-of-fn ()
512+
(rust-test-motion
513+
rust-test-motion-string
514+
'middle-of-fn1
515+
'start-of-fn1
516+
#'beginning-of-defun))
517+
518+
(ert-deftest rust-beginning-of-defun-from-end ()
519+
(rust-test-motion
520+
rust-test-motion-string
521+
'end-of-fn1
522+
'start-of-fn1
523+
#'beginning-of-defun))
524+
525+
(ert-deftest rust-beginning-of-defun-before-open-brace ()
526+
(rust-test-motion
527+
rust-test-motion-string
528+
'start-of-fn1-middle-of-line
529+
'start-of-fn1
530+
#'beginning-of-defun))
531+
532+
(ert-deftest rust-beginning-of-defun-between-fns ()
533+
(rust-test-motion
534+
rust-test-motion-string
535+
'between-fn1-fn2
536+
'start-of-fn1
537+
#'beginning-of-defun))
538+
539+
(ert-deftest rust-beginning-of-defun-with-arg ()
540+
(rust-test-motion
541+
rust-test-motion-string
542+
'middle-of-fn2
543+
'start-of-fn1
544+
#'beginning-of-defun 2))
545+
546+
(ert-deftest rust-beginning-of-defun-with-negative-arg ()
547+
(rust-test-motion
548+
rust-test-motion-string
549+
'middle-of-fn1
550+
'beginning-of-fn3
551+
#'beginning-of-defun -2))
552+
553+
(ert-deftest rust-beginning-of-defun-pub-fn ()
554+
(rust-test-motion
555+
rust-test-motion-string
556+
'middle-of-fn3
557+
'beginning-of-fn3
558+
#'beginning-of-defun))
559+
560+
(ert-deftest rust-end-of-defun-from-middle-of-fn ()
561+
(rust-test-motion
562+
rust-test-motion-string
563+
'middle-of-fn1
564+
'between-fn1-fn2
565+
#'end-of-defun))
566+
567+
(ert-deftest rust-end-of-defun-from-beg ()
568+
(rust-test-motion
569+
rust-test-motion-string
570+
'start-of-fn1
571+
'between-fn1-fn2
572+
#'end-of-defun))
573+
574+
(ert-deftest rust-end-of-defun-before-open-brace ()
575+
(rust-test-motion
576+
rust-test-motion-string
577+
'start-of-fn1-middle-of-line
578+
'between-fn1-fn2
579+
#'end-of-defun))
580+
581+
(ert-deftest rust-end-of-defun-between-fns ()
582+
(rust-test-motion
583+
rust-test-motion-string
584+
'between-fn1-fn2
585+
'after-end-of-fn2
586+
#'end-of-defun))
587+
588+
(ert-deftest rust-end-of-defun-with-arg ()
589+
(rust-test-motion
590+
rust-test-motion-string
591+
'middle-of-fn1
592+
'after-end-of-fn2
593+
#'end-of-defun 2))
594+
595+
(ert-deftest rust-end-of-defun-with-negative-arg ()
596+
(rust-test-motion
597+
rust-test-motion-string
598+
'middle-of-fn3
599+
'between-fn1-fn2
600+
#'end-of-defun -2))
601+
602+
(ert-deftest rust-mark-defun-from-middle-of-fn ()
603+
(rust-test-region
604+
rust-test-region-string
605+
'middle-of-fn2
606+
'between-fn1-fn2 'after-end-of-fn2
607+
#'mark-defun))
608+
609+
(ert-deftest rust-mark-defun-from-end ()
610+
(rust-test-region
611+
rust-test-region-string
612+
'end-of-fn1
613+
'before-start-of-fn1 'between-fn1-fn2
614+
#'mark-defun))
615+
616+
(ert-deftest rust-mark-defun-start-of-defun ()
617+
(rust-test-region
618+
rust-test-region-string
619+
'start-of-fn2
620+
'between-fn1-fn2 'after-end-of-fn2
621+
#'mark-defun))
622+
623+
(ert-deftest rust-mark-defun-from-middle-of-struct ()
624+
(rust-test-region
625+
rust-test-region-string
626+
'middle-of-struct
627+
'before-start-of-struct 'after-end-of-struct
628+
#'mark-defun))

0 commit comments

Comments
 (0)